summaryrefslogtreecommitdiff
path: root/src/systemc/core
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-09-10 22:01:47 -0700
committerGabe Black <gabeblack@google.com>2018-10-09 21:45:46 +0000
commit960c3500532a0ca28e4192f838e81eeb7c29860c (patch)
treed69f9fca16de85245c1be592c64f54bc186e958d /src/systemc/core
parentc8d3cb5fadfac8ad90fd81edc707d83051b275da (diff)
downloadgem5-960c3500532a0ca28e4192f838e81eeb7c29860c.tar.xz
systemc: Implement SC_FORK, SC_JOIN, and SC_CJOIN.
SC_CJOIN is non-standard, but relied on by the Accellera tests. Change-Id: Ia4ddcb1749a07891157a58398137e94fcaa8e815 Reviewed-on: https://gem5-review.googlesource.com/c/12615 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/core')
-rw-r--r--src/systemc/core/process.cc5
-rw-r--r--src/systemc/core/process.hh11
-rw-r--r--src/systemc/core/sc_join.cc42
3 files changed, 29 insertions, 29 deletions
diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc
index 553f332d3..1c7a9d72e 100644
--- a/src/systemc/core/process.cc
+++ b/src/systemc/core/process.cc
@@ -32,6 +32,7 @@
#include "base/logging.hh"
#include "systemc/core/event.hh"
#include "systemc/core/scheduler.hh"
+#include "systemc/ext/core/sc_join.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/core/sc_process_handle.hh"
#include "systemc/ext/utils/sc_report_handler.hh"
@@ -419,6 +420,10 @@ Process::terminate()
staticSensitivities.clear();
_terminatedEvent.notify();
+
+ for (auto jw: joinWaiters)
+ jw->signal();
+ joinWaiters.clear();
}
Process *Process::_newest;
diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh
index 4d88e27b8..d399d7a3d 100644
--- a/src/systemc/core/process.hh
+++ b/src/systemc/core/process.hh
@@ -49,6 +49,13 @@
#include "systemc/ext/core/sc_process_handle.hh"
#include "systemc/ext/utils/sc_report.hh"
+namespace sc_core
+{
+
+class sc_join;
+
+} // namespace sc_core
+
namespace sc_gem5
{
@@ -347,6 +354,8 @@ class Process : public ::sc_core::sc_process_b, public ListNode
bool dontInitialize() { return _dontInitialize; }
void dontInitialize(bool di) { _dontInitialize = di; }
+ void joinWait(::sc_core::sc_join *join) { joinWaiters.push_back(join); }
+
protected:
Process(const char *name, ProcessFuncWrapper *func, bool internal=false);
@@ -396,6 +405,8 @@ class Process : public ::sc_core::sc_process_b, public ListNode
Sensitivity *dynamicSensitivity;
std::unique_ptr<::sc_core::sc_report> _lastReport;
+
+ std::vector<::sc_core::sc_join *> joinWaiters;
};
inline void
diff --git a/src/systemc/core/sc_join.cc b/src/systemc/core/sc_join.cc
index 4d531433a..3e4c6eec4 100644
--- a/src/systemc/core/sc_join.cc
+++ b/src/systemc/core/sc_join.cc
@@ -28,45 +28,29 @@
*/
#include "base/logging.hh"
+#include "systemc/core/process.hh"
+#include "systemc/ext/core/sc_event.hh"
#include "systemc/ext/core/sc_join.hh"
+#include "systemc/ext/core/sc_module.hh"
namespace sc_core
{
-sc_join::sc_join()
-{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
+sc_join::sc_join() : remaining(0) {}
void
-sc_join::add_process(sc_process_handle)
-{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
-
-int
-sc_join::process_count()
+sc_join::add_process(sc_process_handle h)
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
- return 0;
-}
+ auto p = (::sc_gem5::Process *)h;
+ assert(p);
-void
-sc_join::signal(sc_thread_handle thread_p, int type)
-{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+ remaining++;
+ p->joinWait(this);
}
-void
-sc_join::wait()
-{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
-
-void
-sc_join::wait_clocked()
-{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
+int sc_join::process_count() { return remaining; }
+void sc_join::signal() { if (!--remaining) joinEvent.notify(); }
+void sc_join::wait() { ::sc_core::wait(joinEvent); }
+void sc_join::wait_clocked() { do { ::sc_core::wait(); } while (remaining); }
} // namespace sc_core