summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-09-07 15:19:44 -0700
committerGabe Black <gabeblack@google.com>2018-10-09 21:41:30 +0000
commit5a5f768667736d683bd1555b72d410e32db307a3 (patch)
tree51cb753e35212bccb60168f8f96df6534fdf2493
parent09432ca3cd5372bae3a4f041049ea181ddb7db31 (diff)
downloadgem5-5a5f768667736d683bd1555b72d410e32db307a3.tar.xz
systemc: Track the scheduler status using an enum instead of bools.
The scheduler tracked whether it was paused or stopped with two bools which are mutually exclusive. It's useful to be able to also check for some other mutually exclusive states like what phase the scheduler is currently running. Rather than adding a bunch of additional bools, this change switches those mutually exclusive states over to an enum, and adds some methods to access and maintain that enum. Change-Id: Ia9696b2853d1b122c1100c9df0e12b018fe9b84b Reviewed-on: https://gem5-review.googlesource.com/c/12605 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r--src/systemc/core/scheduler.cc39
-rw-r--r--src/systemc/core/scheduler.hh33
2 files changed, 51 insertions, 21 deletions
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index 5348e6665..beec87d9d 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -46,7 +46,7 @@ Scheduler::Scheduler() :
stopEvent(this, false, StopPriority),
scMain(nullptr), _throwToScMain(nullptr),
starvationEvent(this, false, StarvationPriority),
- _started(false), _paused(false), _stopped(false), _stopNow(false),
+ _started(false), _stopNow(false), _status(StatusOther),
maxTickEvent(this, false, MaxTickPriority),
_numCycles(0), _changeStamp(0), _current(nullptr), initDone(false),
runOnce(false), readyList(nullptr)
@@ -123,10 +123,8 @@ Scheduler::initPhase()
p->ready();
}
- update();
-
- while (!deltas.empty())
- deltas.front()->run();
+ runUpdate();
+ runDelta();
for (auto ets: eventsToSchedule)
eq->schedule(ets.first, ets.second);
@@ -139,6 +137,8 @@ Scheduler::initPhase()
}
initDone = true;
+
+ status(StatusOther);
}
void
@@ -311,23 +311,23 @@ Scheduler::runReady()
if (_stopNow)
return;
- // The update phase.
- update();
-
- // The delta phase.
- while (!deltas.empty())
- deltas.front()->run();
+ runUpdate();
+ runDelta();
if (!runToTime && starved())
scheduleStarvationEvent();
if (runOnce)
schedulePause();
+
+ status(StatusOther);
}
void
-Scheduler::update()
+Scheduler::runUpdate()
{
+ status(StatusUpdate);
+
Channel *channel = updateList.getNext();
while (channel) {
channel->popListNode();
@@ -337,9 +337,17 @@ Scheduler::update()
}
void
+Scheduler::runDelta()
+{
+ status(StatusDelta);
+ while (!deltas.empty())
+ deltas.front()->run();
+}
+
+void
Scheduler::pause()
{
- _paused = true;
+ status(StatusPaused);
kernel->status(::sc_core::SC_PAUSED);
runOnce = false;
if (scMain && !scMain->finished())
@@ -349,7 +357,7 @@ Scheduler::pause()
void
Scheduler::stop()
{
- _stopped = true;
+ status(StatusStopped);
kernel->stop();
clear();
@@ -367,8 +375,7 @@ Scheduler::start(Tick max_tick, bool run_to_time)
scMain = Fiber::currentFiber();
_started = true;
- _paused = false;
- _stopped = false;
+ status(StatusOther);
runToTime = run_to_time;
maxTick = max_tick;
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index dda483f0c..7b6238843 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -318,7 +318,10 @@ class Scheduler
}
// Run scheduled channel updates.
- void update();
+ void runUpdate();
+
+ // Run delta events.
+ void runDelta();
void setScMainFiber(Fiber *sc_main) { scMain = sc_main; }
@@ -328,13 +331,29 @@ class Scheduler
void schedulePause();
void scheduleStop(bool finish_delta);
- bool paused() { return _paused; }
- bool stopped() { return _stopped; }
+ enum Status
+ {
+ StatusOther = 0,
+ StatusDelta,
+ StatusUpdate,
+ StatusTiming,
+ StatusPaused,
+ StatusStopped
+ };
+
+ bool paused() { return status() == StatusPaused; }
+ bool stopped() { return status() == StatusStopped; }
+ bool inDelta() { return status() == StatusDelta; }
+ bool inUpdate() { return status() == StatusUpdate; }
+ bool inTiming() { return status() == StatusTiming; }
uint64_t changeStamp() { return _changeStamp; }
void throwToScMain(const ::sc_core::sc_report *r=nullptr);
+ Status status() { return _status; }
+ void status(Status s) { _status = s; }
+
private:
typedef const EventBase::Priority Priority;
static Priority DefaultPriority = EventBase::Default_Pri;
@@ -395,10 +414,10 @@ class Scheduler
void scheduleStarvationEvent();
bool _started;
- bool _paused;
- bool _stopped;
bool _stopNow;
+ Status _status;
+
Tick maxTick;
Tick lastReadyTick;
void
@@ -436,8 +455,12 @@ extern Scheduler scheduler;
inline void
Scheduler::TimeSlot::process()
{
+ scheduler.status(StatusTiming);
+
while (!events.empty())
events.front()->run();
+
+ scheduler.status(StatusOther);
scheduler.completeTimeSlot(this);
}