Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/12806

Change subject: systemc: Rework how delayed sensitivities are handled.
......................................................................

systemc: Rework how delayed sensitivities are handled.

Make BindInfo into a more general purpose Port class which mirrors
sc_module and Module, sc_object and Object, etc. This tracks multiple
bindings internally, and also pending sensitivities. Keep a global
list of ports which are added in reverse order to match Accellera, and
which is iterated over to finalize binding and for phase callbacks.
This is as opposed to doing it one module at a time, and is to better
match Accellera's ordering for the regressions.

Also the sensitivity classes are now built with factory functions,
which gets around problems calling virtual functions from their
constructors or forgetting to having to have extra boilerplate each
place they're constructed.

The port class also now finalizes port or event finder sensitivities
when its binding is completed, unless it's already complete in which
case it does so immediately.

Change-Id: I1b01689715c425b94e0f68cf0271f5c1565d8c61
---
M src/systemc/core/SConscript
D src/systemc/core/bindinfo.hh
M src/systemc/core/kernel.cc
M src/systemc/core/module.cc
A src/systemc/core/port.cc
A src/systemc/core/port.hh
M src/systemc/core/process.cc
M src/systemc/core/process.hh
M src/systemc/core/sc_module.cc
M src/systemc/core/sc_port.cc
M src/systemc/core/sc_sensitive.cc
M src/systemc/core/sc_spawn.cc
M src/systemc/core/scheduler.cc
M src/systemc/core/sensitivity.cc
M src/systemc/core/sensitivity.hh
M src/systemc/ext/core/sc_port.hh
16 files changed, 484 insertions(+), 283 deletions(-)



diff --git a/src/systemc/core/SConscript b/src/systemc/core/SConscript
index 1d291ef..0aa5994 100644
--- a/src/systemc/core/SConscript
+++ b/src/systemc/core/SConscript
@@ -35,6 +35,7 @@
     Source('kernel.cc')
     Source('module.cc')
     Source('object.cc')
+    Source('port.cc')
     Source('process.cc')
     Source('process_types.cc')
     Source('python.cc')
diff --git a/src/systemc/core/bindinfo.hh b/src/systemc/core/bindinfo.hh
deleted file mode 100644
index 9e636a6..0000000
--- a/src/systemc/core/bindinfo.hh
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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:
-    BindInfo(::sc_core::sc_interface *interface) :
-        interface(interface), port(nullptr)
-    {}
-
-    BindInfo(::sc_core::sc_port_base *port) :
-        interface(nullptr), port(port)
-    {}
-
-    ::sc_core::sc_interface *interface;
-    ::sc_core::sc_port_base *port;
-};
-
-} // namespace sc_gem5
-
-#endif // __SYSTEMC_CORE_BINDINFO_HH__
diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc
index ca99e19..ff8e24e 100644
--- a/src/systemc/core/kernel.cc
+++ b/src/systemc/core/kernel.cc
@@ -32,6 +32,7 @@
 #include "base/logging.hh"
 #include "systemc/core/channel.hh"
 #include "systemc/core/module.hh"
+#include "systemc/core/port.hh"
 #include "systemc/core/scheduler.hh"

 namespace sc_gem5
@@ -75,6 +76,8 @@
         fatal("Simulation called sc_stop during elaboration.\n");

     status(::sc_core::SC_BEFORE_END_OF_ELABORATION);
+    for (auto p: allPorts)
+        p->sc_port_base()->before_end_of_elaboration();
     for (auto m: sc_gem5::allModules)
         m->beforeEndOfElaboration();
     for (auto c: sc_gem5::allChannels)
