systemc: Implement the sensitivity mechanism.
authorGabe Black <gabeblack@google.com>
Mon, 16 Jul 2018 23:14:33 +0000 (16:14 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 5 Sep 2018 06:06:00 +0000 (06:06 +0000)
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>

12 files changed:
src/systemc/core/bindinfo.hh [new file with mode: 0644]
src/systemc/core/event.cc
src/systemc/core/event.hh
src/systemc/core/kernel.cc
src/systemc/core/process.cc
src/systemc/core/process.hh
src/systemc/core/sc_port.cc
src/systemc/core/sc_sensitive.cc
src/systemc/core/scheduler.cc
src/systemc/core/scheduler.hh
src/systemc/ext/core/sc_event.hh
src/systemc/ext/core/sc_port.hh

diff --git a/src/systemc/core/bindinfo.hh b/src/systemc/core/bindinfo.hh
new file mode 100644 (file)
index 0000000..332fb13
--- /dev/null
@@ -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__
index 63fcabe4f3502183aaf799eefafb14a11d5025d9..5008074f640c1096c2c946a30640dd864f19f3c5 100644 (file)
@@ -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
index bf9afd40fbadf2a0767515fb156705db07b2e2ec..a9d318382cf9978c7af0236491ec505fb97afcd4 100644 (file)
 #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;
index e93236541dc7be53beb69c3a4601446da3c7c049..3b75c2fd24a0285b01c9fd29465a1b32fd26ef70 100644 (file)
@@ -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
index 26cfb7ecd1f23534afaa4a35f438ee34e5e5370d..a949c9dee77aeb136c578875e11c517aa02271ce 100644 (file)
  */
 
 #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:
@@ -190,6 +263,23 @@ Process::syncResetOff(bool inc_kids)
     _syncReset = false;
 }
 
+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()
 {
@@ -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;
index bb9a9c60c4f4751d3645346d07cbf9f94a91f9a5..cd92992ebe0a84c6f4c97f94f3e7d5f919f17e17 100644 (file)
 #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__
index 0f981ea547c2f1efe09ba47179924e9ccb5371dd..ad228548fd80f7b3f3af56871c855e96f5cd08c0 100644 (file)
  */
 
 #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 &)
 {
index d233cda6aaf5d68496f0d6870c15ad889b7c268b..25bc1bb085ece9638f2b40bac6db0cb40e35506e 100644 (file)
@@ -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;
 }
 
index 17e7dc43e386b623bf333277ff578bfe9c8cde1f..8ea090f57f387b7912fb97c9e2345e59dbe587fe 100644 (file)
@@ -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
index e1ad21a576edb104221740a1c060fe7ea60d21c9..aa8ec9aa4277868840b483da5547994a067b96a1 100644 (file)
@@ -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;
index d037a84bfd3803a83fcf7d539091ff08710d5626..c2154967d2b7edd0a768c320bb8d2e00c11f2a5a 100644 (file)
@@ -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);
 
index 262ca382b56452aabf699c3693ad59fd77f66135..0f5a661891f5eed7ad3252def2a95d7b8bc6e507 100644 (file)
 #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>