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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user