process.cc revision 13180
17199Sgblack@eecs.umich.edu/*
27199Sgblack@eecs.umich.edu * Copyright 2018 Google, Inc.
37199Sgblack@eecs.umich.edu *
47199Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
57199Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
67199Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
77199Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
87199Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
97199Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
107199Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
117199Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
127199Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
137199Sgblack@eecs.umich.edu * this software without specific prior written permission.
147199Sgblack@eecs.umich.edu *
157199Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
167199Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
177199Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
187199Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
197199Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
207199Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
217199Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
227199Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
237199Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
247199Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
257199Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
267199Sgblack@eecs.umich.edu *
277199Sgblack@eecs.umich.edu * Authors: Gabe Black
287199Sgblack@eecs.umich.edu */
297199Sgblack@eecs.umich.edu
307199Sgblack@eecs.umich.edu#include "systemc/core/process.hh"
317199Sgblack@eecs.umich.edu
327199Sgblack@eecs.umich.edu#include "base/logging.hh"
337199Sgblack@eecs.umich.edu#include "systemc/core/event.hh"
347199Sgblack@eecs.umich.edu#include "systemc/core/scheduler.hh"
357199Sgblack@eecs.umich.edu#include "systemc/ext/core/sc_main.hh"
367199Sgblack@eecs.umich.edu#include "systemc/ext/core/sc_process_handle.hh"
377199Sgblack@eecs.umich.edu#include "systemc/ext/utils/sc_report_handler.hh"
387199Sgblack@eecs.umich.edu
397199Sgblack@eecs.umich.edunamespace sc_gem5
407199Sgblack@eecs.umich.edu{
417199Sgblack@eecs.umich.edu
427199Sgblack@eecs.umich.eduSensitivityTimeout::SensitivityTimeout(Process *p, ::sc_core::sc_time t) :
437199Sgblack@eecs.umich.edu    Sensitivity(p), timeoutEvent([this]() { this->timeout(); })
447199Sgblack@eecs.umich.edu{
457199Sgblack@eecs.umich.edu    scheduler.schedule(&timeoutEvent, t);
467199Sgblack@eecs.umich.edu}
477199Sgblack@eecs.umich.edu
487199Sgblack@eecs.umich.eduSensitivityTimeout::~SensitivityTimeout()
497199Sgblack@eecs.umich.edu{
507199Sgblack@eecs.umich.edu    if (timeoutEvent.scheduled())
517199Sgblack@eecs.umich.edu        scheduler.deschedule(&timeoutEvent);
527199Sgblack@eecs.umich.edu}
537199Sgblack@eecs.umich.edu
547199Sgblack@eecs.umich.eduvoid
557199Sgblack@eecs.umich.eduSensitivityTimeout::timeout()
567199Sgblack@eecs.umich.edu{
577199Sgblack@eecs.umich.edu    notify();
587202Sgblack@eecs.umich.edu}
597202Sgblack@eecs.umich.edu
607202Sgblack@eecs.umich.eduSensitivityEvent::SensitivityEvent(
617202Sgblack@eecs.umich.edu        Process *p, const ::sc_core::sc_event *e) : Sensitivity(p), event(e)
627202Sgblack@eecs.umich.edu{
637202Sgblack@eecs.umich.edu    Event::getFromScEvent(event)->addSensitivity(this);
647202Sgblack@eecs.umich.edu}
657202Sgblack@eecs.umich.edu
667599Sminkyu.jeong@arm.comSensitivityEvent::~SensitivityEvent()
677599Sminkyu.jeong@arm.com{
687202Sgblack@eecs.umich.edu    Event::getFromScEvent(event)->delSensitivity(this);
697202Sgblack@eecs.umich.edu}
707202Sgblack@eecs.umich.edu
717202Sgblack@eecs.umich.eduSensitivityEventAndList::SensitivityEventAndList(
727202Sgblack@eecs.umich.edu        Process *p, const ::sc_core::sc_event_and_list *list) :
737202Sgblack@eecs.umich.edu    Sensitivity(p), list(list), count(0)
747202Sgblack@eecs.umich.edu{
757599Sminkyu.jeong@arm.com    for (auto e: list->events)
767599Sminkyu.jeong@arm.com        Event::getFromScEvent(e)->addSensitivity(this);
777202Sgblack@eecs.umich.edu}
787202Sgblack@eecs.umich.edu
797202Sgblack@eecs.umich.eduSensitivityEventAndList::~SensitivityEventAndList()
807202Sgblack@eecs.umich.edu{
817202Sgblack@eecs.umich.edu    for (auto e: list->events)
827400SAli.Saidi@ARM.com        Event::getFromScEvent(e)->delSensitivity(this);
837202Sgblack@eecs.umich.edu}
847400SAli.Saidi@ARM.com
857202Sgblack@eecs.umich.eduvoid
867202Sgblack@eecs.umich.eduSensitivityEventAndList::notifyWork(Event *e)
877202Sgblack@eecs.umich.edu{
887202Sgblack@eecs.umich.edu    e->delSensitivity(this);
897202Sgblack@eecs.umich.edu    count++;
907599Sminkyu.jeong@arm.com    if (count == list->events.size())
917599Sminkyu.jeong@arm.com        process->satisfySensitivity(this);
927202Sgblack@eecs.umich.edu}
937202Sgblack@eecs.umich.edu
947202Sgblack@eecs.umich.eduSensitivityEventOrList::SensitivityEventOrList(
957202Sgblack@eecs.umich.edu        Process *p, const ::sc_core::sc_event_or_list *list) :
967202Sgblack@eecs.umich.edu    Sensitivity(p), list(list)
977202Sgblack@eecs.umich.edu{
987202Sgblack@eecs.umich.edu    for (auto e: list->events)
997599Sminkyu.jeong@arm.com        Event::getFromScEvent(e)->addSensitivity(this);
1007599Sminkyu.jeong@arm.com}
1017202Sgblack@eecs.umich.edu
1027202Sgblack@eecs.umich.eduSensitivityEventOrList::~SensitivityEventOrList()
1037202Sgblack@eecs.umich.edu{
1047202Sgblack@eecs.umich.edu    for (auto e: list->events)
1057202Sgblack@eecs.umich.edu        Event::getFromScEvent(e)->delSensitivity(this);
1067400SAli.Saidi@ARM.com}
1077202Sgblack@eecs.umich.edu
1087400SAli.Saidi@ARM.comvoid
1097202Sgblack@eecs.umich.eduSensitivityTimeoutAndEventAndList::notifyWork(Event *e)
1107202Sgblack@eecs.umich.edu{
1117202Sgblack@eecs.umich.edu    if (e) {
1127202Sgblack@eecs.umich.edu        // An event went off which must be part of the sc_event_and_list.
1137202Sgblack@eecs.umich.edu        SensitivityEventAndList::notifyWork(e);
1147599Sminkyu.jeong@arm.com    } else {
1157599Sminkyu.jeong@arm.com        // There's no inciting event, so this must be a timeout.
1167202Sgblack@eecs.umich.edu        SensitivityTimeout::notifyWork(e);
1177202Sgblack@eecs.umich.edu    }
1187202Sgblack@eecs.umich.edu}
1197202Sgblack@eecs.umich.edu
1207202Sgblack@eecs.umich.edu
1217202Sgblack@eecs.umich.educlass UnwindExceptionReset : public ::sc_core::sc_unwind_exception
1227202Sgblack@eecs.umich.edu{
1237599Sminkyu.jeong@arm.com  public:
1247599Sminkyu.jeong@arm.com    UnwindExceptionReset() { _isReset = true; }
1257202Sgblack@eecs.umich.edu};
1267202Sgblack@eecs.umich.edu
1277202Sgblack@eecs.umich.educlass UnwindExceptionKill : public ::sc_core::sc_unwind_exception
1287209Sgblack@eecs.umich.edu{
1297209Sgblack@eecs.umich.edu  public:
1307209Sgblack@eecs.umich.edu    UnwindExceptionKill() {}
1317209Sgblack@eecs.umich.edu};
1327209Sgblack@eecs.umich.edu
1337261Sgblack@eecs.umich.edutemplate <typename T>
1347209Sgblack@eecs.umich.edustruct BuiltinExceptionWrapper : public ExceptionWrapperBase
1357209Sgblack@eecs.umich.edu{
1367261Sgblack@eecs.umich.edu  public:
1377261Sgblack@eecs.umich.edu    T t;
1387209Sgblack@eecs.umich.edu    void throw_it() override { throw t; }
1397209Sgblack@eecs.umich.edu};
1407209Sgblack@eecs.umich.edu
1417209Sgblack@eecs.umich.eduBuiltinExceptionWrapper<UnwindExceptionReset> resetException;
1427209Sgblack@eecs.umich.eduBuiltinExceptionWrapper<UnwindExceptionKill> killException;
1437209Sgblack@eecs.umich.edu
1447209Sgblack@eecs.umich.edu
1457209Sgblack@eecs.umich.eduvoid
1467209Sgblack@eecs.umich.eduProcess::forEachKid(const std::function<void(Process *)> &work)
1477261Sgblack@eecs.umich.edu{
1487209Sgblack@eecs.umich.edu    for (auto &kid: get_child_objects()) {
1497209Sgblack@eecs.umich.edu        Process *p_kid = dynamic_cast<Process *>(kid);
1507261Sgblack@eecs.umich.edu        if (p_kid)
1517261Sgblack@eecs.umich.edu            work(p_kid);
1527209Sgblack@eecs.umich.edu    }
1537209Sgblack@eecs.umich.edu}
1547209Sgblack@eecs.umich.edu
1557209Sgblack@eecs.umich.eduvoid
1567209Sgblack@eecs.umich.eduProcess::suspend(bool inc_kids)
1577209Sgblack@eecs.umich.edu{
1587261Sgblack@eecs.umich.edu    if (inc_kids)
1597209Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->suspend(true); });
1607209Sgblack@eecs.umich.edu
1617261Sgblack@eecs.umich.edu    if (!_suspended) {
1627261Sgblack@eecs.umich.edu        _suspended = true;
1637209Sgblack@eecs.umich.edu        _suspendedReady = scheduler.suspend(this);
1647226Sgblack@eecs.umich.edu
1657249Sgblack@eecs.umich.edu        if (procKind() != ::sc_core::SC_METHOD_PROC_ &&
1667249Sgblack@eecs.umich.edu                scheduler.current() == this) {
1677249Sgblack@eecs.umich.edu            // This isn't in the spec, but Accellera says that a thread that
1687249Sgblack@eecs.umich.edu            // self suspends should be marked ready immediately when it's
1697249Sgblack@eecs.umich.edu            // resumed.
1707249Sgblack@eecs.umich.edu            _suspendedReady = true;
1717249Sgblack@eecs.umich.edu            scheduler.yield();
1727249Sgblack@eecs.umich.edu        }
1737249Sgblack@eecs.umich.edu    }
1747249Sgblack@eecs.umich.edu}
1757249Sgblack@eecs.umich.edu
1767249Sgblack@eecs.umich.eduvoid
1777249Sgblack@eecs.umich.eduProcess::resume(bool inc_kids)
1787261Sgblack@eecs.umich.edu{
1797249Sgblack@eecs.umich.edu    if (inc_kids)
1807249Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->resume(true); });
1817261Sgblack@eecs.umich.edu
1827261Sgblack@eecs.umich.edu    if (_suspended) {
1837249Sgblack@eecs.umich.edu        _suspended = false;
1847249Sgblack@eecs.umich.edu        if (_suspendedReady)
1857251Sgblack@eecs.umich.edu            scheduler.resume(this);
1867251Sgblack@eecs.umich.edu        _suspendedReady = false;
1877251Sgblack@eecs.umich.edu    }
1887261Sgblack@eecs.umich.edu}
1897251Sgblack@eecs.umich.edu
1907251Sgblack@eecs.umich.eduvoid
1917261Sgblack@eecs.umich.eduProcess::disable(bool inc_kids)
1927261Sgblack@eecs.umich.edu{
1937251Sgblack@eecs.umich.edu    if (inc_kids)
1947251Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->disable(true); });
1957226Sgblack@eecs.umich.edu
1967226Sgblack@eecs.umich.edu    if (!::sc_core::sc_allow_process_control_corners &&
1977226Sgblack@eecs.umich.edu            dynamic_cast<SensitivityTimeout *>(dynamicSensitivity)) {
1987232Sgblack@eecs.umich.edu        std::string message("attempt to disable a thread with timeout wait: ");
1997226Sgblack@eecs.umich.edu        message += name();
2007226Sgblack@eecs.umich.edu        SC_REPORT_ERROR("Undefined process control interaction",
2017226Sgblack@eecs.umich.edu                message.c_str());
2027226Sgblack@eecs.umich.edu    }
2037226Sgblack@eecs.umich.edu
2047232Sgblack@eecs.umich.edu    _disabled = true;
2057226Sgblack@eecs.umich.edu}
2067422Sgblack@eecs.umich.edu
2077232Sgblack@eecs.umich.eduvoid
2087232Sgblack@eecs.umich.eduProcess::enable(bool inc_kids)
2097226Sgblack@eecs.umich.edu{
2107226Sgblack@eecs.umich.edu
2117226Sgblack@eecs.umich.edu    if (inc_kids)
2127226Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->enable(true); });
2137226Sgblack@eecs.umich.edu
2147232Sgblack@eecs.umich.edu    _disabled = false;
2157226Sgblack@eecs.umich.edu}
2167226Sgblack@eecs.umich.edu
2177226Sgblack@eecs.umich.eduvoid
2187226Sgblack@eecs.umich.eduProcess::kill(bool inc_kids)
2197226Sgblack@eecs.umich.edu{
2207232Sgblack@eecs.umich.edu    if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) {
2217226Sgblack@eecs.umich.edu        SC_REPORT_ERROR(
2227422Sgblack@eecs.umich.edu                "(E572) a process may not be killed before it is initialized",
2237232Sgblack@eecs.umich.edu                name());
2247232Sgblack@eecs.umich.edu    }
2257226Sgblack@eecs.umich.edu
2267226Sgblack@eecs.umich.edu    // Propogate the kill to our children no matter what happens to us.
2277226Sgblack@eecs.umich.edu    if (inc_kids)
2287226Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->kill(true); });
2297226Sgblack@eecs.umich.edu
2307226Sgblack@eecs.umich.edu    // If we're in the middle of unwinding, ignore the kill request.
2317226Sgblack@eecs.umich.edu    if (_isUnwinding)
2327226Sgblack@eecs.umich.edu        return;
2337232Sgblack@eecs.umich.edu
2347226Sgblack@eecs.umich.edu    // Update our state.
2357226Sgblack@eecs.umich.edu    terminate();
2367232Sgblack@eecs.umich.edu    _isUnwinding = true;
2377226Sgblack@eecs.umich.edu
2387226Sgblack@eecs.umich.edu    // Make sure this process isn't marked ready
2397226Sgblack@eecs.umich.edu    popListNode();
2407226Sgblack@eecs.umich.edu
2417232Sgblack@eecs.umich.edu    // Inject the kill exception into this process if it's started.
2427226Sgblack@eecs.umich.edu    if (!_needsStart)
2437422Sgblack@eecs.umich.edu        injectException(killException);
2447232Sgblack@eecs.umich.edu}
2457232Sgblack@eecs.umich.edu
2467226Sgblack@eecs.umich.eduvoid
2477226Sgblack@eecs.umich.eduProcess::reset(bool inc_kids)
2487226Sgblack@eecs.umich.edu{
2497226Sgblack@eecs.umich.edu    if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) {
2507226Sgblack@eecs.umich.edu        SC_REPORT_ERROR(
2517226Sgblack@eecs.umich.edu                "(E573) a process may not be asynchronously reset while"
2527226Sgblack@eecs.umich.edu                "the simulation is not running", name());
2537226Sgblack@eecs.umich.edu    }
2547232Sgblack@eecs.umich.edu
2557226Sgblack@eecs.umich.edu    // Propogate the reset to our children no matter what happens to us.
2567226Sgblack@eecs.umich.edu    if (inc_kids)
2577232Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->reset(true); });
2587226Sgblack@eecs.umich.edu
2597226Sgblack@eecs.umich.edu    // If we're in the middle of unwinding, ignore the reset request.
2607226Sgblack@eecs.umich.edu    if (_isUnwinding)
2617226Sgblack@eecs.umich.edu        return;
2627232Sgblack@eecs.umich.edu
2637226Sgblack@eecs.umich.edu
2647422Sgblack@eecs.umich.edu    if (_needsStart) {
2657232Sgblack@eecs.umich.edu        scheduler.runNow(this);
2667232Sgblack@eecs.umich.edu    } else {
2677226Sgblack@eecs.umich.edu        _isUnwinding = true;
2687234Sgblack@eecs.umich.edu        injectException(resetException);
2697234Sgblack@eecs.umich.edu    }
2707234Sgblack@eecs.umich.edu
2717234Sgblack@eecs.umich.edu    _resetEvent.notify();
2727234Sgblack@eecs.umich.edu}
2737234Sgblack@eecs.umich.edu
2747234Sgblack@eecs.umich.eduvoid
2757234Sgblack@eecs.umich.eduProcess::throw_it(ExceptionWrapperBase &exc, bool inc_kids)
2767234Sgblack@eecs.umich.edu{
2777234Sgblack@eecs.umich.edu    if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) {
2787234Sgblack@eecs.umich.edu        SC_REPORT_ERROR(
2797234Sgblack@eecs.umich.edu                "(E574) throw_it not allowed unless simulation is running ",
2807234Sgblack@eecs.umich.edu                name());
2817234Sgblack@eecs.umich.edu    }
2827234Sgblack@eecs.umich.edu
2837234Sgblack@eecs.umich.edu    if (inc_kids)
2847234Sgblack@eecs.umich.edu        forEachKid([&exc](Process *p) { p->throw_it(exc, true); });
2857234Sgblack@eecs.umich.edu
2867234Sgblack@eecs.umich.edu    // Only inject an exception into threads that have started.
2877234Sgblack@eecs.umich.edu    if (!_needsStart)
2887234Sgblack@eecs.umich.edu        injectException(exc);
2897234Sgblack@eecs.umich.edu}
2907234Sgblack@eecs.umich.edu
2917234Sgblack@eecs.umich.eduvoid
2927234Sgblack@eecs.umich.eduProcess::injectException(ExceptionWrapperBase &exc)
2937234Sgblack@eecs.umich.edu{
2947234Sgblack@eecs.umich.edu    excWrapper = &exc;
2957234Sgblack@eecs.umich.edu    scheduler.runNow(this);
2967234Sgblack@eecs.umich.edu};
2977234Sgblack@eecs.umich.edu
2987234Sgblack@eecs.umich.eduvoid
2997234Sgblack@eecs.umich.eduProcess::syncResetOn(bool inc_kids)
3007234Sgblack@eecs.umich.edu{
3017234Sgblack@eecs.umich.edu    if (inc_kids)
3027234Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->syncResetOn(true); });
3037234Sgblack@eecs.umich.edu
3047234Sgblack@eecs.umich.edu    _syncReset = true;
3057234Sgblack@eecs.umich.edu}
3067234Sgblack@eecs.umich.edu
3077234Sgblack@eecs.umich.eduvoid
3087234Sgblack@eecs.umich.eduProcess::syncResetOff(bool inc_kids)
3097234Sgblack@eecs.umich.edu{
3107234Sgblack@eecs.umich.edu    if (inc_kids)
3117234Sgblack@eecs.umich.edu        forEachKid([](Process *p) { p->syncResetOff(true); });
3127234Sgblack@eecs.umich.edu
3137234Sgblack@eecs.umich.edu    _syncReset = false;
3147234Sgblack@eecs.umich.edu}
3157234Sgblack@eecs.umich.edu
3167234Sgblack@eecs.umich.eduvoid
3177234Sgblack@eecs.umich.eduProcess::dontInitialize()
3187234Sgblack@eecs.umich.edu{
3197234Sgblack@eecs.umich.edu    scheduler.dontInitialize(this);
3207234Sgblack@eecs.umich.edu}
3217234Sgblack@eecs.umich.edu
3227234Sgblack@eecs.umich.eduvoid
3237234Sgblack@eecs.umich.eduProcess::finalize()
3247234Sgblack@eecs.umich.edu{
3257234Sgblack@eecs.umich.edu    for (auto &s: pendingStaticSensitivities) {
3267234Sgblack@eecs.umich.edu        s->finalize(staticSensitivities);
3277234Sgblack@eecs.umich.edu        delete s;
3287234Sgblack@eecs.umich.edu        s = nullptr;
3297234Sgblack@eecs.umich.edu    }
3307234Sgblack@eecs.umich.edu    pendingStaticSensitivities.clear();
3317234Sgblack@eecs.umich.edu};
3327234Sgblack@eecs.umich.edu
3337234Sgblack@eecs.umich.eduvoid
3347234Sgblack@eecs.umich.eduProcess::run()
3357234Sgblack@eecs.umich.edu{
3367234Sgblack@eecs.umich.edu    bool reset;
3377234Sgblack@eecs.umich.edu    do {
3387234Sgblack@eecs.umich.edu        reset = false;
3397234Sgblack@eecs.umich.edu        try {
3407234Sgblack@eecs.umich.edu            func->call();
3417234Sgblack@eecs.umich.edu        } catch(ScHalt) {
3427234Sgblack@eecs.umich.edu            std::cout << "Terminating process " << name() << std::endl;
3437234Sgblack@eecs.umich.edu        } catch(const ::sc_core::sc_unwind_exception &exc) {
3447234Sgblack@eecs.umich.edu            reset = exc.is_reset();
3457234Sgblack@eecs.umich.edu            _isUnwinding = false;
3467234Sgblack@eecs.umich.edu        }
3477234Sgblack@eecs.umich.edu    } while (reset);
3487234Sgblack@eecs.umich.edu    needsStart(true);
3497234Sgblack@eecs.umich.edu}
3507234Sgblack@eecs.umich.edu
3517234Sgblack@eecs.umich.eduvoid
3527234Sgblack@eecs.umich.eduProcess::addStatic(PendingSensitivity *s)
3537234Sgblack@eecs.umich.edu{
3547234Sgblack@eecs.umich.edu    pendingStaticSensitivities.push_back(s);
3557234Sgblack@eecs.umich.edu}
3567234Sgblack@eecs.umich.edu
3577234Sgblack@eecs.umich.eduvoid
3587234Sgblack@eecs.umich.eduProcess::setDynamic(Sensitivity *s)
3597234Sgblack@eecs.umich.edu{
3607234Sgblack@eecs.umich.edu    delete dynamicSensitivity;
3617234Sgblack@eecs.umich.edu    dynamicSensitivity = s;
3627234Sgblack@eecs.umich.edu}
3637234Sgblack@eecs.umich.edu
3647234Sgblack@eecs.umich.eduvoid
3657234Sgblack@eecs.umich.eduProcess::satisfySensitivity(Sensitivity *s)
3667234Sgblack@eecs.umich.edu{
3677234Sgblack@eecs.umich.edu    // If there's a dynamic sensitivity and this wasn't it, ignore.
3687234Sgblack@eecs.umich.edu    if (dynamicSensitivity && dynamicSensitivity != s)
3697234Sgblack@eecs.umich.edu        return;
3707234Sgblack@eecs.umich.edu
3717234Sgblack@eecs.umich.edu    setDynamic(nullptr);
3727234Sgblack@eecs.umich.edu    ready();
3737234Sgblack@eecs.umich.edu}
3747234Sgblack@eecs.umich.edu
3757234Sgblack@eecs.umich.eduvoid
3767234Sgblack@eecs.umich.eduProcess::ready()
3777234Sgblack@eecs.umich.edu{
3787234Sgblack@eecs.umich.edu    if (disabled())
3797234Sgblack@eecs.umich.edu        return;
3807234Sgblack@eecs.umich.edu    if (suspended())
3817234Sgblack@eecs.umich.edu        _suspendedReady = true;
3827234Sgblack@eecs.umich.edu    else
3837234Sgblack@eecs.umich.edu        scheduler.ready(this);
3847234Sgblack@eecs.umich.edu}
3857234Sgblack@eecs.umich.edu
3867234Sgblack@eecs.umich.eduvoid
3877234Sgblack@eecs.umich.eduProcess::lastReport(::sc_core::sc_report *report)
3887234Sgblack@eecs.umich.edu{
3897234Sgblack@eecs.umich.edu    if (report) {
3907234Sgblack@eecs.umich.edu        _lastReport = std::unique_ptr<::sc_core::sc_report>(
3917234Sgblack@eecs.umich.edu                new ::sc_core::sc_report(*report));
3927234Sgblack@eecs.umich.edu    } else {
3937234Sgblack@eecs.umich.edu        _lastReport = nullptr;
3947234Sgblack@eecs.umich.edu    }
3957234Sgblack@eecs.umich.edu}
3967234Sgblack@eecs.umich.edu
3977234Sgblack@eecs.umich.edu::sc_core::sc_report *Process::lastReport() const { return _lastReport.get(); }
3987234Sgblack@eecs.umich.edu
3997234Sgblack@eecs.umich.eduProcess::Process(const char *name, ProcessFuncWrapper *func, bool internal) :
4007234Sgblack@eecs.umich.edu    ::sc_core::sc_process_b(name), excWrapper(nullptr), func(func),
4017234Sgblack@eecs.umich.edu    _internal(internal), _needsStart(true), _isUnwinding(false),
4027234Sgblack@eecs.umich.edu    _terminated(false), _suspended(false), _disabled(false), _syncReset(false),
4037234Sgblack@eecs.umich.edu    refCount(0), stackSize(::Fiber::DefaultStackSize),
4047234Sgblack@eecs.umich.edu    dynamicSensitivity(nullptr)
4057234Sgblack@eecs.umich.edu{
4067234Sgblack@eecs.umich.edu    _dynamic =
4077234Sgblack@eecs.umich.edu            (::sc_core::sc_get_status() >
4087234Sgblack@eecs.umich.edu             ::sc_core::SC_BEFORE_END_OF_ELABORATION);
4097234Sgblack@eecs.umich.edu    _newest = this;
4107239Sgblack@eecs.umich.edu}
4117239Sgblack@eecs.umich.edu
4127239Sgblack@eecs.umich.eduvoid
4137239Sgblack@eecs.umich.eduProcess::terminate()
4147239Sgblack@eecs.umich.edu{
4157239Sgblack@eecs.umich.edu    _terminated = true;
4167239Sgblack@eecs.umich.edu    _suspendedReady = false;
4177239Sgblack@eecs.umich.edu    _suspended = false;
4187239Sgblack@eecs.umich.edu    _syncReset = false;
4197239Sgblack@eecs.umich.edu    delete dynamicSensitivity;
4207239Sgblack@eecs.umich.edu    dynamicSensitivity = nullptr;
4217239Sgblack@eecs.umich.edu    for (auto s: staticSensitivities)
4227239Sgblack@eecs.umich.edu        delete s;
4237239Sgblack@eecs.umich.edu    staticSensitivities.clear();
4247422Sgblack@eecs.umich.edu
4257239Sgblack@eecs.umich.edu    _terminatedEvent.notify();
4267239Sgblack@eecs.umich.edu}
4277239Sgblack@eecs.umich.edu
4287242Sgblack@eecs.umich.eduProcess *Process::_newest;
4297242Sgblack@eecs.umich.edu
4307242Sgblack@eecs.umich.eduvoid
4317242Sgblack@eecs.umich.eduthrow_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids)
4327242Sgblack@eecs.umich.edu{
4337242Sgblack@eecs.umich.edu    p->throw_it(exc, inc_kids);
4347242Sgblack@eecs.umich.edu}
4357242Sgblack@eecs.umich.edu
4367242Sgblack@eecs.umich.edu} // namespace sc_gem5
4377242Sgblack@eecs.umich.edu