From: Gabe Black Date: Sat, 21 Jul 2018 02:27:27 +0000 (-0700) Subject: systemc: Implement much of sc_spawn. X-Git-Tag: v19.0.0.0~1826 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1fc84b480c30a7ba43f24854c62fbc6ddadc5fcd;p=gem5.git systemc: Implement much of sc_spawn. This doesn't implement reset signals, although those aren't implemented for static processes either yet. Change-Id: I748a7f75b9b91774c91d969bc1ff5b07e1711aa3 Reviewed-on: https://gem5-review.googlesource.com/12044 Reviewed-by: Gabe Black Maintainer: Gabe Black --- 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 + #include "sc_process_handle.hh" namespace sc_core { +class sc_spawn_options; + +} // namespace sc_core + +namespace sc_gem5 +{ + +class Process; + +template +struct ProcessObjFuncWrapper : public ProcessFuncWrapper +{ + T t; + + ProcessObjFuncWrapper(T t) : t(t) {} + + void call() override { t(); } +}; + +template +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 sc_in; template @@ -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); private: + bool _spawnMethod; + bool _dontInitialize; + int _stackSize; + std::vector _events; + std::vector _ports; + std::vector _exports; + std::vector _interfaces; + std::vector _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(object); + ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p); + return sc_process_handle() = p; } template @@ -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