@@ -88,11 +91,12 @@
         return;

     try {
-        for (auto m: sc_gem5::allModules)
-            for (auto p: m->ports)
-                p->_gem5Finalize();
+        for (auto p: allPorts)
+            p->finalize();

         status(::sc_core::SC_END_OF_ELABORATION);
+        for (auto p: allPorts)
+            p->sc_port_base()->end_of_elaboration();
         for (auto m: sc_gem5::allModules)
             m->endOfElaboration();
         for (auto c: sc_gem5::allChannels)
@@ -117,6 +121,8 @@

     try {
         status(::sc_core::SC_START_OF_SIMULATION);
+        for (auto p: allPorts)
+            p->sc_port_base()->start_of_simulation();
         for (auto m: sc_gem5::allModules)
             m->startOfSimulation();
         for (auto c: sc_gem5::allChannels)
@@ -147,6 +153,8 @@
 {
     status(::sc_core::SC_END_OF_SIMULATION);
     try {
+        for (auto p: allPorts)
+            p->sc_port_base()->end_of_simulation();
         for (auto m: sc_gem5::allModules)
             m->endOfSimulation();
         for (auto c: sc_gem5::allChannels)
diff --git a/src/systemc/core/module.cc b/src/systemc/core/module.cc
index dcd6faa..afc3bf2 100644
--- a/src/systemc/core/module.cc
+++ b/src/systemc/core/module.cc
@@ -113,8 +113,6 @@
 {
     callbackModule(this);
     _sc_mod->before_end_of_elaboration();
-    for (auto p: ports)
-        p->before_end_of_elaboration();
     for (auto e: exports)
         e->before_end_of_elaboration();
     callbackModule(nullptr);
@@ -131,8 +129,6 @@
     }
     callbackModule(this);
     _sc_mod->end_of_elaboration();
-    for (auto p: ports)
-        p->end_of_elaboration();
     for (auto e: exports)
         e->end_of_elaboration();
     callbackModule(nullptr);
@@ -143,8 +139,6 @@
 {
     callbackModule(this);
     _sc_mod->start_of_simulation();
-    for (auto p: ports)
-        p->start_of_simulation();
     for (auto e: exports)
         e->start_of_simulation();
     callbackModule(nullptr);
@@ -155,8 +149,6 @@
 {
     callbackModule(this);
     _sc_mod->end_of_simulation();
-    for (auto p: ports)
-        p->end_of_simulation();
     for (auto e: exports)
         e->end_of_simulation();
     callbackModule(nullptr);
diff --git a/src/systemc/core/port.cc b/src/systemc/core/port.cc
new file mode 100644
index 0000000..af6ecd1
--- /dev/null
+++ b/src/systemc/core/port.cc
@@ -0,0 +1,101 @@
+/*
+ * 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
+ */
+
+#include "systemc/core/port.hh"
+
+#include "systemc/core/sensitivity.hh"
+
+namespace sc_gem5
+{
+
+void
+Port::finalizePort(StaticSensitivityPort *port)
+{
+    for (int i = 0; i < size(); i++)
+        port->addEvent(&getInterface(i)->default_event());
+}
+
+void
+Port::finalizeFinder(StaticSensitivityFinder *finder)
+{
+    for (int i = 0; i < size(); i++)
+        finder->addEvent(&finder->find(getInterface(i)));
+}
+
+void
+Port::sensitive(StaticSensitivityPort *port)
+{
+    if (finalized)
+        finalizePort(port);
+    else
+        sensitivities.push_back(new Sensitivity(port));
+}
+
+void
+Port::sensitive(StaticSensitivityFinder *finder)
+{
+    if (finalized)
+        finalizeFinder(finder);
+    else
+        sensitivities.push_back(new Sensitivity(finder));
+}
+
+void
+Port::finalize()
+{
+    if (finalized)
+        return;
+    finalized = true;
+
+    for (auto &b: bindings) {
+        if (b->interface) {
+            addInterface(b->interface);
+        } else {
+            b->port->_gem5Port->finalize();
+            addInterfaces(b->port);
+        }
+        delete b;
+    }
+
+    bindings.clear();
+
+    for (auto &s: sensitivities) {
+        if (s->port)
+            finalizePort(s->port);
+        else
+            finalizeFinder(s->finder);
+        delete s;
+    }
+
+    sensitivities.clear();
+}
+
+std::list<Port *> allPorts;
+
+} // namespace sc_gem5
diff --git a/src/systemc/core/port.hh b/src/systemc/core/port.hh
new file mode 100644
index 0000000..15e7bbe
--- /dev/null
+++ b/src/systemc/core/port.hh
@@ -0,0 +1,150 @@
+/*
+ * 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_PORT_HH__
+#define __SYSTEMC_CORE_PORT_HH__
+
+#include <list>
+#include <vector>
+
+#include "systemc/ext/core/sc_interface.hh"
+#include "systemc/ext/core/sc_port.hh"
+
+namespace sc_gem5
+{
+
+class StaticSensitivityPort;
+class StaticSensitivityFinder;
+
+class Port;
+
+extern std::list<Port *> allPorts;
+
+class Port
+{
+  private:
+    ::sc_core::sc_port_base *portBase;
+
+    bool finalized;
+    int _maxSize;
+    int _size;
+
+    void finalizePort(StaticSensitivityPort *port);
+    void finalizeFinder(StaticSensitivityFinder *finder);
+
+    void
+    addInterface(::sc_core::sc_interface *i)
+    {
+        _size++;
+        portBase->_gem5AddInterface(i);
+    }
+
+    void
+    addInterfaces(::sc_core::sc_port_base *pb)
+    {
+        for (int i = 0; i < pb->size(); i++)
+            addInterface(pb->_gem5Interface(i));
+    }
+
+    ::sc_core::sc_interface *
+    getInterface(int i)
+    {
+        return portBase->_gem5Interface(i);
+    }
+
+    struct Binding
+    {
+        explicit Binding(::sc_core::sc_interface *interface) :
+            interface(interface), port(nullptr)
+        {}
+
+        explicit Binding(::sc_core::sc_port_base *port) :
+            interface(nullptr), port(port)
+        {}
+
+        ::sc_core::sc_interface *interface;
+        ::sc_core::sc_port_base *port;
+    };
+
+    struct Sensitivity
+    {
+        Sensitivity(StaticSensitivityPort *port) :
+            port(port), finder(nullptr)
+        {}
+
+        Sensitivity(StaticSensitivityFinder *finder) :
+            port(nullptr), finder(finder)
+        {}
+
+        StaticSensitivityPort *port;
+        StaticSensitivityFinder *finder;
+    };
+
+    std::vector<Binding *> bindings;
+    std::vector<Sensitivity *> sensitivities;
+
+  public:
+    static Port *
+    fromPort(const ::sc_core::sc_port_base *pb)
+    {
+        return pb->_gem5Port;
+    }
+
+    ::sc_core::sc_port_base *sc_port_base() { return portBase; }
+
+    Port(::sc_core::sc_port_base *port_base, int max) :
+        portBase(port_base), finalized(false), _maxSize(max), _size(0)
+    {
+        allPorts.push_front(this);
+    }
+
+    void
+    bind(::sc_core::sc_interface *interface)
+    {
+        bindings.push_back(new Binding(interface));
+    }
+
+    void
+    bind(::sc_core::sc_port_base *port)
+    {
+        bindings.push_back(new Binding(port));
+    }
+
+    void sensitive(StaticSensitivityPort *port);
+    void sensitive(StaticSensitivityFinder *finder);
+
+    void finalize();
+
+    int size() { return _size; }
+    int maxSize() { return _maxSize; }
+};
+
+} // namespace sc_gem5
+
+#endif // __SYSTEMC_CORE_PORT_HH__
diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc
index e977713..45c01e9 100644
--- a/src/systemc/core/process.cc
+++ b/src/systemc/core/process.cc
@@ -236,13 +236,6 @@
 }

 void
-Process::finalize()
-{
-    for (auto s: staticSensitivities)
-        s->finalize();
-};
-
-void
 Process::run()
 {
     bool reset;
@@ -276,8 +269,6 @@
         delete dynamicSensitivity;
     }
     dynamicSensitivity = s;
-    if (dynamicSensitivity)
-        dynamicSensitivity->finalize();
 }

 void
diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh
index 0a312e2..4266c2d 100644
--- a/src/systemc/core/process.hh
+++ b/src/systemc/core/process.hh
@@ -35,7 +35,6 @@
 #include <vector>

 #include "base/fiber.hh"
-#include "systemc/core/bindinfo.hh"
 #include "systemc/core/list.hh"
 #include "systemc/core/object.hh"
 #include "systemc/core/sched_event.hh"
@@ -96,8 +95,6 @@

     void setStackSize(size_t size) { stackSize = size; }

-    void finalize();
-
     void run();

     void addStatic(StaticSensitivity *);
diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc
index 3e900f6..32d1c97 100644
--- a/src/systemc/core/sc_module.cc
+++ b/src/systemc/core/sc_module.cc
@@ -505,7 +505,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->cancelTimeout();
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
 }

 void
@@ -513,7 +513,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->cancelTimeout();
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
 }

 void
@@ -521,7 +521,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->cancelTimeout();
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
 }

 void
@@ -543,7 +543,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->setTimeout(t);
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
 }

 void
@@ -557,7 +557,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->setTimeout(t);
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
 }

 void
@@ -571,7 +571,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->setTimeout(t);
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
 }

 void
@@ -616,7 +616,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->cancelTimeout();
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
     sc_gem5::scheduler.yield();
 }

@@ -625,7 +625,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->cancelTimeout();
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
     sc_gem5::scheduler.yield();
 }

@@ -634,7 +634,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->cancelTimeout();
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
     sc_gem5::scheduler.yield();
 }

@@ -658,7 +658,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->setTimeout(t);
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+    ::sc_gem5::newDynamicSensitivityEvent(p, &e);
     sc_gem5::scheduler.yield();
 }

@@ -673,7 +673,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->setTimeout(t);
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+    ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
     sc_gem5::scheduler.yield();
 }

@@ -688,7 +688,7 @@
 {
     sc_gem5::Process *p = sc_gem5::scheduler.current();
     p->setTimeout(t);
-    p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+    ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
     sc_gem5::scheduler.yield();
 }

diff --git a/src/systemc/core/sc_port.cc b/src/systemc/core/sc_port.cc
index c822e96..52f66b7 100644
--- a/src/systemc/core/sc_port.cc
+++ b/src/systemc/core/sc_port.cc
@@ -28,8 +28,8 @@
  */

 #include "base/logging.hh"
-#include "systemc/core/bindinfo.hh"
 #include "systemc/core/module.hh"
+#include "systemc/core/port.hh"
 #include "systemc/core/scheduler.hh"
 #include "systemc/ext/core/sc_main.hh"
 #include "systemc/ext/core/sc_port.hh"
@@ -56,7 +56,7 @@
 }

 sc_port_base::sc_port_base(const char *name, int n, sc_port_policy p) :
-    sc_object(name), _maxSize(n), _size(0), finalized(false)
+    sc_object(name), _gem5Port(new ::sc_gem5::Port(this, n))
 {
     if (sc_is_running()) {
         reportError("(E110) insert port failed", "simulation running",
@@ -76,51 +76,21 @@
     }
 }

+sc_port_base::~sc_port_base()
+{
+    delete _gem5Port;
+}
+
 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 _size; }
+int sc_port_base::maxSize() const { return _gem5Port->maxSize(); }
+int sc_port_base::size() const { return _gem5Port->size(); }

-void
-sc_port_base::bind(sc_interface &i)
-{
-    _gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&i));
-}
-
-void
-sc_port_base::bind(sc_port_base &p)
-{
-    _gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&p));
-}
-
-void
-sc_port_base::_gem5Finalize()
-{
-    if (finalized)
-        return;
-    finalized = true;
-
-    for (auto &bi: _gem5BindInfo) {
-        if (bi->interface) {
-            _size++;
-            _gem5AddInterface(bi->interface);
-        } else {
-            sc_port_base *port = bi->port;
-            port->_gem5Finalize();
-            int size = port->size();
-            for (int i = 0; i < size; i++) {
-                _size++;
-                _gem5AddInterface(port->_gem5Interface(i));
-            }
-        }
-        delete bi;
-    }
-
-    _gem5BindInfo.clear();
-}
+void sc_port_base::bind(sc_interface &i) { _gem5Port->bind(&i); }
+void sc_port_base::bind(sc_port_base &p) { _gem5Port->bind(&p); }

 } // namespace sc_core
