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 <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user