From 86d82dff58d631318161127b67d5689bb44f76cf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 10 Sep 2018 17:25:00 -0700 Subject: systemc: Keep all pre-init processes on a single list. We were keeping track of processes which should be initialized and those which shouldn't on two different lists, and then processing each list one after the other. This could reorder processes from the order they were created, and so cause spurious differences which cause the Accellera tests to fail. This does make the scheduler slightly simpler, so it's not all bad. Change-Id: I63306a41ce7bea91fa9ff2f6774ce9150134ce48 Reviewed-on: https://gem5-review.googlesource.com/c/12613 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/core/process.cc | 12 +++------- src/systemc/core/process.hh | 8 ++++--- src/systemc/core/sc_module.cc | 4 ++-- src/systemc/core/sc_spawn.cc | 5 ++--- src/systemc/core/scheduler.cc | 52 +++++++++++++------------------------------ src/systemc/core/scheduler.hh | 4 ---- 6 files changed, 28 insertions(+), 57 deletions(-) (limited to 'src/systemc/core') diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc index e4d213bc1..553f332d3 100644 --- a/src/systemc/core/process.cc +++ b/src/systemc/core/process.cc @@ -313,12 +313,6 @@ Process::syncResetOff(bool inc_kids) _syncReset = false; } -void -Process::dontInitialize() -{ - scheduler.dontInitialize(this); -} - void Process::finalize() { @@ -400,9 +394,9 @@ Process::lastReport(::sc_core::sc_report *report) Process::Process(const char *name, ProcessFuncWrapper *func, bool internal) : ::sc_core::sc_process_b(name), excWrapper(nullptr), func(func), - _internal(internal), _timedOut(false), _needsStart(true), - _isUnwinding(false), _terminated(false), _suspended(false), - _disabled(false), _syncReset(false), refCount(0), + _internal(internal), _timedOut(false), _dontInitialize(false), + _needsStart(true), _isUnwinding(false), _terminated(false), + _suspended(false), _disabled(false), _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize), dynamicSensitivity(nullptr) { _dynamic = diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh index 1ea599747..4d88e27b8 100644 --- a/src/systemc/core/process.hh +++ b/src/systemc/core/process.hh @@ -319,9 +319,6 @@ class Process : public ::sc_core::sc_process_b, public ListNode const ::sc_core::sc_event &resetEvent() { return _resetEvent; } const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; } - // This should only be called before initialization. - void dontInitialize(); - void setStackSize(size_t size) { stackSize = size; } void finalize(); @@ -347,6 +344,9 @@ class Process : public ::sc_core::sc_process_b, public ListNode bool timedOut() { return _timedOut; } void timedOut(bool to) { _timedOut = to; } + bool dontInitialize() { return _dontInitialize; } + void dontInitialize(bool di) { _dontInitialize = di; } + protected: Process(const char *name, ProcessFuncWrapper *func, bool internal=false); @@ -371,6 +371,8 @@ class Process : public ::sc_core::sc_process_b, public ListNode // Needed to support the deprecated "timed_out" function. bool _timedOut; + bool _dontInitialize; + bool _needsStart; bool _dynamic; bool _isUnwinding; diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc index 2fc6e8c75..e695f7697 100644 --- a/src/systemc/core/sc_module.cc +++ b/src/systemc/core/sc_module.cc @@ -86,7 +86,7 @@ newCThreadProcess(const char *name, ProcessFuncWrapper *func) return nullptr; } scheduler.reg(p); - p->dontInitialize(); + p->dontInitialize(true); return p; } @@ -296,7 +296,7 @@ sc_module::async_reset_signal_is(const sc_signal_in_if &, bool) void sc_module::dont_initialize() { - ::sc_gem5::Process::newest()->dontInitialize(); + ::sc_gem5::Process::newest()->dontInitialize(true); } void diff --git a/src/systemc/core/sc_spawn.cc b/src/systemc/core/sc_spawn.cc index 00fe502e6..9e2b4c83a 100644 --- a/src/systemc/core/sc_spawn.cc +++ b/src/systemc/core/sc_spawn.cc @@ -66,6 +66,8 @@ spawnWork(ProcessFuncWrapper *func, const char *name, else proc = new Thread(name, func); + proc->dontInitialize(dontInitialize); + if (opts) { for (auto e: opts->_events) proc->addStatic(new PendingSensitivityEvent(proc, e)); @@ -95,9 +97,6 @@ spawnWork(ProcessFuncWrapper *func, const char *name, scheduler.reg(proc); - if (dontInitialize) - scheduler.dontInitialize(proc); - return proc; } diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc index 801580947..fe00ac0f8 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -88,8 +88,6 @@ Scheduler::clear() deschedule(&maxTickEvent); Process *p; - while ((p = toFinalize.getNext())) - p->popListNode(); while ((p = initList.getNext())) p->popListNode(); while ((p = readyListMethods.getNext())) @@ -105,24 +103,22 @@ Scheduler::clear() void Scheduler::initPhase() { - for (Process *p = toFinalize.getNext(); p; p = toFinalize.getNext()) { + for (Process *p = initList.getNext(); p; p = initList.getNext()) { p->finalize(); p->popListNode(); - if (!p->hasStaticSensitivities() && !p->internal()) { - SC_REPORT_WARNING( - "(W558) disable() or dont_initialize() called on process " - "with no static sensitivity, it will be orphaned", - p->name()); + if (p->dontInitialize()) { + if (!p->hasStaticSensitivities() && !p->internal()) { + SC_REPORT_WARNING( + "(W558) disable() or dont_initialize() called on " + "process with no static sensitivity, it will be " + "orphaned", p->name()); + } + } else { + p->ready(); } } - for (Process *p = initList.getNext(); p; p = initList.getNext()) { - p->finalize(); - p->popListNode(); - p->ready(); - } - runUpdate(); runDelta(); @@ -147,8 +143,9 @@ Scheduler::reg(Process *p) if (initDone) { // If we're past initialization, finalize static sensitivity. p->finalize(); - // Mark the process as ready. - p->ready(); + // If not marked as dontInitialize, mark as ready. + if (!p->dontInitialize()) + p->ready(); } else { // Otherwise, record that this process should be initialized once we // get there. @@ -156,20 +153,6 @@ Scheduler::reg(Process *p) } } -void -Scheduler::dontInitialize(Process *p) -{ - if (initDone) { - // Pop this process off of the ready list. - p->popListNode(); - } else { - // Push this process onto the list of processes which still need - // their static sensitivity to be finalized. That implicitly pops it - // off the list of processes to be initialized/marked ready. - toFinalize.pushLast(p); - } -} - void Scheduler::yield() { @@ -240,15 +223,12 @@ Scheduler::suspend(Process *p) { bool was_ready; if (initDone) { - // After initialization, the only list we can be on is the ready list. + // After initialization, check if we're on a ready list. was_ready = (p->nextListNode != nullptr); p->popListNode(); } else { - // Check the ready lists to see if we find this process. - was_ready = listContains(&readyListMethods, p) || - listContains(&readyListThreads, p); - if (was_ready) - toFinalize.pushLast(p); + // Nothing is ready before init. + was_ready = false; } return was_ready; } diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index 052be08c3..0bbc3dac6 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -173,9 +173,6 @@ class Scheduler // Register a process with the scheduler. void reg(Process *p); - // Tell the scheduler not to initialize a process. - void dontInitialize(Process *p); - // Run the next process, if there is one. void yield(); @@ -439,7 +436,6 @@ class Scheduler bool runOnce; ProcessList initList; - ProcessList toFinalize; ProcessList *readyList; ProcessList readyListMethods; -- cgit v1.2.3