diff --git a/src/systemc/core/sc_sensitive.cc b/src/systemc/core/sc_sensitive.cc
index 93b460a..b254f68 100644
--- a/src/systemc/core/sc_sensitive.cc
+++ b/src/systemc/core/sc_sensitive.cc
@@ -40,32 +40,28 @@
 sc_sensitive &
 sc_sensitive::operator << (const sc_event &e)
 {
-    currentProcess->addStatic(
-            new sc_gem5::StaticSensitivityEvent(currentProcess, &e));
+    sc_gem5::newStaticSensitivityEvent(currentProcess, &e);
     return *this;
 }

 sc_sensitive &
 sc_sensitive::operator << (const sc_interface &i)
 {
-    currentProcess->addStatic(
-            new sc_gem5::StaticSensitivityInterface(currentProcess, &i));
+    sc_gem5::newStaticSensitivityInterface(currentProcess, &i);
     return *this;
 }

 sc_sensitive &
 sc_sensitive::operator << (const sc_port_base &b)
 {
-    currentProcess->addStatic(
-            new sc_gem5::StaticSensitivityPort(currentProcess, &b));
+    sc_gem5::newStaticSensitivityPort(currentProcess, &b);
     return *this;
 }

 sc_sensitive &
 sc_sensitive::operator << (sc_event_finder &f)
 {
-    currentProcess->addStatic(
-            new sc_gem5::StaticSensitivityFinder(currentProcess, &f));
+    sc_gem5::newStaticSensitivityFinder(currentProcess, &f);
     return *this;
 }

