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
This commit is contained in:
Andrew Bardsley 2014-10-16 05:49:32 -04:00
parent a63ba6c7b7
commit d8502ee46d
23 changed files with 547 additions and 189 deletions

View file

@ -183,6 +183,9 @@ AddLocalOption('--update-ref', dest='update_ref', action='store_true',
help='Update test reference outputs') help='Update test reference outputs')
AddLocalOption('--verbose', dest='verbose', action='store_true', AddLocalOption('--verbose', dest='verbose', action='store_true',
help='Print full tool command lines') 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')) 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'] print 'Using build cache located at', main['M5_BUILD_CACHE']
CacheDir(main['M5_BUILD_CACHE']) CacheDir(main['M5_BUILD_CACHE'])
# Find Python include and library directories for embedding the if not GetOption('without_python'):
# interpreter. We rely on python-config to resolve the appropriate # Find Python include and library directories for embedding the
# includes and linker flags. ParseConfig does not seem to understand # interpreter. We rely on python-config to resolve the appropriate
# the more exotic linker flags such as -Xlinker and -export-dynamic so # includes and linker flags. ParseConfig does not seem to understand
# we add them explicitly below. If you want to link in an alternate # the more exotic linker flags such as -Xlinker and -export-dynamic so
# version of python, see above for instructions on how to invoke # we add them explicitly below. If you want to link in an alternate
# scons with the appropriate PATH set. # 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() # First we check if python2-config exists, else we use python-config
if not os.path.exists(python_config): python_config = readCommand(['which', 'python2-config'],
python_config = readCommand(['which', 'python-config'],
exception='').strip() exception='').strip()
py_includes = readCommand([python_config, '--includes'], if not os.path.exists(python_config):
exception='').split() python_config = readCommand(['which', 'python-config'],
# Strip the -I from the include folders before adding them to the exception='').strip()
# CPPPATH py_includes = readCommand([python_config, '--includes'],
main.Append(CPPPATH=map(lambda inc: inc[2:], py_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 # Read the linker flags and split them into libraries and other link
# flags. The libraries are added later through the call the CheckLib. # flags. The libraries are added later through the call the CheckLib.
py_ld_flags = readCommand([python_config, '--ldflags'], exception='').split() py_ld_flags = readCommand([python_config, '--ldflags'],
py_libs = [] exception='').split()
for lib in py_ld_flags: py_libs = []
if not lib.startswith('-l'): for lib in py_ld_flags:
main.Append(LINKFLAGS=[lib]) if not lib.startswith('-l'):
else: main.Append(LINKFLAGS=[lib])
lib = lib[2:] else:
if lib not in py_libs: lib = lib[2:]
py_libs.append(lib) if lib not in py_libs:
py_libs.append(lib)
# verify that this stuff works # verify that this stuff works
if not conf.CheckHeader('Python.h', '<>'): if not conf.CheckHeader('Python.h', '<>'):
print "Error: can't find Python.h header in", py_includes print "Error: can't find Python.h header in", py_includes
print "Install Python headers (package python-dev on Ubuntu and RedHat)" 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) 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 # 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(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'):
if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'):

View file

@ -63,6 +63,8 @@ from m5.util import code_formatter, compareVersions
# false). Current filters are: # false). Current filters are:
# main -- specifies the gem5 main() function # main -- specifies the gem5 main() function
# skip_lib -- do not put this file into the gem5 library # 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
# <unittest> -- unit tests use filters based on the unit test name # <unittest> -- unit tests use filters based on the unit test name
# #
# A parent can now be specified for a source file and default filter # 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): def __init__(self, package, source, **guards):
'''Specify the python package, the source file, and any 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 modname,ext = self.extname
assert ext == 'i' assert ext == 'i'
@ -238,8 +240,8 @@ class SwigSource(SourceFile):
cc_file = joinpath(self.dirname, modname + '_wrap.cc') cc_file = joinpath(self.dirname, modname + '_wrap.cc')
py_file = joinpath(self.dirname, modname + '.py') py_file = joinpath(self.dirname, modname + '.py')
self.cc_source = Source(cc_file, swig=True, parent=self) self.cc_source = Source(cc_file, swig=True, parent=self, **guards)
self.py_source = PySource(package, py_file, parent=self) self.py_source = PySource(package, py_file, parent=self, **guards)
class ProtoBuf(SourceFile): class ProtoBuf(SourceFile):
'''Add a Protocol Buffer to build''' '''Add a Protocol Buffer to build'''
@ -874,9 +876,9 @@ EmbeddedPython embedded_${sym}(
code.write(str(target[0])) code.write(str(target[0]))
for source in PySource.all: for source in PySource.all:
env.Command(source.cpp, source.tnode, env.Command(source.cpp, source.tnode,
MakeAction(embedPyFile, Transform("EMBED PY"))) 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 return obj
static_objs = \ lib_guards = {'main': False, 'skip_lib': False}
[ make_obj(s, True) for s in Source.get(main=False, skip_lib=False) ]
shared_objs = \ # Without Python, leave out all SWIG and Python content from the
[ make_obj(s, False) for s in Source.get(main=False, skip_lib=False) ] # 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_date = make_obj(date_source, static=True, extra_deps=static_objs)
static_objs.append(static_date) static_objs.append(static_date)
shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) shared_date = make_obj(date_source, static=False, extra_deps=shared_objs)
shared_objs.append(shared_date) shared_objs.append(shared_date)

View file

@ -462,9 +462,31 @@ Formula::str() const
return root ? root->str() : ""; 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 dumpQueue;
CallbackQueue resetQueue; CallbackQueue resetQueue;
void
processResetQueue()
{
resetQueue.process();
}
void
processDumpQueue()
{
dumpQueue.process();
}
void void
registerResetCallback(Callback *cb) registerResetCallback(Callback *cb)
{ {
@ -488,6 +510,24 @@ enable()
_enabled = true; _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 void
registerDumpCallback(Callback *cb) registerDumpCallback(Callback *cb)
{ {

View file

@ -3208,6 +3208,15 @@ void reset();
void enable(); void enable();
bool enabled(); 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 * Register a callback that should be called whenever statistics are
* reset * reset
@ -3220,6 +3229,16 @@ void registerResetCallback(Callback *cb);
*/ */
void registerDumpCallback(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<Info *> &statsList(); std::list<Info *> &statsList();
typedef std::map<const void *, Info *> MapType; typedef std::map<const void *, Info *> MapType;

View file

@ -31,8 +31,8 @@
Import('*') Import('*')
Source('swig/pyevent.cc') Source('swig/pyevent.cc', skip_no_python=True)
Source('swig/pyobject.cc') Source('swig/pyobject.cc', skip_no_python=True)
PySource('', 'importer.py') PySource('', 'importer.py')
PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/__init__.py')

View file

@ -41,6 +41,7 @@ def initText(filename, desc=True):
def initSimStats(): def initSimStats():
internal.stats.initSimStats() internal.stats.initSimStats()
internal.stats.registerPythonStatsHandlers()
names = [] names = []
stats_dict = {} stats_dict = {}

View file

@ -157,9 +157,12 @@ extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);
// these in sim/main.cc as well that are handled without this define. // these in sim/main.cc as well that are handled without this define.
#define PCC(s) const_cast<char *>(s) #define PCC(s) const_cast<char *>(s)
/** Single instance of PythonSimObjectResolver as its action is effectively
* static but SimObjectResolver can use a non-persistent object */
PythonSimObjectResolver pythonSimObjectResolver;
SimObject * SimObject *
resolveSimObject(const string &name) PythonSimObjectResolver::resolveSimObject(const string &name)
{ {
PyObject *module = PyImport_ImportModule(PCC("m5.SimObject")); PyObject *module = PyImport_ImportModule(PCC("m5.SimObject"));
if (module == NULL) if (module == NULL)
@ -188,3 +191,9 @@ resolveSimObject(const string &name)
return obj; return obj;
} }
Checkpoint *
getCheckpoint(const std::string &cpt_dir)
{
return new Checkpoint(cpt_dir, pythonSimObjectResolver);
}

View file

@ -36,7 +36,12 @@
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); 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); EtherInt * lookupEthPort(SimObject *so, const std::string &name, int i);
@ -53,11 +58,8 @@ serializeAll(const std::string &cpt_dir)
Serializable::serializeAll(cpt_dir); Serializable::serializeAll(cpt_dir);
} }
inline Checkpoint * Checkpoint *
getCheckpoint(const std::string &cpt_dir) getCheckpoint(const std::string &cpt_dir);
{
return new Checkpoint(cpt_dir);
}
inline void inline void
unserializeGlobals(Checkpoint *cp) unserializeGlobals(Checkpoint *cp)

View file

@ -43,6 +43,7 @@
#include "base/statistics.hh" #include "base/statistics.hh"
#include "sim/core.hh" #include "sim/core.hh"
#include "sim/stat_control.hh" #include "sim/stat_control.hh"
#include "sim/stat_register.hh"
namespace Stats { namespace Stats {
template <class T> template <class T>
@ -64,20 +65,6 @@ Stats_Info_flags_set(Info *info, FlagsType flags)
info->flags = flags; info->flags = flags;
} }
inline void
processResetQueue()
{
extern CallbackQueue resetQueue;
resetQueue.process();
}
inline void
processDumpQueue()
{
extern CallbackQueue dumpQueue;
dumpQueue.process();
}
inline char * inline char *
PCC(const char *string) PCC(const char *string)
{ {
@ -102,13 +89,13 @@ call_module_function(const char *module_name, const char *func_name)
} }
void void
dump() pythonDump()
{ {
call_module_function("m5.stats", "dump"); call_module_function("m5.stats", "dump");
} }
void void
reset() pythonReset()
{ {
call_module_function("m5.stats", "reset"); call_module_function("m5.stats", "reset");
} }
@ -150,6 +137,8 @@ template <class T> T cast_info(Info *info);
void initSimStats(); void initSimStats();
Output *initText(const std::string &filename, bool desc); Output *initText(const std::string &filename, bool desc);
void registerPythonStatsHandlers();
void schedStatEvent(bool dump, bool reset, void schedStatEvent(bool dump, bool reset,
Tick when = curTick(), Tick repeat = 0); Tick when = curTick(), Tick repeat = 0);

View file

@ -44,9 +44,11 @@ Source('arguments.cc')
Source('async.cc') Source('async.cc')
Source('core.cc') Source('core.cc')
Source('debug.cc') Source('debug.cc')
Source('py_interact.cc', skip_no_python=True)
Source('eventq.cc') Source('eventq.cc')
Source('global_event.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('main.cc', main=True, skip_lib=True)
Source('root.cc') Source('root.cc')
Source('serialize.cc') Source('serialize.cc')
@ -57,6 +59,7 @@ Source('sub_system.cc')
Source('ticked_object.cc') Source('ticked_object.cc')
Source('simulate.cc') Source('simulate.cc')
Source('stat_control.cc') Source('stat_control.cc')
Source('stat_register.cc', skip_no_python=True)
Source('clock_domain.cc') Source('clock_domain.cc')
Source('voltage_domain.cc') Source('voltage_domain.cc')
Source('system.cc') Source('system.cc')

View file

@ -29,8 +29,6 @@
* Steve Reinhardt * Steve Reinhardt
*/ */
#include <Python.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -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 remote_gdb_base_port = 7000;
int int

View file

@ -53,8 +53,6 @@ void takeCheckpoint(Tick when);
*/ */
void eventqDump(); void eventqDump();
void py_interact();
int getRemoteGDBPort(); int getRemoteGDBPort();
// Remote gdb base port. 0 disables remote gdb. // Remote gdb base port. 0 disables remote gdb.
void setRemoteGDBPort(int port); void setRemoteGDBPort(int port);

View file

@ -46,7 +46,6 @@
#include <marshal.h> #include <marshal.h>
#include <zlib.h> #include <zlib.h>
#include <csignal>
#include <iostream> #include <iostream>
#include <list> #include <list>
#include <string> #include <string>
@ -65,90 +64,6 @@
using namespace std; 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, // The python library is totally messed up with respect to constness,
// so make a simple macro to make life a little easier // so make a simple macro to make life a little easier
#define PyCC(x) (const_cast<char *>(x)) #define PyCC(x) (const_cast<char *>(x))

View file

@ -76,11 +76,6 @@ struct EmbeddedSwig
static void initAll(); static void initAll();
}; };
void dumpStatsHandler(int sigtype);
void dumprstStatsHandler(int sigtype);
void exitNowHandler(int sigtype);
void abortHandler(int sigtype);
void initSignals();
int initM5Python(); int initM5Python();
int m5Main(int argc, char **argv); int m5Main(int argc, char **argv);
PyMODINIT_FUNC initm5(void); PyMODINIT_FUNC initm5(void);

138
src/sim/init_signals.cc Normal file
View file

@ -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 <csignal>
#include <iostream>
#include <string>
#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);
}

40
src/sim/init_signals.hh Normal file
View file

@ -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__

View file

@ -31,6 +31,7 @@
#include <Python.h> #include <Python.h>
#include "sim/init.hh" #include "sim/init.hh"
#include "sim/init_signals.hh"
// main() is now pretty stripped down and just sets up python and then // main() is now pretty stripped down and just sets up python and then
// calls initM5Python which loads the various embedded python modules // calls initM5Python which loads the various embedded python modules

51
src/sim/py_interact.cc Normal file
View file

@ -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 <Python.h>
#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);
}

40
src/sim/py_interact.hh Normal file
View file

@ -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__

View file

@ -58,8 +58,6 @@
using namespace std; using namespace std;
extern SimObject *resolveSimObject(const string &);
// //
// The base implementations use to_number for parsing and '<<' for // The base implementations use to_number for parsing and '<<' for
// displaying, suitable for integer types. // displaying, suitable for integer types.
@ -600,8 +598,8 @@ Checkpoint::dir()
} }
Checkpoint::Checkpoint(const string &cpt_dir) Checkpoint::Checkpoint(const string &cpt_dir, SimObjectResolver &resolver)
: db(new IniFile), cptDir(setDir(cpt_dir)) : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
{ {
string filename = cptDir + "/" + Checkpoint::baseFilename; string filename = cptDir + "/" + Checkpoint::baseFilename;
if (!db->load(filename)) { if (!db->load(filename)) {
@ -630,7 +628,7 @@ Checkpoint::findObj(const string &section, const string &entry,
if (!db->find(section, entry, path)) if (!db->find(section, entry, path))
return false; return false;
value = resolveSimObject(path); value = objNameResolver.resolveSimObject(path);
return true; return true;
} }

View file

@ -255,14 +255,28 @@ class SerializableClass
SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \
OBJ_CLASS::createForUnserialize); 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 class Checkpoint
{ {
private: private:
IniFile *db; IniFile *db;
SimObjectResolver &objNameResolver;
public: public:
Checkpoint(const std::string &cpt_dir); Checkpoint(const std::string &cpt_dir, SimObjectResolver &resolver);
~Checkpoint(); ~Checkpoint();
const std::string cptDir; const std::string cptDir;

53
src/sim/stat_register.cc Normal file
View file

@ -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

57
src/sim/stat_register.hh Normal file
View file

@ -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__