systemc: Fill out process handle kill and reset mechanisms.
authorGabe Black <gabeblack@google.com>
Sat, 21 Jul 2018 05:16:12 +0000 (22:16 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 11 Sep 2018 21:46:48 +0000 (21:46 +0000)
Some flags were being updated too early, making the functions think
what they were about to do had already been done. Also, actually check
for and throw the exception installed in a process when it's next
supposed to run, and when injecting an exception schedule that other
process to run immediately.

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

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

index 678cb04dbc1d3b76fc61748e0e14563005cbd8f9..ec5c57cb9180797908b3e635342f949783045f2a 100644 (file)
@@ -108,15 +108,13 @@ SensitivityEventOrList::~SensitivityEventOrList()
 class UnwindExceptionReset : public ::sc_core::sc_unwind_exception
 {
   public:
-    const char *what() const throw() override { return "RESET"; }
-    bool is_reset() const override { return true; }
+    UnwindExceptionReset() { _isReset = true; }
 };
 
 class UnwindExceptionKill : public ::sc_core::sc_unwind_exception
 {
   public:
-    const char *what() const throw() override { return "KILL"; }
-    bool is_reset() const override { return false; }
+    UnwindExceptionKill() {}
 };
 
 template <typename T>
@@ -194,10 +192,6 @@ Process::enable(bool inc_kids)
 void
 Process::kill(bool inc_kids)
 {
-    // Update our state.
-    _terminated = true;
-    _isUnwinding = true;
-
     // Propogate the kill to our children no matter what happens to us.
     if (inc_kids)
         forEachKid([](Process *p) { p->kill(true); });
@@ -206,6 +200,13 @@ Process::kill(bool inc_kids)
     if (_isUnwinding)
         return;
 
+    // Update our state.
+    _terminated = true;
+    _isUnwinding = true;
+    _suspendedReady = false;
+    _suspended = false;
+    _syncReset = false;
+
     // Inject the kill exception into this process.
     injectException(killException);
 
@@ -215,9 +216,6 @@ Process::kill(bool inc_kids)
 void
 Process::reset(bool inc_kids)
 {
-    // Update our state.
-    _isUnwinding = true;
-
     // Propogate the reset to our children no matter what happens to us.
     if (inc_kids)
         forEachKid([](Process *p) { p->reset(true); });
@@ -226,6 +224,9 @@ Process::reset(bool inc_kids)
     if (_isUnwinding)
         return;
 
+    // Update our state.
+    _isUnwinding = true;
+
     // Inject the reset exception into this process.
     injectException(resetException);
 
@@ -243,7 +244,7 @@ void
 Process::injectException(ExceptionWrapperBase &exc)
 {
     excWrapper = &exc;
-    // Let this process preempt us.
+    scheduler.runNow(this);
 };
 
 void
@@ -289,8 +290,9 @@ Process::run()
         reset = false;
         try {
             func->call();
-        } catch(::sc_core::sc_unwind_exception exc) {
+        } catch(const ::sc_core::sc_unwind_exception &exc) {
             reset = exc.is_reset();
+            _isUnwinding = false;
         }
     } while (reset);
     _terminated = true;
index c2b5ec38d605abe57dd355fce54a35321caa05b5..085602d7b4895c2ece439543bb7c7552c4374112 100644 (file)
@@ -117,6 +117,13 @@ Scheduler::yield()
         if (_current && _current->needsStart())
             _current->run();
     }
+    if (_current && _current->excWrapper) {
+        // Make sure this isn't a method process.
+        assert(!_current->needsStart());
+        auto ew = _current->excWrapper;
+        _current->excWrapper = nullptr;
+        ew->throw_it();
+    }
 }
 
 void