diff --git a/src/systemc/core/sc_spawn.cc b/src/systemc/core/sc_spawn.cc
index 9a6ec39..d2e6bd4 100644
--- a/src/systemc/core/sc_spawn.cc
+++ b/src/systemc/core/sc_spawn.cc
@@ -70,19 +70,19 @@

     if (opts) {
         for (auto e: opts->_events)
-            proc->addStatic(new StaticSensitivityEvent(proc, e));
+            newStaticSensitivityEvent(proc, e);

         for (auto p: opts->_ports)
-            proc->addStatic(new StaticSensitivityPort(proc, p));
+            newStaticSensitivityPort(proc, p);

         for (auto e: opts->_exports)
-            proc->addStatic(new StaticSensitivityExport(proc, e));
+            newStaticSensitivityExport(proc, e);

         for (auto i: opts->_interfaces)
-            proc->addStatic(new StaticSensitivityInterface(proc, i));
+            newStaticSensitivityInterface(proc, i);

         for (auto f: opts->_finders)
-            proc->addStatic(new StaticSensitivityFinder(proc, f));
+            newStaticSensitivityFinder(proc, f);
     }

     if (opts && opts->_dontInitialize &&
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index a0695a3..8a796bb 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -104,7 +104,6 @@
 Scheduler::initPhase()
 {
     for (Process *p = initList.getNext(); p; p = initList.getNext()) {
-        p->finalize();
         p->popListNode();

         if (p->dontInitialize()) {
@@ -141,8 +140,6 @@
 Scheduler::reg(Process *p)
 {
     if (initDone) {
-        // If we're past initialization, finalize static sensitivity.
-        p->finalize();
         // If not marked as dontInitialize, mark as ready.
         if (!p->dontInitialize())
             p->ready();
diff --git a/src/systemc/core/sensitivity.cc b/src/systemc/core/sensitivity.cc
index 77aacb5..740090c 100644
--- a/src/systemc/core/sensitivity.cc
+++ b/src/systemc/core/sensitivity.cc
@@ -30,6 +30,7 @@
 #include "systemc/core/sensitivity.hh"

 #include "systemc/core/event.hh"
+#include "systemc/core/port.hh"
 #include "systemc/core/scheduler.hh"
 #include "systemc/ext/core/sc_export.hh"
 #include "systemc/ext/core/sc_interface.hh"
@@ -38,6 +39,10 @@
 namespace sc_gem5
 {

+/*
+ * Common sensitivity interface.
+ */
+
 void
 Sensitivity::satisfy()
 {
@@ -53,6 +58,10 @@
 }


+/*
+ * Dynamic vs. static sensitivity.
+ */
+
 void
 DynamicSensitivity::addToEvent(const ::sc_core::sc_event *e)
 {
@@ -77,44 +86,110 @@
     Event::getFromScEvent(e)->delSensitivity(this);
 }

+
+/*
+ * Static sensitivities.
+ */
+
 void
-StaticSensitivityInterface::finalize()
+newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e)
 {
-    event = &interface->default_event();
-    SensitivityEvent::finalize();
+    auto s = new StaticSensitivityEvent(p, e);
+    s->addToEvent(s->event);
+    p->addStatic(s);
 }

 void
-StaticSensitivityPort::finalize()
+newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i)
 {
-    for (int i = 0; i < port->size(); i++) {
-        const ::sc_core::sc_event *event =
-            &port->_gem5Interface(i)->default_event();
-        events.insert(event);
-        addToEvent(event);
-    }
+    auto s = new StaticSensitivityInterface(p, i);
+    s->addToEvent(s->event);
+    p->addStatic(s);
 }

 void
-StaticSensitivityExport::finalize()
+newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb)
 {
-    event = &exp->get_interface()->default_event();
-    SensitivityEvent::finalize();
+    auto s = new StaticSensitivityPort(p);
+    Port *port = Port::fromPort(pb);
+    port->sensitive(s);
+    p->addStatic(s);
 }

 void
-StaticSensitivityFinder::finalize()
+newStaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp)
 {
-    const ::sc_core::sc_port_base *port = finder->port();
-    int size = port->size();
-    for (int i = 0; i < size; i++) {
-        ::sc_core::sc_interface *interface = port->_gem5Interface(i);
-        const ::sc_core::sc_event *event = &finder->find_event(interface);
-        events.insert(event);
-        addToEvent(event);
-    }
+    auto s = new StaticSensitivityExport(p, exp);
+    s->addToEvent(s->event);
+    p->addStatic(s);
 }

+void
+newStaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f)
+{
+    auto s = new StaticSensitivityFinder(p, f);
+    Port *port = Port::fromPort(f->port());
+    port->sensitive(s);
+    p->addStatic(s);
+}
+
+
+StaticSensitivityInterface::StaticSensitivityInterface(
+        Process *p, const sc_core::sc_interface *i) :
+    Sensitivity(p), StaticSensitivity(p),
+    SensitivityEvent(p, &i->default_event())
+{}
+
+StaticSensitivityExport::StaticSensitivityExport(
+        Process *p, const sc_core::sc_export_base *exp) :
+    Sensitivity(p), StaticSensitivity(p),
+    SensitivityEvent(p, &exp->get_interface()->default_event())
+{}
+
+const ::sc_core::sc_event &
+StaticSensitivityFinder::find(::sc_core::sc_interface *i)
+{
+    return finder->find_event(i);
+}
+
+
+/*
+ * Dynamic sensitivities.
+ */
+
+void
+newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e)
+{
+    auto s = new DynamicSensitivityEvent(p, e);
+    s->addToEvent(s->event);
+    p->setDynamic(s);
+}
+
+void
+newDynamicSensitivityEventOrList(
+        Process *p, const sc_core::sc_event_or_list *eol)
+{
+    auto s = new DynamicSensitivityEventOrList(p, eol);
+    for (auto event: s->events)
+        s->addToEvent(event);
+    p->setDynamic(s);
+}
+
+void newDynamicSensitivityEventAndList(
+        Process *p, const sc_core::sc_event_and_list *eal)
+{
+    auto s = new DynamicSensitivityEventAndList(p, eal);
+    for (auto event: s->events)
+        s->addToEvent(event);
+    p->setDynamic(s);
+}
+
+
+DynamicSensitivityEventOrList::DynamicSensitivityEventOrList(
+        Process *p, const sc_core::sc_event_or_list *eol) :
+ Sensitivity(p), DynamicSensitivity(p), SensitivityEvents(p, eol->events)
+{}
+
 bool
 DynamicSensitivityEventOrList::notifyWork(Event *e)
 {
@@ -129,25 +204,11 @@
     return true;
 }

-DynamicSensitivityEventOrList::DynamicSensitivityEventOrList(
-        Process *p, const sc_core::sc_event_or_list *eol) :
-    Sensitivity(p), DynamicSensitivity(p), events(eol->events)
+DynamicSensitivityEventAndList::DynamicSensitivityEventAndList(
+        Process *p, const sc_core::sc_event_and_list *eal) :
+ Sensitivity(p), DynamicSensitivity(p), SensitivityEvents(p, eal->events)
 {}

-void
-DynamicSensitivityEventOrList::finalize()
-{
-    for (auto e: events)
-        addToEvent(e);
-}
-
-void
-DynamicSensitivityEventOrList::clear()
-{
-    for (auto e: events)
-        delFromEvent(e);
-}
-
 bool
 DynamicSensitivityEventAndList::notifyWork(Event *e)
 {
@@ -160,23 +221,4 @@
     return true;
 }

-DynamicSensitivityEventAndList::DynamicSensitivityEventAndList(
-        Process *p, const sc_core::sc_event_and_list *eal) :
-    Sensitivity(p), DynamicSensitivity(p), events(eal->events)
-{}
-
-void
-DynamicSensitivityEventAndList::finalize()
-{
-    for (auto e: events)
-        addToEvent(e);
-}
-
-void
-DynamicSensitivityEventAndList::clear()
-{
-    for (auto e: events)
-        delFromEvent(e);
-}
-
 } // namespace sc_gem5
