systemc: Don't re-schedule a process which is already scheduled.
authorGabe Black <gabeblack@google.com>
Tue, 9 Oct 2018 06:08:27 +0000 (23:08 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 16 Oct 2018 01:15:18 +0000 (01:15 +0000)
Change-Id: I8e12713c49aad03d0bfb779883adcbfa8fd4b42e
Reviewed-on: https://gem5-review.googlesource.com/c/13334
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 a0759d9ccbc764c7f418cf1f2042b301fcd3d187..e29cee030303687653ced2a5c4e40ee96a8ec25f 100644 (file)
@@ -359,7 +359,7 @@ Process::ready()
         return;
     if (suspended())
         _suspendedReady = true;
-    else
+    else if (!scheduled())
         scheduler.ready(this);
 }
 
@@ -381,9 +381,10 @@ Process::Process(const char *name, ProcessFuncWrapper *func, bool internal) :
     timeoutEvent([this]() { this->timeout(); }),
     func(func), _internal(internal), _timedOut(false), _dontInitialize(false),
     _needsStart(true), _isUnwinding(false), _terminated(false),
-    _suspended(false), _disabled(false), _syncReset(false), syncResetCount(0),
-    asyncResetCount(0), _waitCount(0), refCount(0),
-    stackSize(::Fiber::DefaultStackSize), dynamicSensitivity(nullptr)
+    _scheduled(false), _suspended(false), _disabled(false),
+    _syncReset(false), syncResetCount(0), asyncResetCount(0), _waitCount(0),
+    refCount(0), stackSize(::Fiber::DefaultStackSize),
+    dynamicSensitivity(nullptr)
 {
     _dynamic =
             (::sc_core::sc_get_status() >
index d50c82905e15216b953b44d696f24fe52ba97de2..12901bc8e9d3422cb463be1af7dec96bacc2aaa5 100644 (file)
@@ -72,6 +72,9 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     void isUnwinding(bool v) { _isUnwinding = v; }
     bool terminated() const { return _terminated; }
 
+    bool scheduled() const { return _scheduled; }
+    void scheduled(bool new_val) { _scheduled = new_val; }
+
     void forEachKid(const std::function<void(Process *)> &work);
 
     bool suspended() const { return _suspended; }
@@ -172,6 +175,7 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     bool _dynamic;
     bool _isUnwinding;
     bool _terminated;
+    bool _scheduled;
 
     void terminate();
 
index ec91c795a8c79924eae0e3714d879a3605f8e745..52bf7ec315d440897d43333e546568dfd087e350 100644 (file)
@@ -165,6 +165,7 @@ Scheduler::yield()
         Fiber::primaryFiber()->run();
     } else {
         _current->popListNode();
+        _current->scheduled(false);
         // Switch to whatever Fiber is supposed to run this process. All
         // Fibers which aren't running should be parked at this line.
         _current->fiber()->run();
@@ -199,6 +200,8 @@ Scheduler::ready(Process *p)
     if (_stopNow)
         return;
 
+    p->scheduled(true);
+
     if (p->procKind() == ::sc_core::SC_METHOD_PROC_)
         readyListMethods.pushLast(p);
     else