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>
This commit is contained in:
Gabe Black
2018-09-10 22:01:47 -07:00
parent c8d3cb5fad
commit 960c350053
5 changed files with 51 additions and 33 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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)
sc_join::add_process(sc_process_handle h)
{
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
auto p = (::sc_gem5::Process *)h;
assert(p);
remaining++;
p->joinWait(this);
}
int
sc_join::process_count()
{
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
return 0;
}
void
sc_join::signal(sc_thread_handle thread_p, int type)
{
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
}
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

View File

@@ -30,6 +30,7 @@
#ifndef __SYSTEMC_EXT_CORE_SC_JOIN_HH__
#define __SYSTEMC_EXT_CORE_SC_JOIN_HH__
#include "sc_event.hh"
#include "sc_process_handle.hh"
namespace sc_core
@@ -43,11 +44,16 @@ class sc_join
{
public:
sc_join();
void add_process(sc_process_handle);
int process_count();
virtual void signal(sc_thread_handle thread_p, int type);
void signal();
void wait();
void wait_clocked();
private:
sc_event joinEvent;
int remaining;
};
} // namespace sc_core

View File

@@ -32,6 +32,7 @@
#include <vector>
#include "sc_join.hh"
#include "sc_process_handle.hh"
namespace sc_core
@@ -166,11 +167,22 @@ sc_spawn(typename T::result_type *r_p, T object, const char *name_p=nullptr,
::sc_core::sc_process_handle forkees[] = {
#define SC_JOIN \
}; /* TODO wait for the forkees. */ \
}; \
::sc_core::sc_join join; \
for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \
join.add_process(forkees[i]); \
join.wait(); \
}
// Non-standard
#define SC_CJOIN SC_JOIN
#define SC_CJOIN \
}; \
::sc_core::sc_join join; \
for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \
join.add_process(forkees[i]); \
join.wait_clocked(); \
}
} // namespace sc_core