diff --git a/src/systemc/core/sensitivity.hh b/src/systemc/core/sensitivity.hh
index f032630..b3f9a2e 100644
--- a/src/systemc/core/sensitivity.hh
+++ b/src/systemc/core/sensitivity.hh
@@ -79,7 +79,6 @@
     }

   public:
-    virtual void finalize() = 0;
     virtual void clear() = 0;

     void satisfy();
@@ -124,7 +123,7 @@


 /*
- * Sensitivity to events, which can be static or dynamic.
+ * Sensitivity to an event or events, which can be static or dynamic.
  */

 class SensitivityEvent : virtual public Sensitivity
@@ -137,19 +136,57 @@
     {}

   public:
-    void finalize() override { addToEvent(event); }
     void clear() override { delFromEvent(event); }
 };

+class SensitivityEvents : virtual public Sensitivity
+{
+  protected:
+    std::set<const ::sc_core::sc_event *> events;
+
+    SensitivityEvents(Process *p) : Sensitivity(p) {}
+    SensitivityEvents(
+            Process *p, const std::set<const ::sc_core::sc_event *> &s) :
+        Sensitivity(p), events(s)
+    {}
+
+  public:
+    void
+    clear() override
+    {
+        for (auto event: events)
+            delFromEvent(event);
+    }
+
+    void
+    addEvent(const ::sc_core::sc_event *event)
+    {
+        events.insert(event);
+        addToEvent(event);
+    }
+};
+

 /*
  * Static sensitivities.
  */

