systemc: Generalize gem5 style event scheduling.
authorGabe Black <gabeblack@google.com>
Sat, 18 Aug 2018 00:48:56 +0000 (17:48 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 25 Sep 2018 23:52:00 +0000 (23:52 +0000)
These events are either scheduled directly, or if no event queue is
yet available they're recorded in a map to schedule later. Since this
was used in a few places (and should have been used for the ready
event), this change moves it into some common functions which remove
some duplication and abstract away this detail.

Change-Id: I4320d7296f4f72344539b2b4b2564a6a27576dd8
Reviewed-on: https://gem5-review.googlesource.com/12219
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

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

index e18855c4d2d675d5bbe4641a77f2bef10e503029..cdebd99866f608cfe2b333f9e64b5e1b8da350bd 100644 (file)
@@ -77,7 +77,7 @@ Scheduler::initPhase()
     if (_started) {
         if (starved() && !runToTime)
             scheduleStarvationEvent();
-        eq->schedule(&maxTickEvent, maxTick);
+        kernel->status(::sc_core::SC_RUNNING);
     }
 
     initDone = true;
@@ -153,8 +153,7 @@ void
 Scheduler::requestUpdate(Channel *c)
 {
     updateList.pushLast(c);
-    if (eq)
-        scheduleReadyEvent();
+    scheduleReadyEvent();
 }
 
 void
@@ -162,10 +161,9 @@ Scheduler::scheduleReadyEvent()
 {
     // Schedule the evaluate and update phases.
     if (!readyEvent.scheduled()) {
-        panic_if(!eq, "Need to schedule ready, but no event manager.\n");
-        eq->schedule(&readyEvent, eq->getCurTick());
+        schedule(&readyEvent);
         if (starvationEvent.scheduled())
-            eq->deschedule(&starvationEvent);
+            deschedule(&starvationEvent);
     }
 }
 
@@ -173,13 +171,9 @@ void
 Scheduler::scheduleStarvationEvent()
 {
     if (!starvationEvent.scheduled()) {
-        Tick now = getCurTick();
-        if (initDone)
-            eq->schedule(&starvationEvent, now);
-        else
-            eventsToSchedule[&starvationEvent] = now;
+        schedule(&starvationEvent);
         if (readyEvent.scheduled())
-            eq->deschedule(&readyEvent);
+            deschedule(&readyEvent);
     }
 }
 
@@ -258,9 +252,10 @@ Scheduler::start(Tick max_tick, bool run_to_time)
         if (starved() && !runToTime)
             scheduleStarvationEvent();
         kernel->status(::sc_core::SC_RUNNING);
-        eq->schedule(&maxTickEvent, maxTick);
     }
 
+    schedule(&maxTickEvent, maxTick);
+
     // Return to gem5 to let it run events, etc.
     Fiber::primaryFiber()->run();
 
index 2843b68290a61682831c2cdc6cbc76e39f0ef86b..c22bdf87025b7c33f822b48421502087e96815d8 100644 (file)
@@ -225,10 +225,7 @@ class Scheduler
         TimeSlot *&ts = timeSlots[tick];
         if (!ts) {
             ts = new TimeSlot;
-            if (initDone)
-                eq->schedule(ts, tick);
-            else
-                eventsToSchedule[ts] = tick;
+            schedule(ts, tick);
         }
         ts->events.insert(event);
     }
@@ -255,10 +252,7 @@ class Scheduler
 
         // If no more events are happening at this time slot, get rid of it.
         if (events.empty()) {
-            if (initDone)
-                eq->deschedule(ts);
-            else
-                eventsToSchedule.erase(ts);
+            deschedule(ts);
             timeSlots.erase(tsit);
         }
     }
@@ -328,6 +322,27 @@ class Scheduler
 
     EventQueue *eq;
 
+    // For gem5 style events.
+    void
+    schedule(::Event *event, Tick tick)
+    {
+        if (initDone)
+            eq->schedule(event, tick);
+        else
+            eventsToSchedule[event] = tick;
+    }
+
+    void schedule(::Event *event) { schedule(event, getCurTick()); }
+
+    void
+    deschedule(::Event *event)
+    {
+        if (initDone)
+            eq->deschedule(event);
+        else
+            eventsToSchedule.erase(event);
+    }
+
     ScEvents deltas;
     TimeSlots timeSlots;