systemc: Handle suspended processes and handle sensitivity overload.
This change keeps track of whether a process would have become ready but was suspended so that it can become ready when the process is resumed. Also, this makes a process ignore its static sensitivity while a dynamic sensitivity is in place. Change-Id: If3f6c62f370051e574f81bf227746db8c43527e2 Reviewed-on: https://gem5-review.googlesource.com/11715 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -36,14 +36,6 @@
|
||||
namespace sc_gem5
|
||||
{
|
||||
|
||||
void
|
||||
Sensitivity::satisfy()
|
||||
{
|
||||
warn_once("Ignoring suspended status for now.\n");
|
||||
process->setDynamic(nullptr);
|
||||
scheduler.ready(process);
|
||||
}
|
||||
|
||||
SensitivityTimeout::SensitivityTimeout(Process *p, ::sc_core::sc_time t) :
|
||||
Sensitivity(p), timeoutEvent(this), timeout(t)
|
||||
{
|
||||
@@ -88,7 +80,7 @@ SensitivityEventAndList::notifyWork(Event *e)
|
||||
e->delSensitivity(this);
|
||||
count++;
|
||||
if (count == list->events.size())
|
||||
satisfy();
|
||||
process->satisfySensitivity(this);
|
||||
}
|
||||
|
||||
SensitivityEventOrList::SensitivityEventOrList(
|
||||
@@ -150,7 +142,7 @@ Process::suspend(bool inc_kids)
|
||||
|
||||
if (!_suspended) {
|
||||
_suspended = true;
|
||||
//TODO Suspend this process.
|
||||
_suspendedReady = false;
|
||||
}
|
||||
|
||||
if (procKind() != ::sc_core::SC_METHOD_PROC_ &&
|
||||
@@ -167,7 +159,9 @@ Process::resume(bool inc_kids)
|
||||
|
||||
if (_suspended) {
|
||||
_suspended = false;
|
||||
//TODO Resume this process.
|
||||
if (_suspendedReady)
|
||||
ready();
|
||||
_suspendedReady = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,6 +303,26 @@ Process::setDynamic(Sensitivity *s)
|
||||
dynamicSensitivity = s;
|
||||
}
|
||||
|
||||
void
|
||||
Process::satisfySensitivity(Sensitivity *s)
|
||||
{
|
||||
// If there's a dynamic sensitivity and this wasn't it, ignore.
|
||||
if (dynamicSensitivity && dynamicSensitivity != s)
|
||||
return;
|
||||
|
||||
setDynamic(nullptr);
|
||||
ready();
|
||||
}
|
||||
|
||||
void
|
||||
Process::ready()
|
||||
{
|
||||
if (suspended())
|
||||
_suspendedReady = true;
|
||||
else
|
||||
scheduler.ready(this);
|
||||
}
|
||||
|
||||
Process::Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) :
|
||||
::sc_core::sc_object(name), excWrapper(nullptr), func(func),
|
||||
_running(false), _dynamic(_dynamic), _isUnwinding(false),
|
||||
|
||||
@@ -51,13 +51,12 @@ class Sensitivity
|
||||
{
|
||||
protected:
|
||||
Process *process;
|
||||
void satisfy();
|
||||
|
||||
public:
|
||||
Sensitivity(Process *p) : process(p) {}
|
||||
virtual ~Sensitivity() {}
|
||||
|
||||
virtual void notifyWork(Event *e) { satisfy(); }
|
||||
virtual void notifyWork(Event *e);
|
||||
void notify(Event *e);
|
||||
void notify() { notify(nullptr); }
|
||||
|
||||
@@ -290,6 +289,10 @@ class Process : public ::sc_core::sc_object, public ListNode
|
||||
void addStatic(PendingSensitivity *);
|
||||
void setDynamic(Sensitivity *);
|
||||
|
||||
void satisfySensitivity(Sensitivity *);
|
||||
|
||||
void ready();
|
||||
|
||||
virtual Fiber *fiber() { return Fiber::primaryFiber(); }
|
||||
|
||||
static Process *newest() { return _newest; }
|
||||
@@ -317,6 +320,7 @@ class Process : public ::sc_core::sc_object, public ListNode
|
||||
bool _terminated;
|
||||
|
||||
bool _suspended;
|
||||
bool _suspendedReady;
|
||||
bool _disabled;
|
||||
|
||||
bool _syncReset;
|
||||
@@ -331,6 +335,12 @@ class Process : public ::sc_core::sc_object, public ListNode
|
||||
Sensitivity *dynamicSensitivity;
|
||||
};
|
||||
|
||||
inline void
|
||||
Sensitivity::notifyWork(Event *e)
|
||||
{
|
||||
process->satisfySensitivity(this);
|
||||
}
|
||||
|
||||
inline void
|
||||
Sensitivity::notify(Event *e)
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ Scheduler::prepareForInit()
|
||||
|
||||
for (Process *p = initList.getNext(); p; p = initList.getNext()) {
|
||||
p->finalize();
|
||||
ready(p);
|
||||
p->ready();
|
||||
}
|
||||
|
||||
initReady = true;
|
||||
@@ -64,7 +64,7 @@ Scheduler::reg(Process *p)
|
||||
// If we're past initialization, finalize static sensitivity.
|
||||
p->finalize();
|
||||
// Mark the process as ready.
|
||||
ready(p);
|
||||
p->ready();
|
||||
} else {
|
||||
// Otherwise, record that this process should be initialized once we
|
||||
// get there.
|
||||
|
||||
Reference in New Issue
Block a user