/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include <Python.h>
+#include "sim/init.hh"
+
#include <marshal.h>
#include <zlib.h>
-#include <csignal>
#include <iostream>
#include <list>
#include <string>
#include "base/misc.hh"
#include "base/types.hh"
#include "config/have_protobuf.hh"
+#include "python/pybind11/pybind.hh"
#include "sim/async.hh"
#include "sim/core.hh"
-#include "sim/init.hh"
#if HAVE_PROTOBUF
#include <google/protobuf/stubs/common.h>
+
#endif
using namespace std;
-
-/// Stats signal handler.
-void
-dumpStatsHandler(int sigtype)
-{
- async_event = true;
- async_statdump = true;
-}
-
-void
-dumprstStatsHandler(int sigtype)
-{
- async_event = true;
- async_statdump = true;
- async_statreset = true;
-}
-
-/// Exit signal handler.
-void
-exitNowHandler(int sigtype)
-{
- async_event = true;
- async_exit = true;
-}
-
-/// Abort signal handler.
-void
-abortHandler(int sigtype)
-{
- ccprintf(cerr, "Program aborted at cycle %d\n", curTick());
-}
-
-// Handle SIGIO
-static void
-ioHandler(int sigtype)
-{
- async_event = true;
- async_io = true;
-}
-
-// Handle SIGALRM
-static void
-alrmHandler(int sigtype)
-{
- async_event = true;
- async_alarm = true;
- alarm(1);
-}
-
-static void
-installSignalHandler(int signal, void (*handler)(int sigtype))
-{
- struct sigaction sa;
-
- memset(&sa, 0, sizeof(sa));
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = handler;
- sa.sa_flags = SA_RESTART;
-
- if (sigaction(signal, &sa, NULL) == -1)
- panic("Failed to setup handler for signal %i\n", signal);
-}
-
-/*
- * M5 can do several special things when various signals are sent.
- * None are mandatory.
- */
-void
-initSignals()
-{
- // Floating point exceptions may happen on misspeculated paths, so
- // ignore them
- signal(SIGFPE, SIG_IGN);
-
- // We use SIGTRAP sometimes for debugging
- signal(SIGTRAP, SIG_IGN);
-
- // Dump intermediate stats
- installSignalHandler(SIGUSR1, dumpStatsHandler);
-
- // Dump intermediate stats and reset them
- installSignalHandler(SIGUSR2, dumprstStatsHandler);
-
- // Exit cleanly on Interrupt (Ctrl-C)
- installSignalHandler(SIGINT, exitNowHandler);
-
- // Print out cycle number on abort
- installSignalHandler(SIGABRT, abortHandler);
-
- // Install a SIGIO handler to handle asynchronous file IO. See the
- // PollQueue class.
- installSignalHandler(SIGIO, ioHandler);
-
- // Setup an alarm handler that triggers every second. This
- // triggers a PollQueue service just like a SIGIO. It is
- // /probably/ used to work around a bug in the poll queue (likely
- // a race between setting up a asynchronous IO and data becoming
- // available), but its use isn't documented anywhere.
- // TODO: Find out why this is needed and fix the original bug.
- installSignalHandler(SIGALRM, alrmHandler);
- alarm(1);
-}
+namespace py = pybind11;
// The python library is totally messed up with respect to constness,
// so make a simple macro to make life a little easier
}
/*
- * Load and initialize all of the python parts of M5, including Swig
- * and the embedded module importer.
+ * Load and initialize all of the python parts of M5.
*/
int
EmbeddedPython::initAll()
return 0;
}
-EmbeddedSwig::EmbeddedSwig(void (*init_func)())
- : initFunc(init_func)
+EmbeddedPyBind::EmbeddedPyBind(const char *_name,
+ void (*init_func)(py::module &),
+ const char *_base)
+ : initFunc(init_func), registered(false), name(_name), base(_base)
{
- getList().push_back(this);
+ getMap()[_name] = this;
}
-list<EmbeddedSwig *> &
-EmbeddedSwig::getList()
+EmbeddedPyBind::EmbeddedPyBind(const char *_name,
+ void (*init_func)(py::module &))
+ : initFunc(init_func), registered(false), name(_name), base("")
{
- static list<EmbeddedSwig *> the_list;
- return the_list;
+ getMap()[_name] = this;
}
void
-EmbeddedSwig::initAll()
+EmbeddedPyBind::init(py::module &m)
{
- // initialize SWIG modules. initSwig() is autogenerated and calls
- // all of the individual swig initialization functions.
- list<EmbeddedSwig *>::iterator i = getList().begin();
- list<EmbeddedSwig *>::iterator end = getList().end();
- for (; i != end; ++i)
- (*i)->initFunc();
+ if (!registered) {
+ initFunc(m);
+ registered = true;
+ } else {
+ cprintf("Warning: %s already registered.\n", name);
+ }
+}
+
+bool
+EmbeddedPyBind::depsReady() const
+{
+ return base.empty() || getMap()[base]->registered;
+}
+
+std::map<std::string, EmbeddedPyBind *> &
+EmbeddedPyBind::getMap()
+{
+ static std::map<std::string, EmbeddedPyBind *> objs;
+ return objs;
+}
+
+void
+EmbeddedPyBind::initAll()
+{
+ std::list<EmbeddedPyBind *> pending;
+
+ py::module m_m5 = py::module("_m5");
+ m_m5.attr("__package__") = py::cast("_m5");
+
+ pybind_init_core(m_m5);
+ pybind_init_debug(m_m5);
+
+ pybind_init_event(m_m5);
+ pybind_init_pyobject(m_m5);
+ pybind_init_stats(m_m5);
+
+ for (auto &kv : getMap()) {
+ auto &obj = kv.second;
+ if (obj->base.empty()) {
+ obj->init(m_m5);
+ } else {
+ pending.push_back(obj);
+ }
+ }
+
+ while (!pending.empty()) {
+ for (auto it = pending.begin(); it != pending.end(); ) {
+ EmbeddedPyBind &obj = **it;
+ if (obj.depsReady()) {
+ obj.init(m_m5);
+ it = pending.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
}
int
initM5Python()
{
- EmbeddedSwig::initAll();
+ EmbeddedPyBind::initAll();
return EmbeddedPython::initAll();
}