systemc: Track the scheduler status using an enum instead of bools.
authorGabe Black <gabeblack@google.com>
Fri, 7 Sep 2018 22:19:44 +0000 (15:19 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 9 Oct 2018 21:41:30 +0000 (21:41 +0000)
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>

src/systemc/core/scheduler.cc
src/systemc/core/scheduler.hh

index 5348e6665ee526f789891384dfa42fef8b4910c0..beec87d9d06a7c3a224f74c0c7963e9c02610310 100644 (file)
@@ -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();
@@ -336,10 +336,18 @@ 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;
index dda483f0cf3ef8b5c6cf3d17955aa9a94ce64d01..7b6238843d4eb6c0d9bd3668ff7480f6e6e96991 100644 (file)
@@ -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);
 }