diff options
author | Gabe Black <gabeblack@google.com> | 2018-07-20 16:28:54 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-09-11 21:42:55 +0000 |
commit | fbf406d0a63ec42ab0ac09788e16eab2a4839230 (patch) | |
tree | d6a5d45cd754530b4e32918b5ac4acf55ce7c93e | |
parent | 8a488364afcaa1baaa0014484d7f42b9aca9ac27 (diff) | |
download | gem5-fbf406d0a63ec42ab0ac09788e16eab2a4839230.tar.xz |
systemc: Implement the SC_EXIT_ON_STARVATION exit mode.
This mode implies checking whether there's any activity left either
before starting a delta cycle, or processing delta or timed
notification or timeout.
Change-Id: I0780a1f720cf63f3d2907b8dd28685266b52d6b4
Reviewed-on: https://gem5-review.googlesource.com/12038
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r-- | src/systemc/core/scheduler.cc | 27 | ||||
-rw-r--r-- | src/systemc/core/scheduler.hh | 16 |
2 files changed, 42 insertions, 1 deletions
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc index 5174627d0..c2b5ec38d 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -42,7 +42,9 @@ Scheduler::Scheduler() : eq(nullptr), readyEvent(this, false, ReadyPriority), pauseEvent(this, false, PausePriority), stopEvent(this, false, StopPriority), - scMain(nullptr), _started(false), _paused(false), _stopped(false), + scMain(nullptr), + starvationEvent(this, false, StarvationPriority), + _started(false), _paused(false), _stopped(false), maxTickEvent(this, false, MaxTickPriority), _numCycles(0), _current(nullptr), initReady(false) {} @@ -143,6 +145,20 @@ Scheduler::scheduleReadyEvent() if (!readyEvent.scheduled()) { panic_if(!eq, "Need to schedule ready, but no event manager.\n"); eq->schedule(&readyEvent, eq->getCurTick()); + if (starvationEvent.scheduled()) + eq->deschedule(&starvationEvent); + } +} + +void +Scheduler::scheduleStarvationEvent() +{ + if (!starvationEvent.scheduled()) { + panic_if(!eq, "Need to schedule starvation event, " + "but no event manager.\n"); + eq->schedule(&starvationEvent, eq->getCurTick()); + if (readyEvent.scheduled()) + eq->deschedule(&readyEvent); } } @@ -162,6 +178,9 @@ Scheduler::runReady() // The update phase. update(); + if (starved() && !runToTime) + scheduleStarvationEvent(); + // The delta phase will happen naturally through the event queue. } @@ -202,9 +221,13 @@ Scheduler::start(Tick max_tick, bool run_to_time) _started = true; _paused = false; _stopped = false; + runToTime = run_to_time; maxTick = max_tick; + if (starved() && !runToTime) + return; + if (initReady) { kernel->status(::sc_core::SC_RUNNING); eq->schedule(&maxTickEvent, maxTick); @@ -219,6 +242,8 @@ Scheduler::start(Tick max_tick, bool run_to_time) eq->deschedule(&stopEvent); if (maxTickEvent.scheduled()) eq->deschedule(&maxTickEvent); + if (starvationEvent.scheduled()) + eq->deschedule(&starvationEvent); } void diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index 73d660e9e..0c755eda4 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -215,6 +215,9 @@ class Scheduler auto it = pendingTicks.begin(); if (--it->second == 0) pendingTicks.erase(it); + + if (starved() && !runToTime) + scheduleStarvationEvent(); } // Pending activity ignores gem5 activity, much like how a systemc @@ -277,6 +280,7 @@ class Scheduler static Priority StopPriority = DefaultPriority - 1; static Priority PausePriority = DefaultPriority + 1; static Priority ReadyPriority = DefaultPriority + 2; + static Priority StarvationPriority = ReadyPriority; static Priority MaxTickPriority = DefaultPriority + 3; EventQueue *eq; @@ -292,6 +296,17 @@ class Scheduler EventWrapper<Scheduler, &Scheduler::stop> stopEvent; Fiber *scMain; + bool + starved() + { + return (readyList.empty() && updateList.empty() && + (pendingTicks.empty() || + pendingTicks.begin()->first > maxTick) && + initList.empty()); + } + EventWrapper<Scheduler, &Scheduler::pause> starvationEvent; + void scheduleStarvationEvent(); + bool _started; bool _paused; bool _stopped; @@ -304,6 +319,7 @@ class Scheduler Process *_current; bool initReady; + bool runToTime; ProcessList initList; ProcessList toFinalize; |