systemc: Handle suspended processes and handle sensitivity overload.
authorGabe Black <gabeblack@google.com>
Mon, 16 Jul 2018 23:44:07 +0000 (16:44 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 5 Sep 2018 06:07:01 +0000 (06:07 +0000)
This change keeps track of whether a process would have become ready
but was suspended so that it can become ready when the process is
resumed.

Also, this makes a process ignore its static sensitivity while a
dynamic sensitivity is in place.

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

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

index a949c9dee77aeb136c578875e11c517aa02271ce..63d2ff94b7e1337ec2a050daa5d0803650914dc4 100644 (file)
 namespace sc_gem5
 {
 
-void
-Sensitivity::satisfy()
-{
-    warn_once("Ignoring suspended status for now.\n");
-    process->setDynamic(nullptr);
-    scheduler.ready(process);
-}
-
 SensitivityTimeout::SensitivityTimeout(Process *p, ::sc_core::sc_time t) :
     Sensitivity(p), timeoutEvent(this), timeout(t)
 {
@@ -88,7 +80,7 @@ SensitivityEventAndList::notifyWork(Event *e)
     e->delSensitivity(this);
     count++;
     if (count == list->events.size())
-        satisfy();
+        process->satisfySensitivity(this);
 }
 
 SensitivityEventOrList::SensitivityEventOrList(
@@ -150,7 +142,7 @@ Process::suspend(bool inc_kids)
 
     if (!_suspended) {
         _suspended = true;
-        //TODO Suspend this process.
+        _suspendedReady = false;
     }
 
     if (procKind() != ::sc_core::SC_METHOD_PROC_ &&
@@ -167,7 +159,9 @@ Process::resume(bool inc_kids)
 
     if (_suspended) {
         _suspended = false;
-        //TODO Resume this process.
+        if (_suspendedReady)
+            ready();
+        _suspendedReady = false;
     }
 }
 
@@ -309,6 +303,26 @@ Process::setDynamic(Sensitivity *s)
     dynamicSensitivity = s;
 }
 
+void
+Process::satisfySensitivity(Sensitivity *s)
+{
+    // If there's a dynamic sensitivity and this wasn't it, ignore.
+    if (dynamicSensitivity && dynamicSensitivity != s)
+        return;
+
+    setDynamic(nullptr);
+    ready();
+}
+
+void
+Process::ready()
+{
+    if (suspended())
+        _suspendedReady = true;
+    else
+        scheduler.ready(this);
+}
+
 Process::Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) :
     ::sc_core::sc_object(name), excWrapper(nullptr), func(func),
     _running(false), _dynamic(_dynamic), _isUnwinding(false),
index cd92992ebe0a84c6f4c97f94f3e7d5f919f17e17..579ea602f53ce8d7a710f1fe5673d7b988468547 100644 (file)
@@ -51,13 +51,12 @@ class Sensitivity
 {
   protected:
     Process *process;
-    void satisfy();
 
   public:
     Sensitivity(Process *p) : process(p) {}
     virtual ~Sensitivity() {}
 
-    virtual void notifyWork(Event *e) { satisfy(); }
+    virtual void notifyWork(Event *e);
     void notify(Event *e);
     void notify() { notify(nullptr); }
 
@@ -290,6 +289,10 @@ class Process : public ::sc_core::sc_object, public ListNode
     void addStatic(PendingSensitivity *);
     void setDynamic(Sensitivity *);
 
+    void satisfySensitivity(Sensitivity *);
+
+    void ready();
+
     virtual Fiber *fiber() { return Fiber::primaryFiber(); }
 
     static Process *newest() { return _newest; }
@@ -317,6 +320,7 @@ class Process : public ::sc_core::sc_object, public ListNode
     bool _terminated;
 
     bool _suspended;
+    bool _suspendedReady;
     bool _disabled;
 
     bool _syncReset;
@@ -331,6 +335,12 @@ class Process : public ::sc_core::sc_object, public ListNode
     Sensitivity *dynamicSensitivity;
 };
 
+inline void
+Sensitivity::notifyWork(Event *e)
+{
+    process->satisfySensitivity(this);
+}
+
 inline void
 Sensitivity::notify(Event *e)
 {
index 8ea090f57f387b7912fb97c9e2345e59dbe587fe..230ed0af2710ee48b5b3bb2c94b39d3fdabf5d32 100644 (file)
@@ -51,7 +51,7 @@ Scheduler::prepareForInit()
 
     for (Process *p = initList.getNext(); p; p = initList.getNext()) {
         p->finalize();
-        ready(p);
+        p->ready();
     }
 
     initReady = true;
@@ -64,7 +64,7 @@ Scheduler::reg(Process *p)
         // If we're past initialization, finalize static sensitivity.
         p->finalize();
         // Mark the process as ready.
-        ready(p);
+        p->ready();
     } else {
         // Otherwise, record that this process should be initialized once we
         // get there.