summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-07-16 16:14:33 -0700
committerGabe Black <gabeblack@google.com>2018-09-05 06:06:00 +0000
commitf2ab5e7a9e11783da3b9d7338775cf4b5fe2c29c (patch)
treec8b08f18270cb3131f37b6e0bfe1e8f2e94da63d
parentd7755ec828868582e2b409ba14f1c8c920c7f184 (diff)
downloadgem5-f2ab5e7a9e11783da3b9d7338775cf4b5fe2c29c.tar.xz
systemc: Implement the sensitivity mechanism.
This change lets processes be sensitive to events, timeouts, etc. Change-Id: If30a256dfa8a2e92192c1f9c96b48e2aa28ec27e Reviewed-on: https://gem5-review.googlesource.com/11713 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r--src/systemc/core/bindinfo.hh46
-rw-r--r--src/systemc/core/event.cc25
-rw-r--r--src/systemc/core/event.hh11
-rw-r--r--src/systemc/core/kernel.cc2
-rw-r--r--src/systemc/core/process.cc112
-rw-r--r--src/systemc/core/process.hh233
-rw-r--r--src/systemc/core/sc_port.cc8
-rw-r--r--src/systemc/core/sc_sensitive.cc22
-rw-r--r--src/systemc/core/scheduler.cc46
-rw-r--r--src/systemc/core/scheduler.hh18
-rw-r--r--src/systemc/ext/core/sc_event.hh4
-rw-r--r--src/systemc/ext/core/sc_port.hh22
12 files changed, 523 insertions, 26 deletions
diff --git a/src/systemc/core/bindinfo.hh b/src/systemc/core/bindinfo.hh
new file mode 100644
index 000000000..332fb1330
--- /dev/null
+++ b/src/systemc/core/bindinfo.hh
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __SYSTEMC_CORE_BINDINFO_HH__
+#define __SYSTEMC_CORE_BINDINFO_HH__
+
+#include "systemc/ext/core/sc_interface.hh"
+
+namespace sc_gem5
+{
+
+class BindInfo
+{
+ public:
+ ::sc_core::sc_interface *interface;
+};
+
+} // namespace sc_gem5
+
+#endif // __SYSTEMC_CORE_BINDINFO_HH__
diff --git a/src/systemc/core/event.cc b/src/systemc/core/event.cc
index 63fcabe4f..5008074f6 100644
--- a/src/systemc/core/event.cc
+++ b/src/systemc/core/event.cc
@@ -32,6 +32,8 @@
#include <cstring>
#include <utility>
+#include "base/logging.hh"
+#include "sim/core.hh"
#include "systemc/core/module.hh"
#include "systemc/core/scheduler.hh"
@@ -41,7 +43,7 @@ namespace sc_gem5
Event::Event(sc_core::sc_event *_sc_event) : Event(_sc_event, "") {}
Event::Event(sc_core::sc_event *_sc_event, const char *_basename) :
- _sc_event(_sc_event), _basename(_basename)
+ _sc_event(_sc_event), _basename(_basename), delayedNotify(this)
{
Module *p = currentModule();
@@ -81,6 +83,9 @@ Event::~Event()
EventsIt it = findEvent(_name);
std::swap(*it, allEvents.back());
allEvents.pop_back();
+
+ if (delayedNotifyEvent.scheduled())
+ scheduler.deschedule(&delayedNotifyEvent);
}
const std::string &
@@ -110,16 +115,34 @@ Event::getParentObject() const
void
Event::notify()
{
+ auto local_sensitivities = sensitivities;
+ for (auto s: local_sensitivities)
+ s->notify(this);
}
void
Event::notify(const sc_core::sc_time &t)
{
+ //XXX We're assuming the systemc time resolution is in ps.
+ Tick new_tick = t.value() * SimClock::Int::ps +
+ scheduler.eventQueue().getCurTick();
+ if (delayedNotify.scheduled()) {
+ Tick old_tick = delayedNotify.when();
+
+ if (new_tick >= old_tick)
+ return;
+
+ scheduler.eventQueue().deschedule(&delayedNotify);
+ }
+
+ scheduler.eventQueue().schedule(&delayedNotify, new_tick);
}
void
Event::cancel()
{
+ if (delayedNotify.scheduled())
+ scheduler.eventQueue().deschedule(&delayedNotify);
}
bool
diff --git a/src/systemc/core/event.hh b/src/systemc/core/event.hh
index bf9afd40f..a9d318382 100644
--- a/src/systemc/core/event.hh
+++ b/src/systemc/core/event.hh
@@ -30,9 +30,11 @@
#ifndef __SYSTEMC_CORE_EVENT_HH__
#define __SYSTEMC_CORE_EVENT_HH__
+#include <set>
#include <string>
#include <vector>
+#include "sim/eventq.hh"
#include "systemc/core/list.hh"
#include "systemc/core/object.hh"
#include "systemc/ext/core/sc_prim.hh"
@@ -50,6 +52,8 @@ namespace sc_gem5
typedef std::vector<sc_core::sc_event *> Events;
+class Sensitivity;
+
class Event
{
public:
@@ -88,6 +92,9 @@ class Event
return e->_gem5_event;
}
+ void addSensitivity(Sensitivity *s) const { sensitivities.insert(s); }
+ void delSensitivity(Sensitivity *s) const { sensitivities.erase(s); }
+
private:
sc_core::sc_event *_sc_event;
@@ -97,6 +104,10 @@ class Event
sc_core::sc_object *parent;
EventsIt parentIt;
+
+ EventWrapper<Event, &Event::notify> delayedNotify;
+
+ mutable std::set<Sensitivity *> sensitivities;
};
extern Events topLevelEvents;
diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc
index e93236541..3b75c2fd2 100644
--- a/src/systemc/core/kernel.cc
+++ b/src/systemc/core/kernel.cc
@@ -56,7 +56,7 @@ Kernel::t0Handler()
// happen before them, honoring the ordering for the initialization phase
// in the spec. The delta phase will happen at normal priority, and then
// the event which runs the processes which is at a lower priority.
- ::sc_gem5::scheduler.initToReady();
+ ::sc_gem5::scheduler.prepareForInit();
}
} // namespace SystemC
diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc
index 26cfb7ecd..a949c9dee 100644
--- a/src/systemc/core/process.cc
+++ b/src/systemc/core/process.cc
@@ -28,11 +28,84 @@
*/
#include "systemc/core/process.hh"
+
+#include "base/logging.hh"
+#include "systemc/core/event.hh"
#include "systemc/core/scheduler.hh"
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)
+{
+ Tick when = scheduler.eventQueue().getCurTick() + timeout.value();
+ scheduler.eventQueue().schedule(&timeoutEvent, when);
+}
+
+SensitivityTimeout::~SensitivityTimeout()
+{
+ if (timeoutEvent.scheduled())
+ scheduler.eventQueue().deschedule(&timeoutEvent);
+}
+
+SensitivityEvent::SensitivityEvent(
+ Process *p, const ::sc_core::sc_event *e) : Sensitivity(p), event(e)
+{
+ Event::getFromScEvent(event)->addSensitivity(this);
+}
+
+SensitivityEvent::~SensitivityEvent()
+{
+ Event::getFromScEvent(event)->delSensitivity(this);
+}
+
+SensitivityEventAndList::SensitivityEventAndList(
+ Process *p, const ::sc_core::sc_event_and_list *list) :
+ Sensitivity(p), list(list), count(0)
+{
+ for (auto e: list->events)
+ Event::getFromScEvent(e)->addSensitivity(this);
+}
+
+SensitivityEventAndList::~SensitivityEventAndList()
+{
+ for (auto e: list->events)
+ Event::getFromScEvent(e)->delSensitivity(this);
+}
+
+void
+SensitivityEventAndList::notifyWork(Event *e)
+{
+ e->delSensitivity(this);
+ count++;
+ if (count == list->events.size())
+ satisfy();
+}
+
+SensitivityEventOrList::SensitivityEventOrList(
+ Process *p, const ::sc_core::sc_event_or_list *list) :
+ Sensitivity(p), list(list)
+{
+ for (auto e: list->events)
+ Event::getFromScEvent(e)->addSensitivity(this);
+}
+
+SensitivityEventOrList::~SensitivityEventOrList()
+{
+ for (auto e: list->events)
+ Event::getFromScEvent(e)->delSensitivity(this);
+}
+
+
class UnwindExceptionReset : public ::sc_core::sc_unwind_exception
{
public:
@@ -191,6 +264,23 @@ Process::syncResetOff(bool inc_kids)
}
void
+Process::dontInitialize()
+{
+ scheduler.dontInitialize(this);
+}
+
+void
+Process::finalize()
+{
+ for (auto &s: pendingStaticSensitivities) {
+ s->finalize(staticSensitivities);
+ delete s;
+ s = nullptr;
+ }
+ pendingStaticSensitivities.clear();
+};
+
+void
Process::run()
{
_running = true;
@@ -206,15 +296,31 @@ Process::run()
_running = false;
}
+void
+Process::addStatic(PendingSensitivity *s)
+{
+ pendingStaticSensitivities.push_back(s);
+}
+
+void
+Process::setDynamic(Sensitivity *s)
+{
+ delete dynamicSensitivity;
+ dynamicSensitivity = s;
+}
+
Process::Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) :
::sc_core::sc_object(name), excWrapper(nullptr), func(func),
_running(false), _dynamic(_dynamic), _isUnwinding(false),
_terminated(false), _suspended(false), _disabled(false),
- _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize)
+ _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize),
+ dynamicSensitivity(nullptr)
{
_newest = this;
- if (!_dynamic)
- scheduler.init(this);
+ if (_dynamic)
+ finalize();
+ else
+ scheduler.reg(this);
}
Process *Process::_newest;
diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh
index bb9a9c60c..cd92992eb 100644
--- a/src/systemc/core/process.hh
+++ b/src/systemc/core/process.hh
@@ -31,17 +31,218 @@
#define __SYSTEMC_CORE_PROCESS_HH__
#include <functional>
+#include <vector>
#include "base/fiber.hh"
+#include "sim/eventq.hh"
+#include "systemc/core/bindinfo.hh"
#include "systemc/core/list.hh"
#include "systemc/core/object.hh"
#include "systemc/ext/core/sc_event.hh"
+#include "systemc/ext/core/sc_interface.hh"
#include "systemc/ext/core/sc_module.hh"
+#include "systemc/ext/core/sc_port.hh"
#include "systemc/ext/core/sc_process_handle.hh"
namespace sc_gem5
{
+class Sensitivity
+{
+ protected:
+ Process *process;
+ void satisfy();
+
+ public:
+ Sensitivity(Process *p) : process(p) {}
+ virtual ~Sensitivity() {}
+
+ virtual void notifyWork(Event *e) { satisfy(); }
+ void notify(Event *e);
+ void notify() { notify(nullptr); }
+
+ const std::string name();
+};
+
+class SensitivityTimeout : virtual public Sensitivity
+{
+ private:
+ EventWrapper<Sensitivity, &Sensitivity::notify> timeoutEvent;
+ ::sc_core::sc_time timeout;
+
+ public:
+ SensitivityTimeout(Process *p, ::sc_core::sc_time t);
+ ~SensitivityTimeout();
+};
+
+class SensitivityEvent : virtual public Sensitivity
+{
+ private:
+ const ::sc_core::sc_event *event;
+
+ public:
+ SensitivityEvent(Process *p, const ::sc_core::sc_event *e);
+ ~SensitivityEvent();
+};
+
+//XXX This sensitivity can't be reused. To reset it, it has to be deleted and
+//recreated. That works for dynamic sensitivities, but not for static.
+//Fortunately processes can't be statically sensitive to sc_event_and_lists.
+class SensitivityEventAndList : virtual public Sensitivity
+{
+ private:
+ const ::sc_core::sc_event_and_list *list;
+ int count;
+
+ public:
+ SensitivityEventAndList(
+ Process *p, const ::sc_core::sc_event_and_list *list);
+ ~SensitivityEventAndList();
+
+ virtual void notifyWork(Event *e) override;
+};
+
+class SensitivityEventOrList : virtual public Sensitivity
+{
+ private:
+ const ::sc_core::sc_event_or_list *list;
+
+ public:
+ SensitivityEventOrList(
+ Process *p, const ::sc_core::sc_event_or_list *list);
+ ~SensitivityEventOrList();
+};
+
+// Combined sensitivities. These trigger when any of their parts do.
+
+class SensitivityTimeoutAndEvent :
+ public SensitivityTimeout, public SensitivityEvent
+{
+ public:
+ SensitivityTimeoutAndEvent(
+ Process *p, ::sc_core::sc_time t, const ::sc_core::sc_event *e) :
+ Sensitivity(p), SensitivityTimeout(p, t), SensitivityEvent(p, e)
+ {}
+};
+
+class SensitivityTimeoutAndEventAndList :
+ public SensitivityTimeout, public SensitivityEventAndList
+{
+ public:
+ SensitivityTimeoutAndEventAndList(
+ Process *p, ::sc_core::sc_time t,
+ const ::sc_core::sc_event_and_list *eal) :
+ Sensitivity(p), SensitivityTimeout(p, t),
+ SensitivityEventAndList(p, eal)
+ {}
+};
+
+class SensitivityTimeoutAndEventOrList :
+ public SensitivityTimeout, public SensitivityEventOrList
+{
+ public:
+ SensitivityTimeoutAndEventOrList(
+ Process *p, ::sc_core::sc_time t,
+ const ::sc_core::sc_event_or_list *eol) :
+ Sensitivity(p), SensitivityTimeout(p, t),
+ SensitivityEventOrList(p, eol)
+ {}
+};
+
+typedef std::vector<Sensitivity *> Sensitivities;
+
+
+/*
+ * Pending sensitivities. These are records of sensitivities to install later,
+ * once all the information to configure them is available.
+ */
+
+class PendingSensitivity
+{
+ protected:
+ Process *process;
+
+ public:
+ virtual void finalize(Sensitivities &s) = 0;
+ PendingSensitivity(Process *p) : process(p) {}
+ virtual ~PendingSensitivity() {}
+};
+
+class PendingSensitivityEvent : public PendingSensitivity
+{
+ private:
+ const sc_core::sc_event *event;
+
+ public:
+ PendingSensitivityEvent(Process *p, const sc_core::sc_event *e) :
+ PendingSensitivity(p), event(e) {}
+
+ void
+ finalize(Sensitivities &s) override
+ {
+ s.push_back(new SensitivityEvent(process, event));
+ }
+};
+
+class PendingSensitivityInterface : public PendingSensitivity
+{
+ private:
+ const sc_core::sc_interface *interface;
+
+ public:
+ PendingSensitivityInterface(Process *p, const sc_core::sc_interface *i) :
+ PendingSensitivity(p), interface(i)
+ {}
+
+ void
+ finalize(Sensitivities &s) override
+ {
+ s.push_back(new SensitivityEvent(process,
+ &interface->default_event()));
+ }
+};
+
+class PendingSensitivityPort : public PendingSensitivity
+{
+ private:
+ const sc_core::sc_port_base *port;
+
+ public:
+ PendingSensitivityPort(Process *p, const sc_core::sc_port_base *pb) :
+ PendingSensitivity(p), port(pb)
+ {}
+
+ void
+ finalize(Sensitivities &s) override
+ {
+ for (int i = 0; i < port->size(); i++) {
+ const ::sc_core::sc_event *e =
+ &port->_gem5BindInfo[i]->interface->default_event();
+ s.push_back(new SensitivityEvent(process, e));
+ }
+ }
+};
+
+class PendingSensitivityFinder : public PendingSensitivity
+{
+ private:
+ const sc_core::sc_event_finder *finder;
+
+ public:
+ PendingSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
+ PendingSensitivity(p), finder(f)
+ {}
+
+ void
+ finalize(Sensitivities &s) override
+ {
+ s.push_back(new SensitivityEvent(process, &finder->find_event()));
+ }
+};
+
+typedef std::vector<PendingSensitivity *> PendingSensitivities;
+
+
class Process : public ::sc_core::sc_object, public ListNode
{
public:
@@ -78,12 +279,17 @@ class Process : public ::sc_core::sc_object, public ListNode
const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; }
// This should only be called before initialization.
- void dontInitialize() { popListNode(); }
+ void dontInitialize();
void setStackSize(size_t size) { stackSize = size; }
+ void finalize();
+
void run();
+ void addStatic(PendingSensitivity *);
+ void setDynamic(Sensitivity *);
+
virtual Fiber *fiber() { return Fiber::primaryFiber(); }
static Process *newest() { return _newest; }
@@ -93,7 +299,12 @@ class Process : public ::sc_core::sc_object, public ListNode
static Process *_newest;
- virtual ~Process() { delete func; }
+ virtual ~Process()
+ {
+ delete func;
+ for (auto s: staticSensitivities)
+ delete s;
+ }
::sc_core::sc_event _resetEvent;
::sc_core::sc_event _terminatedEvent;
@@ -113,8 +324,26 @@ class Process : public ::sc_core::sc_object, public ListNode
int refCount;
size_t stackSize;
+
+ Sensitivities staticSensitivities;
+ PendingSensitivities pendingStaticSensitivities;
+
+ Sensitivity *dynamicSensitivity;
};
+inline void
+Sensitivity::notify(Event *e)
+{
+ if (!process->disabled())
+ notifyWork(e);
+}
+
+inline const std::string
+Sensitivity::name()
+{
+ return std::string(process->name()) + ".timeout";
+}
+
} // namespace sc_gem5
#endif //__SYSTEMC_CORE_PROCESS_HH__
diff --git a/src/systemc/core/sc_port.cc b/src/systemc/core/sc_port.cc
index 0f981ea54..ad228548f 100644
--- a/src/systemc/core/sc_port.cc
+++ b/src/systemc/core/sc_port.cc
@@ -28,17 +28,25 @@
*/
#include "base/logging.hh"
+#include "systemc/core/bindinfo.hh"
#include "systemc/ext/core/sc_port.hh"
namespace sc_core
{
+sc_port_base::sc_port_base(const char *name, int n, sc_port_policy p) :
+ sc_object(name)
+{}
+
void
sc_port_base::warn_unimpl(const char *func) const
{
warn("%s not implemented.\n", func);
}
+int sc_port_base::maxSize() const { return _maxSize; }
+int sc_port_base::size() const { return _gem5BindInfo.size(); }
+
void
sc_port_base::bind(sc_interface &)
{
diff --git a/src/systemc/core/sc_sensitive.cc b/src/systemc/core/sc_sensitive.cc
index d233cda6a..25bc1bb08 100644
--- a/src/systemc/core/sc_sensitive.cc
+++ b/src/systemc/core/sc_sensitive.cc
@@ -28,6 +28,8 @@
*/
#include "base/logging.hh"
+#include "systemc/core/process.hh"
+#include "systemc/ext/core/sc_interface.hh"
#include "systemc/ext/core/sc_sensitive.hh"
namespace sc_core
@@ -36,30 +38,34 @@ namespace sc_core
sc_sensitive::sc_sensitive() : currentProcess(nullptr) {}
sc_sensitive &
-sc_sensitive::operator << (const sc_event &)
+sc_sensitive::operator << (const sc_event &e)
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+ currentProcess->addStatic(
+ new sc_gem5::PendingSensitivityEvent(currentProcess, &e));
return *this;
}
sc_sensitive &
-sc_sensitive::operator << (const sc_interface &)
+sc_sensitive::operator << (const sc_interface &i)
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+ currentProcess->addStatic(
+ new sc_gem5::PendingSensitivityInterface(currentProcess, &i));
return *this;
}
sc_sensitive &
-sc_sensitive::operator << (const sc_port_base &)
+sc_sensitive::operator << (const sc_port_base &b)
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+ currentProcess->addStatic(
+ new sc_gem5::PendingSensitivityPort(currentProcess, &b));
return *this;
}
sc_sensitive &
-sc_sensitive::operator << (sc_event_finder &)
+sc_sensitive::operator << (sc_event_finder &f)
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+ currentProcess->addStatic(
+ new sc_gem5::PendingSensitivityFinder(currentProcess, &f));
return *this;
}
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index 17e7dc43e..8ea090f57 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -38,14 +38,52 @@ namespace sc_gem5
Scheduler::Scheduler() :
eq(nullptr), readyEvent(this, false, EventBase::Default_Pri + 1),
- _numCycles(0), _current(nullptr)
+ _numCycles(0), _current(nullptr), initReady(false)
{}
void
-Scheduler::initToReady()
+Scheduler::prepareForInit()
{
- while (!initList.empty())
- ready(initList.getNext());
+ for (Process *p = toFinalize.getNext(); p; p = toFinalize.getNext()) {
+ p->finalize();
+ p->popListNode();
+ }
+
+ for (Process *p = initList.getNext(); p; p = initList.getNext()) {
+ p->finalize();
+ ready(p);
+ }
+
+ initReady = true;
+}
+
+void
+Scheduler::reg(Process *p)
+{
+ if (initReady) {
+ // If we're past initialization, finalize static sensitivity.
+ p->finalize();
+ // Mark the process as ready.
+ ready(p);
+ } else {
+ // Otherwise, record that this process should be initialized once we
+ // get there.
+ initList.pushLast(p);
+ }
+}
+
+void
+Scheduler::dontInitialize(Process *p)
+{
+ if (initReady) {
+ // 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
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index e1ad21a57..aa8ec9aa4 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -30,6 +30,8 @@
#ifndef __SYSTEMC_CORE_SCHEDULER_HH__
#define __SYSTEMC_CORE_SCHEDULER_HH__
+#include <vector>
+
#include "sim/eventq.hh"
#include "systemc/core/channel.hh"
#include "systemc/core/list.hh"
@@ -58,7 +60,7 @@ typedef NodeList<Channel> ChannelList;
* schedules an event to be run at time 0 with a slightly elevated priority
* so that it happens before any "normal" event.
*
- * When that t0 event happens, it calls the schedulers initToReady method
+ * When that t0 event happens, it calls the schedulers prepareForInit method
* which performs step 2 above. That indirectly causes the scheduler's
* readyEvent to be scheduled with slightly lowered priority, ensuring it
* happens after any "normal" event.
@@ -115,11 +117,14 @@ class Scheduler
uint64_t numCycles() { return _numCycles; }
Process *current() { return _current; }
- // Mark processes that need to be initialized as ready.
- void initToReady();
+ // Prepare for initialization.
+ void prepareForInit();
+
+ // Register a process with the scheduler.
+ void reg(Process *p);
- // Put a process on the list of processes to be initialized.
- void init(Process *p) { initList.pushLast(p); }
+ // Tell the scheduler not to initialize a process.
+ void dontInitialize(Process *p);
// Run the next process, if there is one.
void yield();
@@ -162,7 +167,10 @@ class Scheduler
Process *_current;
+ bool initReady;
+
ProcessList initList;
+ ProcessList toFinalize;
ProcessList readyList;
ChannelList updateList;
diff --git a/src/systemc/ext/core/sc_event.hh b/src/systemc/ext/core/sc_event.hh
index d037a84bf..c2154967d 100644
--- a/src/systemc/ext/core/sc_event.hh
+++ b/src/systemc/ext/core/sc_event.hh
@@ -39,6 +39,8 @@ namespace sc_gem5
{
class Event;
+class SensitivityEventAndList;
+class SensitivityEventOrList;
}
@@ -100,6 +102,7 @@ class sc_event_and_list
private:
friend class sc_event_and_expr;
+ friend class sc_gem5::SensitivityEventAndList;
explicit sc_event_and_list(bool auto_delete);
@@ -131,6 +134,7 @@ class sc_event_or_list
private:
friend class sc_event_or_expr;
+ friend class sc_gem5::SensitivityEventOrList;
explicit sc_event_or_list(bool auto_delete);
diff --git a/src/systemc/ext/core/sc_port.hh b/src/systemc/ext/core/sc_port.hh
index 262ca382b..0f5a66189 100644
--- a/src/systemc/ext/core/sc_port.hh
+++ b/src/systemc/ext/core/sc_port.hh
@@ -30,9 +30,19 @@
#ifndef __SYSTEMC_EXT_CORE_SC_PORT_HH__
#define __SYSTEMC_EXT_CORE_SC_PORT_HH__
+#include <vector>
+
#include "sc_module.hh" // for sc_gen_unique_name
#include "sc_object.hh"
+namespace sc_gem5
+{
+
+class BindInfo;
+class PendingSensitivityPort;
+
+};
+
namespace sc_core
{
@@ -48,11 +58,13 @@ enum sc_port_policy
class sc_port_base : public sc_object
{
public:
- sc_port_base(const char *name, int n, sc_port_policy p) : sc_object(name)
- {}
+ sc_port_base(const char *name, int n, sc_port_policy p);
void warn_unimpl(const char *func) const;
+ int maxSize() const;
+ int size() const;
+
protected:
// Implementation defined, but depended on by the tests.
void bind(sc_interface &);
@@ -61,6 +73,12 @@ class sc_port_base : public sc_object
// Implementation defined, but depended on by the tests.
virtual int vbind(sc_interface &) = 0;
virtual int vbind(sc_port_base &) = 0;
+
+ private:
+ friend class ::sc_gem5::PendingSensitivityPort;
+
+ std::vector<::sc_gem5::BindInfo *> _gem5BindInfo;
+ int _maxSize;
};
template <class IF>