systemc: Adjust process status tracking to improve kill/reset support.
authorGabe Black <gabeblack@google.com>
Thu, 26 Jul 2018 22:13:52 +0000 (15:13 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 11 Sep 2018 21:49:01 +0000 (21:49 +0000)
This change rearranges how process status is tracked so that the kill
and reset mechanisms work in more circumstances and more like they're
supposed to according to the spec. This makes another test or two pass.

Change-Id: Ie2a683a796155a82092109d5bb45f07c84e06c76
Reviewed-on: https://gem5-review.googlesource.com/12049
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/process_types.hh

index 6a0e7d5a33341559c634ff42c7abcb52a0e7e309..6b4c4276610b16c41c79bec5437e3384e117ed5c 100644 (file)
@@ -32,6 +32,8 @@
 #include "base/logging.hh"
 #include "systemc/core/event.hh"
 #include "systemc/core/scheduler.hh"
+#include "systemc/ext/core/sc_process_handle.hh"
+#include "systemc/ext/utils/sc_report_handler.hh"
 
 namespace sc_gem5
 {
@@ -201,14 +203,15 @@ Process::kill(bool inc_kids)
         return;
 
     // Update our state.
-    _terminated = true;
+    terminate();
     _isUnwinding = true;
-    _suspendedReady = false;
-    _suspended = false;
-    _syncReset = false;
 
-    // Inject the kill exception into this process.
-    injectException(killException);
+    // Make sure this process isn't marked ready
+    popListNode();
+
+    // Inject the kill exception into this process if it's started.
+    if (!_needsStart)
+        injectException(killException);
 
     _terminatedEvent.notify();
 }
@@ -224,11 +227,13 @@ Process::reset(bool inc_kids)
     if (_isUnwinding)
         return;
 
-    // Update our state.
-    _isUnwinding = true;
 
-    // Inject the reset exception into this process.
-    injectException(resetException);
+    if (_needsStart) {
+        scheduler.runNow(this);
+    } else {
+        _isUnwinding = true;
+        injectException(resetException);
+    }
 
     _resetEvent.notify();
 }
@@ -238,6 +243,10 @@ Process::throw_it(ExceptionWrapperBase &exc, bool inc_kids)
 {
     if (inc_kids)
         forEachKid([&exc](Process *p) { p->throw_it(exc, true); });
+
+    // Only inject an exception into threads that have started.
+    if (!_needsStart)
+        injectException(exc);
 }
 
 void
@@ -295,7 +304,6 @@ Process::run()
             _isUnwinding = false;
         }
     } while (reset);
-    _terminated = true;
 }
 
 void
@@ -346,10 +354,9 @@ Process::lastReport(::sc_core::sc_report *report)
 
 ::sc_core::sc_report *Process::lastReport() const { return _lastReport.get(); }
 
-Process::Process(const char *name, ProcessFuncWrapper *func,
-        bool _dynamic, bool needs_start) :
+Process::Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) :
     ::sc_core::sc_object(name), excWrapper(nullptr), func(func),
-    _needsStart(needs_start), _dynamic(_dynamic), _isUnwinding(false),
+    _needsStart(true), _dynamic(_dynamic), _isUnwinding(false),
     _terminated(false), _suspended(false), _disabled(false),
     _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize),
     dynamicSensitivity(nullptr)
@@ -357,6 +364,20 @@ Process::Process(const char *name, ProcessFuncWrapper *func,
     _newest = this;
 }
 
+void
+Process::terminate()
+{
+    _terminated = true;
+    _suspendedReady = false;
+    _suspended = false;
+    _syncReset = false;
+    delete dynamicSensitivity;
+    dynamicSensitivity = nullptr;
+    for (auto s: staticSensitivities)
+        delete s;
+    staticSensitivities.clear();
+}
+
 Process *Process::_newest;
 
 void
index 8abafbd6992185597fa880edaf80086657ab5670..5f0a72d1e0e770f6e19c9188c63c92a0857014f0 100644 (file)
@@ -325,8 +325,7 @@ class Process : public ::sc_core::sc_object, public ListNode
     ::sc_core::sc_report *lastReport() const;
 
   protected:
-    Process(const char *name, ProcessFuncWrapper *func, bool _dynamic,
-            bool needs_start);
+    Process(const char *name, ProcessFuncWrapper *func, bool _dynamic);
 
     static Process *_newest;
 
@@ -347,6 +346,8 @@ class Process : public ::sc_core::sc_object, public ListNode
     bool _isUnwinding;
     bool _terminated;
 
+    void terminate();
+
     bool _suspended;
     bool _suspendedReady;
     bool _disabled;
index 369fa726e94a72c56615a56d3948fba5886b9164..7617d41efd7085aa80b8547ed0fed2744dabfe28 100644 (file)
@@ -40,7 +40,7 @@ class Method : public Process
 {
   public:
     Method(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
-        Process(name, func, _dynamic, true)
+        Process(name, func, _dynamic)
     {}
 
     const char *kind() const override { return "sc_method_process"; }
@@ -56,7 +56,7 @@ class Thread : public Process
 {
   public:
     Thread(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
-        Process(name, func, _dynamic, false), ctx(nullptr)
+        Process(name, func, _dynamic), ctx(nullptr)
     {}
 
     ~Thread() { delete ctx; }
@@ -88,8 +88,15 @@ class Thread : public Process
       private:
         Thread *thread;
 
-        void main() override { thread->run(); }
+        void
+        main() override
+        {
+            thread->_needsStart = false;
+            thread->run();
+            thread->terminate();
+        }
     };
+    friend class Context;
 
     Context *ctx;
 };