diff options
author | Gabe Black <gabeblack@google.com> | 2018-07-16 16:14:33 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-09-05 06:06:00 +0000 |
commit | f2ab5e7a9e11783da3b9d7338775cf4b5fe2c29c (patch) | |
tree | c8b08f18270cb3131f37b6e0bfe1e8f2e94da63d /src/systemc/core/process.cc | |
parent | d7755ec828868582e2b409ba14f1c8c920c7f184 (diff) | |
download | gem5-f2ab5e7a9e11783da3b9d7338775cf4b5fe2c29c.tar.xz |
systemc: Implement the sensitivity mechanism.
This change lets processes be sensitive to events, timeouts, etc.
Change-Id: If30a256dfa8a2e92192c1f9c96b48e2aa28ec27e
Reviewed-on: https://gem5-review.googlesource.com/11713
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/core/process.cc')
-rw-r--r-- | src/systemc/core/process.cc | 112 |
1 files changed, 109 insertions, 3 deletions
diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc index 26cfb7ecd..a949c9dee 100644 --- a/src/systemc/core/process.cc +++ b/src/systemc/core/process.cc @@ -28,11 +28,84 @@ */ #include "systemc/core/process.hh" + +#include "base/logging.hh" +#include "systemc/core/event.hh" #include "systemc/core/scheduler.hh" namespace sc_gem5 { +void +Sensitivity::satisfy() +{ + warn_once("Ignoring suspended status for now.\n"); + process->setDynamic(nullptr); + scheduler.ready(process); +} + +SensitivityTimeout::SensitivityTimeout(Process *p, ::sc_core::sc_time t) : + Sensitivity(p), timeoutEvent(this), timeout(t) +{ + Tick when = scheduler.eventQueue().getCurTick() + timeout.value(); + scheduler.eventQueue().schedule(&timeoutEvent, when); +} + +SensitivityTimeout::~SensitivityTimeout() +{ + if (timeoutEvent.scheduled()) + scheduler.eventQueue().deschedule(&timeoutEvent); +} + +SensitivityEvent::SensitivityEvent( + Process *p, const ::sc_core::sc_event *e) : Sensitivity(p), event(e) +{ + Event::getFromScEvent(event)->addSensitivity(this); +} + +SensitivityEvent::~SensitivityEvent() +{ + Event::getFromScEvent(event)->delSensitivity(this); +} + +SensitivityEventAndList::SensitivityEventAndList( + Process *p, const ::sc_core::sc_event_and_list *list) : + Sensitivity(p), list(list), count(0) +{ + for (auto e: list->events) + Event::getFromScEvent(e)->addSensitivity(this); +} + +SensitivityEventAndList::~SensitivityEventAndList() +{ + for (auto e: list->events) + Event::getFromScEvent(e)->delSensitivity(this); +} + +void +SensitivityEventAndList::notifyWork(Event *e) +{ + e->delSensitivity(this); + count++; + if (count == list->events.size()) + satisfy(); +} + +SensitivityEventOrList::SensitivityEventOrList( + Process *p, const ::sc_core::sc_event_or_list *list) : + Sensitivity(p), list(list) +{ + for (auto e: list->events) + Event::getFromScEvent(e)->addSensitivity(this); +} + +SensitivityEventOrList::~SensitivityEventOrList() +{ + for (auto e: list->events) + Event::getFromScEvent(e)->delSensitivity(this); +} + + class UnwindExceptionReset : public ::sc_core::sc_unwind_exception { public: @@ -191,6 +264,23 @@ Process::syncResetOff(bool inc_kids) } void +Process::dontInitialize() +{ + scheduler.dontInitialize(this); +} + +void +Process::finalize() +{ + for (auto &s: pendingStaticSensitivities) { + s->finalize(staticSensitivities); + delete s; + s = nullptr; + } + pendingStaticSensitivities.clear(); +}; + +void Process::run() { _running = true; @@ -206,15 +296,31 @@ Process::run() _running = false; } +void +Process::addStatic(PendingSensitivity *s) +{ + pendingStaticSensitivities.push_back(s); +} + +void +Process::setDynamic(Sensitivity *s) +{ + delete dynamicSensitivity; + dynamicSensitivity = s; +} + Process::Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) : ::sc_core::sc_object(name), excWrapper(nullptr), func(func), _running(false), _dynamic(_dynamic), _isUnwinding(false), _terminated(false), _suspended(false), _disabled(false), - _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize) + _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize), + dynamicSensitivity(nullptr) { _newest = this; - if (!_dynamic) - scheduler.init(this); + if (_dynamic) + finalize(); + else + scheduler.reg(this); } Process *Process::_newest; |