From d8502ee46d356830698d7b96b29e4b27906a2d79 Mon Sep 17 00:00:00 2001 From: Andrew Bardsley Date: Thu, 16 Oct 2014 05:49:32 -0400 Subject: [PATCH] config: Add a --without-python option to build process Add the ability to build libgem5 without embedded Python or the ability to configure with Python. This is a prelude to a patch to allow config.ini files to be loaded into libgem5 using only C++ which would make embedding gem5 within other simulation systems easier. This adds a few registration interfaces to things which cross between Python and C++. Namely: stats dumping and SimObject resolving --- SConstruct | 80 +++++++++--------- src/SConscript | 27 ++++--- src/base/statistics.cc | 40 +++++++++ src/base/statistics.hh | 19 +++++ src/python/SConscript | 4 +- src/python/m5/stats/__init__.py | 1 + src/python/swig/pyobject.cc | 11 ++- src/python/swig/pyobject.hh | 14 ++-- src/python/swig/stats.i | 21 ++--- src/sim/SConscript | 5 +- src/sim/debug.cc | 18 ----- src/sim/debug.hh | 2 - src/sim/init.cc | 85 -------------------- src/sim/init.hh | 5 -- src/sim/init_signals.cc | 138 ++++++++++++++++++++++++++++++++ src/sim/init_signals.hh | 40 +++++++++ src/sim/main.cc | 1 + src/sim/py_interact.cc | 51 ++++++++++++ src/sim/py_interact.hh | 40 +++++++++ src/sim/serialize.cc | 8 +- src/sim/serialize.hh | 16 +++- src/sim/stat_register.cc | 53 ++++++++++++ src/sim/stat_register.hh | 57 +++++++++++++ 23 files changed, 547 insertions(+), 189 deletions(-) create mode 100644 src/sim/init_signals.cc create mode 100644 src/sim/init_signals.hh create mode 100644 src/sim/py_interact.cc create mode 100644 src/sim/py_interact.hh create mode 100644 src/sim/stat_register.cc create mode 100644 src/sim/stat_register.hh diff --git a/SConstruct b/SConstruct index 1c3d8aa44..034e8e626 100755 --- a/SConstruct +++ b/SConstruct @@ -183,6 +183,9 @@ AddLocalOption('--update-ref', dest='update_ref', action='store_true', help='Update test reference outputs') AddLocalOption('--verbose', dest='verbose', action='store_true', help='Print full tool command lines') +AddLocalOption('--without-python', dest='without_python', + action='store_true', + help='Build without Python configuration support') termcap = get_termcap(GetOption('use_colors')) @@ -884,48 +887,51 @@ if main['M5_BUILD_CACHE']: print 'Using build cache located at', main['M5_BUILD_CACHE'] CacheDir(main['M5_BUILD_CACHE']) -# Find Python include and library directories for embedding the -# interpreter. We rely on python-config to resolve the appropriate -# includes and linker flags. ParseConfig does not seem to understand -# the more exotic linker flags such as -Xlinker and -export-dynamic so -# we add them explicitly below. If you want to link in an alternate -# version of python, see above for instructions on how to invoke -# scons with the appropriate PATH set. -# -# First we check if python2-config exists, else we use python-config -python_config = readCommand(['which', 'python2-config'], exception='').strip() -if not os.path.exists(python_config): - python_config = readCommand(['which', 'python-config'], +if not GetOption('without_python'): + # Find Python include and library directories for embedding the + # interpreter. We rely on python-config to resolve the appropriate + # includes and linker flags. ParseConfig does not seem to understand + # the more exotic linker flags such as -Xlinker and -export-dynamic so + # we add them explicitly below. If you want to link in an alternate + # version of python, see above for instructions on how to invoke + # scons with the appropriate PATH set. + # + # First we check if python2-config exists, else we use python-config + python_config = readCommand(['which', 'python2-config'], exception='').strip() -py_includes = readCommand([python_config, '--includes'], - exception='').split() -# Strip the -I from the include folders before adding them to the -# CPPPATH -main.Append(CPPPATH=map(lambda inc: inc[2:], py_includes)) + if not os.path.exists(python_config): + python_config = readCommand(['which', 'python-config'], + exception='').strip() + py_includes = readCommand([python_config, '--includes'], + exception='').split() + # Strip the -I from the include folders before adding them to the + # CPPPATH + main.Append(CPPPATH=map(lambda inc: inc[2:], py_includes)) -# Read the linker flags and split them into libraries and other link -# flags. The libraries are added later through the call the CheckLib. -py_ld_flags = readCommand([python_config, '--ldflags'], exception='').split() -py_libs = [] -for lib in py_ld_flags: - if not lib.startswith('-l'): - main.Append(LINKFLAGS=[lib]) - else: - lib = lib[2:] - if lib not in py_libs: - py_libs.append(lib) + # Read the linker flags and split them into libraries and other link + # flags. The libraries are added later through the call the CheckLib. + py_ld_flags = readCommand([python_config, '--ldflags'], + exception='').split() + py_libs = [] + for lib in py_ld_flags: + if not lib.startswith('-l'): + main.Append(LINKFLAGS=[lib]) + else: + lib = lib[2:] + if lib not in py_libs: + py_libs.append(lib) -# verify that this stuff works -if not conf.CheckHeader('Python.h', '<>'): - print "Error: can't find Python.h header in", py_includes - print "Install Python headers (package python-dev on Ubuntu and RedHat)" - Exit(1) - -for lib in py_libs: - if not conf.CheckLib(lib): - print "Error: can't find library %s required by python" % lib + # verify that this stuff works + if not conf.CheckHeader('Python.h', '<>'): + print "Error: can't find Python.h header in", py_includes + print "Install Python headers (package python-dev on Ubuntu and RedHat)" Exit(1) + for lib in py_libs: + if not conf.CheckLib(lib): + print "Error: can't find library %s required by python" % lib + Exit(1) + # On Solaris you need to use libsocket for socket ops if not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'): if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): diff --git a/src/SConscript b/src/SConscript index 88fedbfdc..9e3b7fbf6 100755 --- a/src/SConscript +++ b/src/SConscript @@ -63,6 +63,8 @@ from m5.util import code_formatter, compareVersions # false). Current filters are: # main -- specifies the gem5 main() function # skip_lib -- do not put this file into the gem5 library +# skip_no_python -- do not put this file into a no_python library +# as it embeds compiled Python # -- unit tests use filters based on the unit test name # # A parent can now be specified for a source file and default filter @@ -229,7 +231,7 @@ class SwigSource(SourceFile): def __init__(self, package, source, **guards): '''Specify the python package, the source file, and any guards''' - super(SwigSource, self).__init__(source, **guards) + super(SwigSource, self).__init__(source, skip_no_python=True, **guards) modname,ext = self.extname assert ext == 'i' @@ -238,8 +240,8 @@ class SwigSource(SourceFile): cc_file = joinpath(self.dirname, modname + '_wrap.cc') py_file = joinpath(self.dirname, modname + '.py') - self.cc_source = Source(cc_file, swig=True, parent=self) - self.py_source = PySource(package, py_file, parent=self) + self.cc_source = Source(cc_file, swig=True, parent=self, **guards) + self.py_source = PySource(package, py_file, parent=self, **guards) class ProtoBuf(SourceFile): '''Add a Protocol Buffer to build''' @@ -874,9 +876,9 @@ EmbeddedPython embedded_${sym}( code.write(str(target[0])) for source in PySource.all: - env.Command(source.cpp, source.tnode, + env.Command(source.cpp, source.tnode, MakeAction(embedPyFile, Transform("EMBED PY"))) - Source(source.cpp) + Source(source.cpp, skip_no_python=True) ######################################################################## # @@ -973,14 +975,19 @@ def makeEnv(env, label, objsfx, strip = False, **kwargs): return obj - static_objs = \ - [ make_obj(s, True) for s in Source.get(main=False, skip_lib=False) ] - shared_objs = \ - [ make_obj(s, False) for s in Source.get(main=False, skip_lib=False) ] + lib_guards = {'main': False, 'skip_lib': False} + + # Without Python, leave out all SWIG and Python content from the + # library builds. The option doesn't affect gem5 built as a program + if GetOption('without_python'): + lib_guards['skip_no_python'] = False + + static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] + shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] static_date = make_obj(date_source, static=True, extra_deps=static_objs) static_objs.append(static_date) - + shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) shared_objs.append(shared_date) diff --git a/src/base/statistics.cc b/src/base/statistics.cc index 2bd34d3db..5ab837410 100644 --- a/src/base/statistics.cc +++ b/src/base/statistics.cc @@ -462,9 +462,31 @@ Formula::str() const return root ? root->str() : ""; } +Handler resetHandler = NULL; +Handler dumpHandler = NULL; + +void +registerHandlers(Handler reset_handler, Handler dump_handler) +{ + resetHandler = reset_handler; + dumpHandler = dump_handler; +} + CallbackQueue dumpQueue; CallbackQueue resetQueue; +void +processResetQueue() +{ + resetQueue.process(); +} + +void +processDumpQueue() +{ + dumpQueue.process(); +} + void registerResetCallback(Callback *cb) { @@ -488,6 +510,24 @@ enable() _enabled = true; } +void +dump() +{ + if (dumpHandler) + dumpHandler(); + else + fatal("No registered Stats::dump handler"); +} + +void +reset() +{ + if (resetHandler) + resetHandler(); + else + fatal("No registered Stats::reset handler"); +} + void registerDumpCallback(Callback *cb) { diff --git a/src/base/statistics.hh b/src/base/statistics.hh index a6edde2f9..f4b12e847 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -3208,6 +3208,15 @@ void reset(); void enable(); bool enabled(); +/** + * Register reset and dump handlers. These are the functions which + * will actually perform the whole statistics reset/dump actions + * including processing the reset/dump callbacks + */ +typedef void (*Handler)(); + +void registerHandlers(Handler reset_handler, Handler dump_handler); + /** * Register a callback that should be called whenever statistics are * reset @@ -3220,6 +3229,16 @@ void registerResetCallback(Callback *cb); */ void registerDumpCallback(Callback *cb); +/** + * Process all the callbacks in the reset callbacks queue + */ +void processResetQueue(); + +/** + * Process all the callbacks in the dump callbacks queue + */ +void processDumpQueue(); + std::list &statsList(); typedef std::map MapType; diff --git a/src/python/SConscript b/src/python/SConscript index b2c95b88b..7e9380d85 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -31,8 +31,8 @@ Import('*') -Source('swig/pyevent.cc') -Source('swig/pyobject.cc') +Source('swig/pyevent.cc', skip_no_python=True) +Source('swig/pyobject.cc', skip_no_python=True) PySource('', 'importer.py') PySource('m5', 'm5/__init__.py') diff --git a/src/python/m5/stats/__init__.py b/src/python/m5/stats/__init__.py index 770749bf0..763d9b9e3 100644 --- a/src/python/m5/stats/__init__.py +++ b/src/python/m5/stats/__init__.py @@ -41,6 +41,7 @@ def initText(filename, desc=True): def initSimStats(): internal.stats.initSimStats() + internal.stats.registerPythonStatsHandlers() names = [] stats_dict = {} diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc index 51bd1f62f..fed60ba46 100644 --- a/src/python/swig/pyobject.cc +++ b/src/python/swig/pyobject.cc @@ -157,9 +157,12 @@ extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); // these in sim/main.cc as well that are handled without this define. #define PCC(s) const_cast(s) +/** Single instance of PythonSimObjectResolver as its action is effectively + * static but SimObjectResolver can use a non-persistent object */ +PythonSimObjectResolver pythonSimObjectResolver; SimObject * -resolveSimObject(const string &name) +PythonSimObjectResolver::resolveSimObject(const string &name) { PyObject *module = PyImport_ImportModule(PCC("m5.SimObject")); if (module == NULL) @@ -188,3 +191,9 @@ resolveSimObject(const string &name) return obj; } + +Checkpoint * +getCheckpoint(const std::string &cpt_dir) +{ + return new Checkpoint(cpt_dir, pythonSimObjectResolver); +} diff --git a/src/python/swig/pyobject.hh b/src/python/swig/pyobject.hh index 8debcc82c..a4f06555e 100644 --- a/src/python/swig/pyobject.hh +++ b/src/python/swig/pyobject.hh @@ -36,7 +36,12 @@ #include "sim/sim_object.hh" extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); -SimObject *resolveSimObject(const std::string &name); + +/** Resolve a SimObject name using the Python configuration */ +class PythonSimObjectResolver : public SimObjectResolver +{ + SimObject *resolveSimObject(const std::string &name); +}; EtherInt * lookupEthPort(SimObject *so, const std::string &name, int i); @@ -53,11 +58,8 @@ serializeAll(const std::string &cpt_dir) Serializable::serializeAll(cpt_dir); } -inline Checkpoint * -getCheckpoint(const std::string &cpt_dir) -{ - return new Checkpoint(cpt_dir); -} +Checkpoint * +getCheckpoint(const std::string &cpt_dir); inline void unserializeGlobals(Checkpoint *cp) diff --git a/src/python/swig/stats.i b/src/python/swig/stats.i index 3bdd2c9aa..41115445c 100644 --- a/src/python/swig/stats.i +++ b/src/python/swig/stats.i @@ -43,6 +43,7 @@ #include "base/statistics.hh" #include "sim/core.hh" #include "sim/stat_control.hh" +#include "sim/stat_register.hh" namespace Stats { template @@ -64,20 +65,6 @@ Stats_Info_flags_set(Info *info, FlagsType flags) info->flags = flags; } -inline void -processResetQueue() -{ - extern CallbackQueue resetQueue; - resetQueue.process(); -} - -inline void -processDumpQueue() -{ - extern CallbackQueue dumpQueue; - dumpQueue.process(); -} - inline char * PCC(const char *string) { @@ -102,13 +89,13 @@ call_module_function(const char *module_name, const char *func_name) } void -dump() +pythonDump() { call_module_function("m5.stats", "dump"); } void -reset() +pythonReset() { call_module_function("m5.stats", "reset"); } @@ -150,6 +137,8 @@ template T cast_info(Info *info); void initSimStats(); Output *initText(const std::string &filename, bool desc); +void registerPythonStatsHandlers(); + void schedStatEvent(bool dump, bool reset, Tick when = curTick(), Tick repeat = 0); diff --git a/src/sim/SConscript b/src/sim/SConscript index 7d75a9439..7987afa00 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -44,9 +44,11 @@ Source('arguments.cc') Source('async.cc') Source('core.cc') Source('debug.cc') +Source('py_interact.cc', skip_no_python=True) Source('eventq.cc') Source('global_event.cc') -Source('init.cc') +Source('init.cc', skip_no_python=True) +Source('init_signals.cc') Source('main.cc', main=True, skip_lib=True) Source('root.cc') Source('serialize.cc') @@ -57,6 +59,7 @@ Source('sub_system.cc') Source('ticked_object.cc') Source('simulate.cc') Source('stat_control.cc') +Source('stat_register.cc', skip_no_python=True) Source('clock_domain.cc') Source('voltage_domain.cc') Source('system.cc') diff --git a/src/sim/debug.cc b/src/sim/debug.cc index 0dd16a88d..dd504778c 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -29,8 +29,6 @@ * Steve Reinhardt */ -#include - #include #include @@ -108,22 +106,6 @@ eventqDump() } } -void -py_interact() -{ - PyObject *globals; - PyObject *locals; - - globals = PyEval_GetGlobals(); - Py_INCREF(globals); - locals = PyDict_New(); - PyRun_String("import code", Py_file_input, globals, locals); - PyRun_String("code.interact(local=globals())", Py_file_input, - globals, locals); - Py_DECREF(globals); - Py_DECREF(locals); -} - int remote_gdb_base_port = 7000; int diff --git a/src/sim/debug.hh b/src/sim/debug.hh index c29251a1e..fc9f0f55e 100644 --- a/src/sim/debug.hh +++ b/src/sim/debug.hh @@ -53,8 +53,6 @@ void takeCheckpoint(Tick when); */ void eventqDump(); -void py_interact(); - int getRemoteGDBPort(); // Remote gdb base port. 0 disables remote gdb. void setRemoteGDBPort(int port); diff --git a/src/sim/init.cc b/src/sim/init.cc index 042448e41..0a15c384d 100644 --- a/src/sim/init.cc +++ b/src/sim/init.cc @@ -46,7 +46,6 @@ #include #include -#include #include #include #include @@ -65,90 +64,6 @@ 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 tick %d\n", curTick()); -} - -// Handle SIGIO -static void -ioHandler(int sigtype) -{ - async_event = true; - async_io = true; -} - -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); -} - // The python library is totally messed up with respect to constness, // so make a simple macro to make life a little easier #define PyCC(x) (const_cast(x)) diff --git a/src/sim/init.hh b/src/sim/init.hh index 325fc8e6f..766cb4365 100644 --- a/src/sim/init.hh +++ b/src/sim/init.hh @@ -76,11 +76,6 @@ struct EmbeddedSwig static void initAll(); }; -void dumpStatsHandler(int sigtype); -void dumprstStatsHandler(int sigtype); -void exitNowHandler(int sigtype); -void abortHandler(int sigtype); -void initSignals(); int initM5Python(); int m5Main(int argc, char **argv); PyMODINIT_FUNC initm5(void); diff --git a/src/sim/init_signals.cc b/src/sim/init_signals.cc new file mode 100644 index 000000000..705a154e8 --- /dev/null +++ b/src/sim/init_signals.cc @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2012 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. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include +#include +#include + +#include "base/cprintf.hh" +#include "sim/async.hh" +#include "sim/core.hh" +#include "sim/init_signals.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()); +} + +// Handle SIGIO +static void +ioHandler(int sigtype) +{ + async_event = true; + async_io = true; +} + +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); +} + diff --git a/src/sim/init_signals.hh b/src/sim/init_signals.hh new file mode 100644 index 000000000..7285f51ce --- /dev/null +++ b/src/sim/init_signals.hh @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#ifndef __SIM_INIT_SIGNALS_HH__ +#define __SIM_INIT_SIGNALS_HH__ + +void dumpStatsHandler(int sigtype); +void dumprstStatsHandler(int sigtype); +void exitNowHandler(int sigtype); +void abortHandler(int sigtype); +void initSignals(); + +#endif // __SIM_INIT_SIGNALS_HH__ diff --git a/src/sim/main.cc b/src/sim/main.cc index d674e0cff..48b159263 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -31,6 +31,7 @@ #include #include "sim/init.hh" +#include "sim/init_signals.hh" // main() is now pretty stripped down and just sets up python and then // calls initM5Python which loads the various embedded python modules diff --git a/src/sim/py_interact.cc b/src/sim/py_interact.cc new file mode 100644 index 000000000..7e6527e81 --- /dev/null +++ b/src/sim/py_interact.cc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + */ + +#include + +#include "sim/py_interact.hh" + +void +py_interact() +{ + PyObject *globals; + PyObject *locals; + + globals = PyEval_GetGlobals(); + Py_INCREF(globals); + locals = PyDict_New(); + PyRun_String("import code", Py_file_input, globals, locals); + PyRun_String("code.interact(local=globals())", Py_file_input, + globals, locals); + Py_DECREF(globals); + Py_DECREF(locals); +} + diff --git a/src/sim/py_interact.hh b/src/sim/py_interact.hh new file mode 100644 index 000000000..bb27b4ef5 --- /dev/null +++ b/src/sim/py_interact.hh @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#ifndef __SIM_PY_INTERACT_HH__ +#define __SIM_PY_INTERACT_HH__ + +/** @file This file provides py_interact useful for interacting with the + * embedded Python content in a debugger such as gdb. + */ + +void py_interact(); + +#endif // __SIM_PY_INTERACT_HH__ diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 27bf87254..99426b5a6 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -58,8 +58,6 @@ using namespace std; -extern SimObject *resolveSimObject(const string &); - // // The base implementations use to_number for parsing and '<<' for // displaying, suitable for integer types. @@ -600,8 +598,8 @@ Checkpoint::dir() } -Checkpoint::Checkpoint(const string &cpt_dir) - : db(new IniFile), cptDir(setDir(cpt_dir)) +Checkpoint::Checkpoint(const string &cpt_dir, SimObjectResolver &resolver) + : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir)) { string filename = cptDir + "/" + Checkpoint::baseFilename; if (!db->load(filename)) { @@ -630,7 +628,7 @@ Checkpoint::findObj(const string §ion, const string &entry, if (!db->find(section, entry, path)) return false; - value = resolveSimObject(path); + value = objNameResolver.resolveSimObject(path); return true; } diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index d3c9bb40b..18efa2a26 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -255,14 +255,28 @@ class SerializableClass SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ OBJ_CLASS::createForUnserialize); +// Base class to wrap object resolving functionality. This can be +// provided to Checkpoint to allow it to map object names onto +// object C++ objects in which to unserialize +class SimObjectResolver +{ + public: + virtual ~SimObjectResolver() { } + + // Find a SimObject given a full path name + virtual SimObject *resolveSimObject(const std::string &name) = 0; +}; + class Checkpoint { private: IniFile *db; + SimObjectResolver &objNameResolver; + public: - Checkpoint(const std::string &cpt_dir); + Checkpoint(const std::string &cpt_dir, SimObjectResolver &resolver); ~Checkpoint(); const std::string cptDir; diff --git a/src/sim/stat_register.cc b/src/sim/stat_register.cc new file mode 100644 index 000000000..ef7ff8216 --- /dev/null +++ b/src/sim/stat_register.cc @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 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. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Andrew Bardsley + */ + +#include "sim/stat_register.hh" + +namespace Stats +{ + +extern void pythonDump(); +extern void pythonReset(); + +void registerPythonStatsHandlers() +{ + registerHandlers(pythonReset, pythonDump); +} + +} // namespace Stats diff --git a/src/sim/stat_register.hh b/src/sim/stat_register.hh new file mode 100644 index 000000000..7f8c3bcd9 --- /dev/null +++ b/src/sim/stat_register.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 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. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Andrew Bardsley + */ + +/* Provide a mechanism to register the Python stats reset/dump functions + * defined in src/swig/python/stats.i with the mechanisms in namespace + * Stats */ + +#ifndef __SIM_STAT_REGISTER_H__ +#define __SIM_STAT_REGISTER_H__ + +#include "base/statistics.hh" + +namespace Stats +{ + +/** Register py_... functions as the statistics handlers */ +void registerPythonStatsHandlers(); + +} // namespace Stats + +#endif // __SIM_STAT_REGISTER_H__