systemc: Keep all pre-init processes on a single list.
authorGabe Black <gabeblack@google.com>
Tue, 11 Sep 2018 00:25:00 +0000 (17:25 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 9 Oct 2018 21:45:00 +0000 (21:45 +0000)
We were keeping track of processes which should be initialized and
those which shouldn't on two different lists, and then processing
each list one after the other. This could reorder processes from the
order they were created, and so cause spurious differences which cause
the Accellera tests to fail.

This does make the scheduler slightly simpler, so it's not all bad.

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

src/systemc/channel/sc_clock.cc
src/systemc/core/process.cc
src/systemc/core/process.hh
src/systemc/core/sc_module.cc
src/systemc/core/sc_spawn.cc
src/systemc/core/scheduler.cc
src/systemc/core/scheduler.hh

index 2a412351f24723c31fd407116125eeafa78599b9..332604f6340478d0c2f3b56ae82115dac48964b9 100644 (file)
@@ -66,8 +66,8 @@ class ClockTick : public ScEvent
     createProcess()
     {
         p = new Method(name.c_str(), &funcWrapper, true);
+        p->dontInitialize(true);
         scheduler.reg(p);
-        scheduler.dontInitialize(p);
     }
 
     ~ClockTick()
index e4d213bc17c42ab9076acc5de54dbb017dd290f8..553f332d3c7d6c7aa1884f53a37f01fe26bfe49a 100644 (file)
@@ -313,12 +313,6 @@ Process::syncResetOff(bool inc_kids)
     _syncReset = false;
 }
 
-void
-Process::dontInitialize()
-{
-    scheduler.dontInitialize(this);
-}
-
 void
 Process::finalize()
 {
@@ -400,9 +394,9 @@ Process::lastReport(::sc_core::sc_report *report)
 
 Process::Process(const char *name, ProcessFuncWrapper *func, bool internal) :
     ::sc_core::sc_process_b(name), excWrapper(nullptr), func(func),
-    _internal(internal), _timedOut(false), _needsStart(true),
-    _isUnwinding(false), _terminated(false), _suspended(false),
-    _disabled(false), _syncReset(false), refCount(0),
+    _internal(internal), _timedOut(false), _dontInitialize(false),
+    _needsStart(true), _isUnwinding(false), _terminated(false),
+    _suspended(false), _disabled(false), _syncReset(false), refCount(0),
     stackSize(::Fiber::DefaultStackSize), dynamicSensitivity(nullptr)
 {
     _dynamic =
index 1ea59974724d6f494a23f72bc5332fa29d51b4a5..4d88e27b841bf8a0fbf3f91ee24251975ba1a516 100644 (file)
@@ -319,9 +319,6 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     const ::sc_core::sc_event &resetEvent() { return _resetEvent; }
     const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; }
 
-    // This should only be called before initialization.
-    void dontInitialize();
-
     void setStackSize(size_t size) { stackSize = size; }
 
     void finalize();
@@ -347,6 +344,9 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     bool timedOut() { return _timedOut; }
     void timedOut(bool to) { _timedOut = to; }
 
+    bool dontInitialize() { return _dontInitialize; }
+    void dontInitialize(bool di) { _dontInitialize = di; }
+
   protected:
     Process(const char *name, ProcessFuncWrapper *func, bool internal=false);
 
@@ -371,6 +371,8 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     // Needed to support the deprecated "timed_out" function.
     bool _timedOut;
 
+    bool _dontInitialize;
+
     bool _needsStart;
     bool _dynamic;
     bool _isUnwinding;
index 2fc6e8c75c8150bb223a163980ce5d6b1c74d1b0..e695f7697c2bc9aa14b7904a388daa549a8113bd 100644 (file)
@@ -86,7 +86,7 @@ newCThreadProcess(const char *name, ProcessFuncWrapper *func)
         return nullptr;
     }
     scheduler.reg(p);
-    p->dontInitialize();
+    p->dontInitialize(true);
     return p;
 }
 
@@ -296,7 +296,7 @@ sc_module::async_reset_signal_is(const sc_signal_in_if<bool> &, bool)
 void
 sc_module::dont_initialize()
 {
-    ::sc_gem5::Process::newest()->dontInitialize();
+    ::sc_gem5::Process::newest()->dontInitialize(true);
 }
 
 void
