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 <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_gem5
|
||||
{
|
||||
|
||||
Process *
|
||||
spawnWork(ProcessFuncWrapper *func, const char *name,
|
||||
const ::sc_core::sc_spawn_options *opts)
|
||||
{
|
||||
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()
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user