+void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e);
+void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
+void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb);
+void newStaticSensitivityExport(
+        Process *p, const sc_core::sc_export_base *exp);
+void newStaticSensitivityFinder(
+        Process *p, const sc_core::sc_event_finder *f);
+
+
 class StaticSensitivityEvent :
     public StaticSensitivity, public SensitivityEvent
 {
-  public:
+    friend void newStaticSensitivityEvent(
+            Process *p, const sc_core::sc_event *e);
+
+  protected:
     StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) :
         Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e)
     {}
@@ -158,71 +195,50 @@
 class StaticSensitivityInterface :
     public StaticSensitivity, public SensitivityEvent
 {
-  private:
-    const sc_core::sc_interface *interface;
-
-  public:
- StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i) : - Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p), interface(i)
-    {}
-
-    void finalize() override;
+    friend void newStaticSensitivityInterface(
+            Process *p, const sc_core::sc_interface *i);
+  protected:
+    StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
 };

-class StaticSensitivityPort : public StaticSensitivity
+class StaticSensitivityPort :
+    public StaticSensitivity, public SensitivityEvents
 {
-  private:
-    const ::sc_core::sc_port_base *port;
-    std::set<const ::sc_core::sc_event *> events;
+    friend void newStaticSensitivityPort(
+            Process *p, const sc_core::sc_port_base *pb);

-  public:
-    StaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb) :
-        Sensitivity(p), StaticSensitivity(p), port(pb)
+  protected:
+    StaticSensitivityPort(Process *p) :
+        Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p)
     {}
