/*
+ * Copyright (c) 2012, 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2000-2005 The Regents of The University of Michigan
* Copyright (c) 2008 The Hewlett-Packard Development Company
* All rights reserved.
#include <Python.h>
+#include "sim/init.hh"
+
#include <marshal.h>
#include <zlib.h>
-#include <csignal>
#include <iostream>
#include <list>
#include <string>
#include "base/cprintf.hh"
#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"
-
-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());
-}
-
-/*
- * 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
- signal(SIGUSR1, dumpStatsHandler);
+#if HAVE_PROTOBUF
+#include <google/protobuf/stubs/common.h>
- // Dump intermediate stats and reset them
- signal(SIGUSR2, dumprstStatsHandler);
+#endif
- // Exit cleanly on Interrupt (Ctrl-C)
- signal(SIGINT, exitNowHandler);
-
- // Print out cycle number on abort
- signal(SIGABRT, abortHandler);
-}
+using namespace std;
+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
EmbeddedPython *EmbeddedPython::importer = NULL;
PyObject *EmbeddedPython::importerModule = NULL;
EmbeddedPython::EmbeddedPython(const char *filename, const char *abspath,
- const char *modpath, const char *code, int zlen, int len)
+ const char *modpath, const unsigned char *code, int zlen, int len)
: filename(filename), abspath(abspath), modpath(modpath), code(code),
zlen(zlen), len(len)
{
}
/*
- * 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();
}
int
m5Main(int argc, char **argv)
{
+#if HAVE_PROTOBUF
+ // Verify that the version of the protobuf library that we linked
+ // against is compatible with the version of the headers we
+ // compiled against.
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+#endif
+
PySys_SetArgv(argc, argv);
// We have to set things up in the special __main__ module
command++;
}
+#if HAVE_PROTOBUF
+ google::protobuf::ShutdownProtobufLibrary();
+#endif
+
return 0;
}