summaryrefslogtreecommitdiff
path: root/src/systemc/core/scheduler.cc
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-07-20 16:28:54 -0700
committerGabe Black <gabeblack@google.com>2018-09-11 21:42:55 +0000
commitfbf406d0a63ec42ab0ac09788e16eab2a4839230 (patch)
treed6a5d45cd754530b4e32918b5ac4acf55ce7c93e /src/systemc/core/scheduler.cc
parent8a488364afcaa1baaa0014484d7f42b9aca9ac27 (diff)
downloadgem5-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>
Diffstat (limited to 'src/systemc/core/scheduler.cc')
-rw-r--r--src/systemc/core/scheduler.cc27
1 files changed, 26 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