-
-    void finalize() override;
-
-    void
-    clear() override
-    {
-        for (auto event: events)
-            delFromEvent(event);
-    }
 };

 class StaticSensitivityExport :
     public StaticSensitivity, public SensitivityEvent
 {
   private:
-    const sc_core::sc_export_base *exp;
+    friend void newStaticSensitivityExport(
+            Process *p, const sc_core::sc_export_base *exp);

-  public:
- StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp) :
-        Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p), exp(exp)
-    {}
-
-    void finalize() override;
+ StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp);
 };

-class StaticSensitivityFinder : public StaticSensitivity
+
+class StaticSensitivityFinder :
+    public StaticSensitivity, public SensitivityEvents
 {
   private:
-    const ::sc_core::sc_event_finder *finder;
-    std::set<const ::sc_core::sc_event *> events;
+    const sc_core::sc_event_finder *finder;

-  public:
+    friend void newStaticSensitivityFinder(
+            Process *p, const sc_core::sc_event_finder *f);
+
StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
-        Sensitivity(p), StaticSensitivity(p), finder(f)
+ Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f)
     {}

-    void finalize() override;
-
-    void
-    clear() override
-    {
-        for (auto event: events)
-            delFromEvent(event);
-    }
+  public:
+    const ::sc_core::sc_event &find(::sc_core::sc_interface *i);
 };


