diff options
-rw-r--r-- | src/systemc/core/process.cc | 4 | ||||
-rw-r--r-- | src/systemc/core/sc_module.cc | 12 | ||||
-rw-r--r-- | src/systemc/core/sc_spawn.cc | 95 | ||||
-rw-r--r-- | src/systemc/ext/core/sc_spawn.hh | 64 |
4 files changed, 147 insertions, 28 deletions
diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc index ad297a23c..678cb04db 100644 --- a/src/systemc/core/process.cc +++ b/src/systemc/core/process.cc @@ -338,10 +338,6 @@ Process::Process(const char *name, ProcessFuncWrapper *func, dynamicSensitivity(nullptr) { _newest = this; - if (_dynamic) - finalize(); - else - scheduler.reg(this); } Process *Process::_newest; diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc index 499a741ce..bd0b2e147 100644 --- a/src/systemc/core/sc_module.cc +++ b/src/systemc/core/sc_module.cc @@ -43,19 +43,25 @@ namespace sc_gem5 Process * newMethodProcess(const char *name, ProcessFuncWrapper *func) { - return new Method(name, func); + Process *p = new Method(name, func); + scheduler.reg(p); + return p; } Process * newThreadProcess(const char *name, ProcessFuncWrapper *func) { - return new Thread(name, func); + Process *p = new Thread(name, func); + scheduler.reg(p); + return p; } Process * newCThreadProcess(const char *name, ProcessFuncWrapper *func) { - return new CThread(name, func); + Process *p = new CThread(name, func); + scheduler.reg(p); + return p; } } // namespace sc_gem5 diff --git a/src/systemc/core/sc_spawn.cc b/src/systemc/core/sc_spawn.cc index fd7dc0ad0..ecb0bbc3f 100644 --- a/src/systemc/core/sc_spawn.cc +++ b/src/systemc/core/sc_spawn.cc @@ -28,64 +28,125 @@ */ #include "base/logging.hh" +#include "systemc/core/process.hh" +#include "systemc/core/process_types.hh" +#include "systemc/core/scheduler.hh" +#include "systemc/ext/core/sc_module.hh" #include "systemc/ext/core/sc_spawn.hh" -namespace sc_core +namespace sc_gem5 { -sc_spawn_options::sc_spawn_options() +Process * +spawnWork(ProcessFuncWrapper *func, const char *name, + const ::sc_core::sc_spawn_options *opts) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + bool method = false; + bool dontInitialize = false; + if (opts) { + if (opts->_spawnMethod) + method = true; + if (opts->_dontInitialize) + dontInitialize = true; + if (opts->_stackSize != -1) + warn("Ignoring request to set stack size.\n"); + } + + if (!name || name[0] == '\0') { + if (method) + name = ::sc_core::sc_gen_unique_name("method_p"); + else + name = ::sc_core::sc_gen_unique_name("thread_p"); + } + + Process *proc; + if (method) + proc = new Method(name, func, true); + else + proc = new Thread(name, func, true); + + if (opts) { + for (auto e: opts->_events) + proc->addStatic(new PendingSensitivityEvent(proc, e)); + + for (auto p: opts->_ports) + proc->addStatic(new PendingSensitivityPort(proc, p)); + + for (auto e: opts->_exports) + proc->addStatic(new PendingSensitivityExport(proc, e)); + + for (auto i: opts->_interfaces) + proc->addStatic(new PendingSensitivityInterface(proc, i)); + + for (auto f: opts->_finders) + proc->addStatic(new PendingSensitivityFinder(proc, f)); + } + + scheduler.reg(proc); + + if (dontInitialize) + scheduler.dontInitialize(proc); + + return proc; } +} // namespace sc_gem5 + +namespace sc_core +{ + +sc_spawn_options::sc_spawn_options() : + _spawnMethod(false), _dontInitialize(false), _stackSize(-1) +{} + void sc_spawn_options::spawn_method() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _spawnMethod = true; } void sc_spawn_options::dont_initialize() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _dontInitialize = true; } void -sc_spawn_options::set_stack_size(int) +sc_spawn_options::set_stack_size(int ss) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _stackSize = ss; } void -sc_spawn_options::set_sensitivity(const sc_event *) +sc_spawn_options::set_sensitivity(const sc_event *e) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _events.push_back(e); } void -sc_spawn_options::set_sensitivity(sc_port_base *) +sc_spawn_options::set_sensitivity(sc_port_base *p) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _ports.push_back(p); } void -sc_spawn_options::set_sensitivity(sc_export_base *) +sc_spawn_options::set_sensitivity(sc_export_base *e) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _exports.push_back(e); } void -sc_spawn_options::set_sensitivity(sc_interface *) +sc_spawn_options::set_sensitivity(sc_interface *i) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _interfaces.push_back(i); } void -sc_spawn_options::set_sensitivity(sc_event_finder *) +sc_spawn_options::set_sensitivity(sc_event_finder *f) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _finders.push_back(f); } diff --git a/src/systemc/ext/core/sc_spawn.hh b/src/systemc/ext/core/sc_spawn.hh index 0463dc133..82851542d 100644 --- a/src/systemc/ext/core/sc_spawn.hh +++ b/src/systemc/ext/core/sc_spawn.hh @@ -30,11 +30,51 @@ #ifndef __SYSTEMC_EXT_CORE_SC_SPAWN_HH__ #define __SYSTEMC_EXT_CORE_SC_SPAWN_HH__ +#include <vector> + #include "sc_process_handle.hh" namespace sc_core { +class sc_spawn_options; + +} // namespace sc_core + +namespace sc_gem5 +{ + +class Process; + +template <typename T> +struct ProcessObjFuncWrapper : public ProcessFuncWrapper +{ + T t; + + ProcessObjFuncWrapper(T t) : t(t) {} + + void call() override { t(); } +}; + +template <typename T, typename R> +struct ProcessObjRetFuncWrapper : public ProcessFuncWrapper +{ + T t; + R *r; + + ProcessObjRetFuncWrapper(T t, R *r) : t(t), r(r) {} + + void call() override { *r = t(); } +}; + +Process *spawnWork(ProcessFuncWrapper *func, const char *name, + const ::sc_core::sc_spawn_options *); + +} // namespace sc_gem5 + +namespace sc_core +{ + template <class T> class sc_in; template <class T> @@ -53,6 +93,10 @@ class sc_port_base; class sc_spawn_options { public: + friend ::sc_gem5::Process *::sc_gem5::spawnWork( + ::sc_gem5::ProcessFuncWrapper *, const char *, + const sc_spawn_options *); + sc_spawn_options(); void spawn_method(); @@ -76,6 +120,15 @@ class sc_spawn_options void async_reset_signal_is(const sc_signal_in_if<bool> &, bool); private: + bool _spawnMethod; + bool _dontInitialize; + int _stackSize; + std::vector<const sc_event *> _events; + std::vector<sc_port_base *> _ports; + std::vector<sc_export_base *> _exports; + std::vector<sc_interface *> _interfaces; + std::vector<sc_event_finder *> _finders; + // Disabled sc_spawn_options(const sc_spawn_options &) {} sc_spawn_options &operator = (const sc_spawn_options &) { return *this; } @@ -88,8 +141,9 @@ sc_process_handle sc_spawn(T object, const char *name_p=nullptr, const sc_spawn_options *opt_p=nullptr) { - sc_spawn_warn_unimpl(__PRETTY_FUNCTION__); - return sc_process_handle(); + auto func = new ::sc_gem5::ProcessObjFuncWrapper<T>(object); + ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p); + return sc_process_handle() = p; } template <typename T> @@ -97,8 +151,10 @@ sc_process_handle sc_spawn(typename T::result_type *r_p, T object, const char *name_p=nullptr, const sc_spawn_options *opt_p=nullptr) { - sc_spawn_warn_unimpl(__PRETTY_FUNCTION__); - return sc_process_handle(); + auto func = new ::sc_gem5::ProcessObjRetFuncWrapper< + T, typename T::result_type>(object, r_p); + ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p); + return sc_process_handle() = p; } #define sc_bind boost::bind |