index 00fe502e67077e54009a13232ec3165ae5c060bb..9e2b4c83a37c560b858f830afe772c26863ac83d 100644 (file)
@@ -66,6 +66,8 @@ spawnWork(ProcessFuncWrapper *func, const char *name,
     else
         proc = new Thread(name, func);
 
+    proc->dontInitialize(dontInitialize);
+
     if (opts) {
         for (auto e: opts->_events)
             proc->addStatic(new PendingSensitivityEvent(proc, e));
@@ -95,9 +97,6 @@ spawnWork(ProcessFuncWrapper *func, const char *name,
 
     scheduler.reg(proc);
 
-    if (dontInitialize)
-        scheduler.dontInitialize(proc);
-
     return proc;
 }
 
index 801580947344eaa91249a129589047c29930d967..fe00ac0f8d549cd03176fc192459f5b794c6ea92 100644 (file)
@@ -88,8 +88,6 @@ Scheduler::clear()
         deschedule(&maxTickEvent);
 
     Process *p;
-    while ((p = toFinalize.getNext()))
-        p->popListNode();
     while ((p = initList.getNext()))
         p->popListNode();
     while ((p = readyListMethods.getNext()))
@@ -105,24 +103,22 @@ Scheduler::clear()
 void
 Scheduler::initPhase()
 {
-    for (Process *p = toFinalize.getNext(); p; p = toFinalize.getNext()) {
+    for (Process *p = initList.getNext(); p; p = initList.getNext()) {
         p->finalize();
         p->popListNode();
 
-        if (!p->hasStaticSensitivities() && !p->internal()) {
-            SC_REPORT_WARNING(
-                    "(W558) disable() or dont_initialize() called on process "
-                    "with no static sensitivity, it will be orphaned",
-                    p->name());
+        if (p->dontInitialize()) {
+            if (!p->hasStaticSensitivities() && !p->internal()) {
+                SC_REPORT_WARNING(
+                        "(W558) disable() or dont_initialize() called on "
+                        "process with no static sensitivity, it will be "
+                        "orphaned", p->name());
+            }
+        } else {
+            p->ready();
         }
     }
 
-    for (Process *p = initList.getNext(); p; p = initList.getNext()) {
-        p->finalize();
-        p->popListNode();
-        p->ready();
-    }
-
     runUpdate();
     runDelta();
 
@@ -147,8 +143,9 @@ Scheduler::reg(Process *p)
     if (initDone) {
         // If we're past initialization, finalize static sensitivity.
         p->finalize();
-        // Mark the process as ready.
-        p->ready();
+        // If not marked as dontInitialize, mark as ready.
+        if (!p->dontInitialize())
+            p->ready();
     } else {
         // Otherwise, record that this process should be initialized once we
         // get there.
@@ -156,20 +153,6 @@ Scheduler::reg(Process *p)
     }
 }
 
-void
-Scheduler::dontInitialize(Process *p)
-{
-    if (initDone) {
-        // Pop this process off of the ready list.
-        p->popListNode();
-    } else {
-        // Push this process onto the list of processes which still need
-        // their static sensitivity to be finalized. That implicitly pops it
-        // off the list of processes to be initialized/marked ready.
-        toFinalize.pushLast(p);
-    }
-}
-
 void
 Scheduler::yield()
 {
@@ -240,15 +223,12 @@ Scheduler::suspend(Process *p)
 {
     bool was_ready;
     if (initDone) {
-        // After initialization, the only list we can be on is the ready list.
+        // After initialization, check if we're on a ready list.
         was_ready = (p->nextListNode != nullptr);
         p->popListNode();
     } else {
-        // Check the ready lists to see if we find this process.
-        was_ready = listContains(&readyListMethods, p) ||
-            listContains(&readyListThreads, p);
-        if (was_ready)
-            toFinalize.pushLast(p);
+        // Nothing is ready before init.
+        was_ready = false;
     }
     return was_ready;
 }
index 052be08c3bdc38109a80d7643fba6b0d98547833..0bbc3dac682d5ff690b8cdb3e70ee762a16ddea4 100644 (file)
@@ -173,9 +173,6 @@ class Scheduler
     // Register a process with the scheduler.
     void reg(Process *p);
 
-    // Tell the scheduler not to initialize a process.
-    void dontInitialize(Process *p);
-
     // Run the next process, if there is one.
     void yield();
 
@@ -439,7 +436,6 @@ class Scheduler
     bool runOnce;
 
     ProcessList initList;
-    ProcessList toFinalize;
 
     ProcessList *readyList;
     ProcessList readyListMethods;