@@ -230,48 +246,51 @@
  * Dynamic sensitivities.
  */

+void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e);
+void newDynamicSensitivityEventOrList(
+        Process *p, const sc_core::sc_event_or_list *eol);
+void newDynamicSensitivityEventAndList(
+        Process *p, const sc_core::sc_event_and_list *eal);
+
 class DynamicSensitivityEvent :
     public DynamicSensitivity, public SensitivityEvent
 {
-  public:
+  private:
+    friend void newDynamicSensitivityEvent(
+            Process *p, const sc_core::sc_event *e);
+
     DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) :
         Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e)
     {}
 };

-class DynamicSensitivityEventOrList : public DynamicSensitivity
+class DynamicSensitivityEventOrList :
+    public DynamicSensitivity, public SensitivityEvents
 {
   private:
-    std::set<const ::sc_core::sc_event *> events;
+    friend void newDynamicSensitivityEventOrList(
+            Process *p, const sc_core::sc_event_or_list *eol);

-  protected:
-    bool notifyWork(Event *e) override;
-
-  public:
     DynamicSensitivityEventOrList(
             Process *p, const sc_core::sc_event_or_list *eol);

-    void finalize() override;
-    void clear() override;
+    bool notifyWork(Event *e) override;
 };

//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 DynamicSensitivityEventAndList : public DynamicSensitivity
+class DynamicSensitivityEventAndList :
+    public DynamicSensitivity, public SensitivityEvents
 {
   private:
-    std::set<const ::sc_core::sc_event *> events;
+    friend void newDynamicSensitivityEventAndList(
+            Process *p, const sc_core::sc_event_and_list *eal);

-  protected:
-    bool notifyWork(Event *e) override;
-
-  public:
     DynamicSensitivityEventAndList(
             Process *p, const sc_core::sc_event_and_list *eal);

-    void finalize() override;
-    void clear() override;
+    bool notifyWork(Event *e) override;
 };

 } // namespace sc_gem5
diff --git a/src/systemc/ext/core/sc_port.hh b/src/systemc/ext/core/sc_port.hh
index de26f5a..c9d436e 100644
--- a/src/systemc/ext/core/sc_port.hh
+++ b/src/systemc/ext/core/sc_port.hh
@@ -39,10 +39,7 @@
 namespace sc_gem5
 {

-class BindInfo;
-class Module;
-class StaticSensitivityPort;
-class StaticSensitivityFinder;
+class Port;

 };

@@ -62,6 +59,7 @@
 {
   public:
     sc_port_base(const char *name, int n, sc_port_policy p);
+    virtual ~sc_port_base();

     void warn_unimpl(const char *func) const;

@@ -87,19 +85,13 @@
     virtual void end_of_simulation() = 0;

   private:
-    friend class ::sc_gem5::StaticSensitivityPort;
-    friend class ::sc_gem5::StaticSensitivityFinder;
+    friend class ::sc_gem5::Port;
     friend class ::sc_gem5::Kernel;

-    void _gem5Finalize();
-
     virtual sc_interface *_gem5Interface(int n) const = 0;
     virtual void _gem5AddInterface(sc_interface *i) = 0;

-    std::vector<::sc_gem5::BindInfo *> _gem5BindInfo;
-    int _maxSize;
-    int _size;
-    bool finalized;
+    ::sc_gem5::Port *_gem5Port;
 };

 template <class IF>

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/12806
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I1b01689715c425b94e0f68cf0271f5c1565d8c61
Gerrit-Change-Number: 12806
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabebl...@google.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to