From 6a198f29234a6a037f73cefd15f784bd18017d1a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Jul 2018 15:13:52 -0700 Subject: systemc: Adjust process status tracking to improve kill/reset support. 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 Maintainer: Gabe Black --- src/systemc/core/process.cc | 49 ++++++++++++++++++++++++++++----------- src/systemc/core/process.hh | 5 ++-- src/systemc/core/process_types.hh | 13 ++++++++--- 3 files changed, 48 insertions(+), 19 deletions(-) (limited to 'src/systemc') diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc index 6a0e7d5a3..6b4c42766 100644 --- a/src/systemc/core/process.cc +++ b/src/systemc/core/process.cc @@ -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 diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh index 8abafbd69..5f0a72d1e 100644 --- a/src/systemc/core/process.hh +++ b/src/systemc/core/process.hh @@ -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; diff --git a/src/systemc/core/process_types.hh b/src/systemc/core/process_types.hh index 369fa726e..7617d41ef 100644 --- a/src/systemc/core/process_types.hh +++ b/src/systemc/core/process_types.hh @@ -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; }; -- cgit v1.2.3