From 23c04b8c666b062cf97ad127805bf56e0797303b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:59:58 -0400 Subject: Params: Remove an unnecessary include. --- src/python/m5/params.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 241d4ceaf..a895549ca 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -406,7 +406,6 @@ class MemorySize32(CheckedInt): class Addr(CheckedInt): cxx_type = 'Addr' - cxx_predecls = ['#include "arch/isa_traits.hh"'] size = 64 unsigned = True def __init__(self, value): -- cgit v1.2.3 From 7be8e671f1fac98fb26155d4804ba005e6b75b0f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 01:00:29 -0400 Subject: Params: Allow nested namespaces in cxx_namespace --- src/python/m5/SimObject.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 78df6bef1..d1aec44b3 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -217,7 +217,10 @@ class MetaSimObject(type): # just declaring a pointer. decl = 'class %s;' % _cxx_class if namespace: - decl = 'namespace %s { %s }' % (namespace, decl) + namespaces = namespace.split('::') + namespaces.reverse() + for namespace in namespaces: + decl = 'namespace %s { %s }' % (namespace, decl) cls._value_dict['cxx_predecls'] = [decl] if 'swig_predecls' not in cls._value_dict: -- cgit v1.2.3 From 907b28cc626e8b156d98187b0f91f5e8df0e9d56 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 13 Jun 2008 01:09:04 -0400 Subject: HG: Add compiled hg revision and date to the standard M5 output. --- src/python/generate.py | 35 +++++++++++++++++++++++++++++++++-- src/python/m5/main.py | 4 ++++ src/python/swig/core.i | 4 ++++ 3 files changed, 41 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/generate.py b/src/python/generate.py index eead6ff5d..f4d923870 100644 --- a/src/python/generate.py +++ b/src/python/generate.py @@ -31,8 +31,7 @@ import py_compile import sys import zipfile -from os.path import basename -from os.path import exists +from os.path import basename, exists, isdir, join class DictImporter(object): '''This importer takes a dictionary of arbitrary module names that @@ -527,3 +526,35 @@ extern const Flags *compoundFlags[]; ''' f.close() + + def programInfo(self, target, source, env): + def gen_file(target, rev, node, date): + pi_stats = file(target, 'w') + print >>pi_stats, 'const char *hgRev = "%s:%s";' % (rev, node) + print >>pi_stats, 'const char *hgDate = "%s";' % date + pi_stats.close() + + target = str(target[0]) + scons_dir = eval(str(source[0])) + try: + import mercurial.demandimport, mercurial.hg, mercurial.ui + import mercurial.util, mercurial.node + if not exists(scons_dir) or not isdir(scons_dir) or \ + not exists(join(scons_dir, ".hg")): + raise ValueError + repo = mercurial.hg.repository(mercurial.ui.ui(), scons_dir) + rev = mercurial.node.nullrev + repo.changelog.count() + changenode = repo.changelog.node(rev) + changes = repo.changelog.read(changenode) + date = mercurial.util.datestr(changes[2]) + + gen_file(target, rev, mercurial.node.hex(changenode), date) + + mercurial.demandimport.disable() + except ImportError: + gen_file(target, "Unknown", "Unknown", "Unknown") + + except: + print "in except" + gen_file(target, "Unknown", "Unknown", "Unknown") + mercurial.demandimport.disable() diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 4bcca46d2..cbdd65492 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -268,6 +268,10 @@ def main(): print "M5 compiled %s" % internal.core.cvar.compileDate; print "M5 started %s" % datetime.datetime.now().ctime() print "M5 executing on %s" % socket.gethostname() + + print "M5 revision %s" % internal.core.cvar.hgRev + print "M5 commit date %s" % internal.core.cvar.hgDate + print "command line:", for argv in sys.argv: print argv, diff --git a/src/python/swig/core.i b/src/python/swig/core.i index 770765ca4..567eff591 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -39,6 +39,8 @@ #include "sim/startup.hh" extern const char *compileDate; +extern const char *hgRev; +extern const char *hgDate; %} %include "stdint.i" @@ -51,6 +53,8 @@ void SimStartup(); void doExitCleanup(); char *compileDate; +char *hgRev; +char *hgDate; void setClockFrequency(Tick ticksPerSecond); -- cgit v1.2.3 From fe4fd9f4146684a649131d09bbf85ecb96ef4ba7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 13 Jun 2008 17:34:22 -0700 Subject: scons: fix program_info.cc generation --- src/python/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/generate.py b/src/python/generate.py index f4d923870..c32204bc9 100644 --- a/src/python/generate.py +++ b/src/python/generate.py @@ -535,7 +535,7 @@ extern const Flags *compoundFlags[]; pi_stats.close() target = str(target[0]) - scons_dir = eval(str(source[0])) + scons_dir = str(source[0]) try: import mercurial.demandimport, mercurial.hg, mercurial.ui import mercurial.util, mercurial.node -- cgit v1.2.3 From 2d037682ff800fa44e715250b07d708bbf4bde91 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 10:30:18 -0700 Subject: scons: proper fix for hg version stuff --- src/python/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/generate.py b/src/python/generate.py index c32204bc9..e6c36ecd2 100644 --- a/src/python/generate.py +++ b/src/python/generate.py @@ -535,7 +535,7 @@ extern const Flags *compoundFlags[]; pi_stats.close() target = str(target[0]) - scons_dir = str(source[0]) + scons_dir = str(source[0].get_contents()) try: import mercurial.demandimport, mercurial.hg, mercurial.ui import mercurial.util, mercurial.node -- cgit v1.2.3 From ce43e46576ccf09d56aeb7021d3decd75d08d90c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 12:57:21 -0700 Subject: Fix various SWIG warnings --- src/python/swig/event.i | 4 ++-- src/python/swig/range.i | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/swig/event.i b/src/python/swig/event.i index 9a2093c99..ee1f3d00b 100644 --- a/src/python/swig/event.i +++ b/src/python/swig/event.i @@ -44,8 +44,8 @@ void create(PyObject *object, Tick when); -class Event; -class CountedDrainEvent : public Event { +class CountedDrainEvent +{ public: void setCount(int _count); }; diff --git a/src/python/swig/range.i b/src/python/swig/range.i index 40809dae4..309e6a8ba 100644 --- a/src/python/swig/range.i +++ b/src/python/swig/range.i @@ -28,6 +28,8 @@ * Authors: Nathan Binkert */ +%rename(assign) *::operator=; + %include "base/range.hh" %include "sim/host.hh" -- cgit v1.2.3 From f82d4e2364e9df683b6891c04efaa861093a50ec Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 20:19:49 -0700 Subject: python: Move various utility classes into a new m5.util package so they're all in the same place. This also involves having just one jobfile.py and moving it into the utils directory to avoid duplication. Lots of improvements to the utility as well. --HG-- rename : src/python/m5/attrdict.py => src/python/m5/util/attrdict.py rename : util/pbs/jobfile.py => src/python/m5/util/jobfile.py rename : src/python/m5/util.py => src/python/m5/util/misc.py rename : src/python/m5/multidict.py => src/python/m5/util/multidict.py rename : util/stats/orderdict.py => src/python/m5/util/orderdict.py --- src/python/SConscript | 8 +- src/python/m5/SimObject.py | 1 - src/python/m5/attrdict.py | 61 ------ src/python/m5/main.py | 2 +- src/python/m5/multidict.py | 182 ---------------- src/python/m5/util.py | 59 ------ src/python/m5/util/__init__.py | 32 +++ src/python/m5/util/attrdict.py | 70 +++++++ src/python/m5/util/jobfile.py | 450 ++++++++++++++++++++++++++++++++++++++++ src/python/m5/util/misc.py | 87 ++++++++ src/python/m5/util/multidict.py | 182 ++++++++++++++++ src/python/m5/util/orderdict.py | 80 +++++++ 12 files changed, 907 insertions(+), 307 deletions(-) delete mode 100644 src/python/m5/attrdict.py delete mode 100644 src/python/m5/multidict.py delete mode 100644 src/python/m5/util.py create mode 100644 src/python/m5/util/__init__.py create mode 100644 src/python/m5/util/attrdict.py create mode 100644 src/python/m5/util/jobfile.py create mode 100644 src/python/m5/util/misc.py create mode 100644 src/python/m5/util/multidict.py create mode 100644 src/python/m5/util/orderdict.py (limited to 'src/python') diff --git a/src/python/SConscript b/src/python/SConscript index b39c9ea9c..0785b4307 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -36,18 +36,20 @@ Source('swig/pyobject.cc') PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/SimObject.py') -PySource('m5', 'm5/attrdict.py') PySource('m5', 'm5/convert.py') PySource('m5', 'm5/event.py') PySource('m5', 'm5/main.py') -PySource('m5', 'm5/multidict.py') PySource('m5', 'm5/params.py') PySource('m5', 'm5/proxy.py') PySource('m5', 'm5/simulate.py') PySource('m5', 'm5/smartdict.py') PySource('m5', 'm5/stats.py') PySource('m5', 'm5/ticks.py') -PySource('m5', 'm5/util.py') +PySource('m5.util', 'm5/util/__init__.py') +PySource('m5.util', 'm5/util/attrdict.py') +PySource('m5.util', 'm5/util/jobfile.py') +PySource('m5.util', 'm5/util/misc.py') +PySource('m5.util', 'm5/util/multidict.py') SwigSource('m5.internal', 'swig/core.i') SwigSource('m5.internal', 'swig/debug.i') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index d1aec44b3..41ed3df9e 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -32,7 +32,6 @@ import sys, types import proxy import m5 from util import * -from multidict import multidict # These utility functions have to come first because they're # referenced in params.py... otherwise they won't be defined when we diff --git a/src/python/m5/attrdict.py b/src/python/m5/attrdict.py deleted file mode 100644 index 4ee7f1b8c..000000000 --- a/src/python/m5/attrdict.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (c) 2006 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 - -__all__ = [ 'attrdict' ] - -class attrdict(dict): - def __getattr__(self, attr): - if attr in self: - return self.__getitem__(attr) - return super(attrdict, self).__getattribute__(attr) - - def __setattr__(self, attr, value): - if attr in dir(self): - return super(attrdict, self).__setattr__(attr, value) - return self.__setitem__(attr, value) - - def __delattr__(self, attr): - if attr in self: - return self.__delitem__(attr) - return super(attrdict, self).__delattr__(attr, value) - -if __name__ == '__main__': - x = attrdict() - x.y = 1 - x['z'] = 2 - print x['y'], x.y - print x['z'], x.z - print dir(x) - print x - - print - - del x['y'] - del x.z - print dir(x) - print(x) diff --git a/src/python/m5/main.py b/src/python/m5/main.py index cbdd65492..5c3324224 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -33,7 +33,7 @@ import os import socket import sys -from attrdict import attrdict +from util import attrdict import defines import traceflags diff --git a/src/python/m5/multidict.py b/src/python/m5/multidict.py deleted file mode 100644 index b5cd700ef..000000000 --- a/src/python/m5/multidict.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright (c) 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 - -__all__ = [ 'multidict' ] - -class multidict(object): - def __init__(self, parent = {}, **kwargs): - self.local = dict(**kwargs) - self.parent = parent - self.deleted = {} - - def __str__(self): - return str(dict(self.items())) - - def __repr__(self): - return `dict(self.items())` - - def __contains__(self, key): - return self.local.has_key(key) or self.parent.has_key(key) - - def __delitem__(self, key): - try: - del self.local[key] - except KeyError, e: - if key in self.parent: - self.deleted[key] = True - else: - raise KeyError, e - - def __setitem__(self, key, value): - self.deleted.pop(key, False) - self.local[key] = value - - def __getitem__(self, key): - try: - return self.local[key] - except KeyError, e: - if not self.deleted.get(key, False) and key in self.parent: - return self.parent[key] - else: - raise KeyError, e - - def __len__(self): - return len(self.local) + len(self.parent) - - def next(self): - for key,value in self.local.items(): - yield key,value - - if self.parent: - for key,value in self.parent.next(): - if key not in self.local and key not in self.deleted: - yield key,value - - def has_key(self, key): - return key in self - - def iteritems(self): - for item in self.next(): - yield item - - def items(self): - return [ item for item in self.next() ] - - def iterkeys(self): - for key,value in self.next(): - yield key - - def keys(self): - return [ key for key,value in self.next() ] - - def itervalues(self): - for key,value in self.next(): - yield value - - def values(self): - return [ value for key,value in self.next() ] - - def get(self, key, default=None): - try: - return self[key] - except KeyError, e: - return default - - def setdefault(self, key, default): - try: - return self[key] - except KeyError: - self.deleted.pop(key, False) - self.local[key] = default - return default - - def _dump(self): - print 'multidict dump' - node = self - while isinstance(node, multidict): - print ' ', node.local - node = node.parent - - def _dumpkey(self, key): - values = [] - node = self - while isinstance(node, multidict): - if key in node.local: - values.append(node.local[key]) - node = node.parent - print key, values - -if __name__ == '__main__': - test1 = multidict() - test2 = multidict(test1) - test3 = multidict(test2) - test4 = multidict(test3) - - test1['a'] = 'test1_a' - test1['b'] = 'test1_b' - test1['c'] = 'test1_c' - test1['d'] = 'test1_d' - test1['e'] = 'test1_e' - - test2['a'] = 'test2_a' - del test2['b'] - test2['c'] = 'test2_c' - del test1['a'] - - test2.setdefault('f', multidict) - - print 'test1>', test1.items() - print 'test2>', test2.items() - #print test1['a'] - print test1['b'] - print test1['c'] - print test1['d'] - print test1['e'] - - print test2['a'] - #print test2['b'] - print test2['c'] - print test2['d'] - print test2['e'] - - for key in test2.iterkeys(): - print key - - test2.get('g', 'foo') - #test2.get('b') - test2.get('b', 'bar') - test2.setdefault('b', 'blah') - print test1 - print test2 - print `test2` - - print len(test2) - - test3['a'] = [ 0, 1, 2, 3 ] - - print test4 diff --git a/src/python/m5/util.py b/src/python/m5/util.py deleted file mode 100644 index 28b8b1b94..000000000 --- a/src/python/m5/util.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2004-2006 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: Steve Reinhardt -# Nathan Binkert - -############################# -# -# Utility classes & methods -# -############################# - -class Singleton(type): - def __call__(cls, *args, **kwargs): - if hasattr(cls, '_instance'): - return cls._instance - - cls._instance = super(Singleton, cls).__call__(*args, **kwargs) - return cls._instance - -# Apply method to object. -# applyMethod(obj, 'meth', ) is equivalent to obj.meth() -def applyMethod(obj, meth, *args, **kwargs): - return getattr(obj, meth)(*args, **kwargs) - -# If the first argument is an (non-sequence) object, apply the named -# method with the given arguments. If the first argument is a -# sequence, apply the method to each element of the sequence (a la -# 'map'). -def applyOrMap(objOrSeq, meth, *args, **kwargs): - if not isinstance(objOrSeq, (list, tuple)): - return applyMethod(objOrSeq, meth, *args, **kwargs) - else: - return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] - - diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py new file mode 100644 index 000000000..f82de696a --- /dev/null +++ b/src/python/m5/util/__init__.py @@ -0,0 +1,32 @@ +# 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 + +from attrdict import attrdict, optiondict +from misc import * +from multidict import multidict +import jobfile diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py new file mode 100644 index 000000000..44479c456 --- /dev/null +++ b/src/python/m5/util/attrdict.py @@ -0,0 +1,70 @@ +# Copyright (c) 2006 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 + +__all__ = [ 'attrdict', 'optiondict' ] + +class attrdict(dict): + def __getattr__(self, attr): + if attr in self: + return self.__getitem__(attr) + return super(attrdict, self).__getattribute__(attr) + + def __setattr__(self, attr, value): + if attr in dir(self): + return super(attrdict, self).__setattr__(attr, value) + return self.__setitem__(attr, value) + + def __delattr__(self, attr): + if attr in self: + return self.__delitem__(attr) + return super(attrdict, self).__delattr__(attr, value) + +class optiondict(attrdict): + def __getattr__(self, attr): + try: + return super(optiondict, self).__getattr__(attr) + except AttributeError: + #d = optionsdict() + #setattr(self, attr, d) + return None + +if __name__ == '__main__': + x = attrdict() + x.y = 1 + x['z'] = 2 + print x['y'], x.y + print x['z'], x.z + print dir(x) + print x + + print + + del x['y'] + del x.z + print dir(x) + print(x) diff --git a/src/python/m5/util/jobfile.py b/src/python/m5/util/jobfile.py new file mode 100644 index 000000000..5e015c4ad --- /dev/null +++ b/src/python/m5/util/jobfile.py @@ -0,0 +1,450 @@ +# Copyright (c) 2005-2006 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 + +import sys + +from attrdict import attrdict, optiondict +from misc import crossproduct, flatten + +class Data(object): + def __init__(self, name, desc, **kwargs): + self.name = name + self.desc = desc + self.__dict__.update(kwargs) + + def update(self, obj): + if not isinstance(obj, Data): + raise AttributeError, "can only update from Data object" + + for k,v in obj.__dict__.iteritems(): + if not k.startswith('_'): + self.__dict__[k] = v + if hasattr(self, 'system') and hasattr(obj, 'system'): + if self.system != obj.system: + raise AttributeError, \ + "conflicting values for system: '%s'/'%s'" % \ + (self.system, obj.system) + + def printinfo(self): + if self.name: + print 'name: %s' % self.name + if self.desc: + print 'desc: %s' % self.desc + try: + if self.system: + print 'system: %s' % self.system + except AttributeError: + pass + + def printverbose(self): + for key in self: + val = self[key] + if isinstance(val, dict): + import pprint + val = pprint.pformat(val) + print '%-20s = %s' % (key, val) + print + + def __contains__(self, attr): + if attr.startswith('_'): + return False + return attr in self.__dict__ + + def __getitem__(self, key): + if key.startswith('_'): + raise KeyError, "Key '%s' not found" % attr + return self.__dict__[key] + + def __iter__(self): + keys = self.__dict__.keys() + keys.sort() + for key in keys: + if not key.startswith('_'): + yield key + + def optiondict(self): + result = optiondict() + for key in self: + result[key] = self[key] + return result + + def __str__(self): + return self.name + +class Job(Data): + def __init__(self, options): + super(Job, self).__init__('', '') + + config = options[0]._config + for opt in options: + if opt._config != config: + raise AttributeError, \ + "All options are not from the same Configuration" + + self._config = config + self._groups = [ opt._group for opt in options ] + self._options = options + + self.update(self._config) + for group in self._groups: + self.update(group) + + self._is_checkpoint = True + + for option in self._options: + self.update(option) + if not option._group._checkpoint: + self._is_checkpoint = False + + if option._suboption: + self.update(option._suboption) + self._is_checkpoint = False + + names = [ ] + for opt in self._options: + if opt.name: + names.append(opt.name) + self.name = ':'.join(names) + + descs = [ ] + for opt in self._options: + if opt.desc: + descs.append(opt.desc) + self.desc = ', '.join(descs) + + self._checkpoint = None + if not self._is_checkpoint: + opts = [] + for opt in options: + cpt = opt._group._checkpoint + if not cpt: + continue + if isinstance(cpt, Option): + opt = cpt.clone(suboptions=False) + else: + opt = opt.clone(suboptions=False) + + opts.append(opt) + + if opts: + self._checkpoint = Job(opts) + + def clone(self): + return Job(self._options) + + def printinfo(self): + super(Job, self).printinfo() + if self._checkpoint: + print 'checkpoint: %s' % self._checkpoint.name + print 'config: %s' % self._config.name + print 'groups: %s' % [ g.name for g in self._groups ] + print 'options: %s' % [ o.name for o in self._options ] + super(Job, self).printverbose() + +class SubOption(Data): + def __init__(self, name, desc, **kwargs): + super(SubOption, self).__init__(name, desc, **kwargs) + self._number = None + +class Option(Data): + def __init__(self, name, desc, **kwargs): + super(Option, self).__init__(name, desc, **kwargs) + self._suboptions = [] + self._suboption = None + self._number = None + + def __getattribute__(self, attr): + if attr == 'name': + name = self.__dict__[attr] + if self._suboption is not None: + name = '%s:%s' % (name, self._suboption.name) + return name + + if attr == 'desc': + desc = [ self.__dict__[attr] ] + if self._suboption is not None and self._suboption.desc: + desc.append(self._suboption.desc) + return ', '.join(desc) + + return super(Option, self).__getattribute__(attr) + + def suboption(self, name, desc, **kwargs): + subo = SubOption(name, desc, **kwargs) + subo._config = self._config + subo._group = self._group + subo._option = self + subo._number = len(self._suboptions) + self._suboptions.append(subo) + return subo + + def clone(self, suboptions=True): + option = Option(self.__dict__['name'], self.__dict__['desc']) + option.update(self) + option._group = self._group + option._config = self._config + option._number = self._number + if suboptions: + option._suboptions.extend(self._suboptions) + option._suboption = self._suboption + return option + + def subopts(self): + if not self._suboptions: + return [ self ] + + subopts = [] + for subo in self._suboptions: + option = self.clone() + option._suboption = subo + subopts.append(option) + + return subopts + + def printinfo(self): + super(Option, self).printinfo() + print 'config: %s' % self._config.name + super(Option, self).printverbose() + +class Group(Data): + def __init__(self, name, desc, **kwargs): + super(Group, self).__init__(name, desc, **kwargs) + self._options = [] + self._number = None + self._checkpoint = False + + def option(self, name, desc, **kwargs): + opt = Option(name, desc, **kwargs) + opt._config = self._config + opt._group = self + opt._number = len(self._options) + self._options.append(opt) + return opt + + def options(self): + return self._options + + def subopts(self): + subopts = [] + for opt in self._options: + for subo in opt.subopts(): + subopts.append(subo) + return subopts + + def printinfo(self): + super(Group, self).printinfo() + print 'config: %s' % self._config.name + print 'options: %s' % [ o.name for o in self._options ] + super(Group, self).printverbose() + +class Configuration(Data): + def __init__(self, name, desc, **kwargs): + super(Configuration, self).__init__(name, desc, **kwargs) + self._groups = [] + self._posfilters = [] + self._negfilters = [] + + def group(self, name, desc, **kwargs): + grp = Group(name, desc, **kwargs) + grp._config = self + grp._number = len(self._groups) + self._groups.append(grp) + return grp + + def groups(self): + return self._groups + + def checkchildren(self, kids): + for kid in kids: + if kid._config != self: + raise AttributeError, "child from the wrong configuration" + + def sortgroups(self, groups): + groups = [ (grp._number, grp) for grp in groups ] + groups.sort() + return [ grp[1] for grp in groups ] + + def options(self, groups=None, checkpoint=False): + if groups is None: + groups = self._groups + self.checkchildren(groups) + groups = self.sortgroups(groups) + if checkpoint: + groups = [ grp for grp in groups if grp._checkpoint ] + optgroups = [ g.options() for g in groups ] + else: + optgroups = [ g.subopts() for g in groups ] + if not optgroups: + return + for options in crossproduct(optgroups): + for opt in options: + cpt = opt._group._checkpoint + if not isinstance(cpt, bool) and cpt != opt: + if checkpoint: + break + else: + yield options + else: + if checkpoint: + yield options + + def addfilter(self, filt, pos=True): + import re + filt = re.compile(filt) + if pos: + self._posfilters.append(filt) + else: + self._negfilters.append(filt) + + def jobfilter(self, job): + for filt in self._negfilters: + if filt.match(job.name): + return False + + if not self._posfilters: + return True + + for filt in self._posfilters: + if filt.match(job.name): + return True + + return False + + def checkpoints(self, groups=None): + for options in self.options(groups, True): + job = Job(options) + if self.jobfilter(job): + yield job + + def jobs(self, groups=None): + for options in self.options(groups, False): + job = Job(options) + if self.jobfilter(job): + yield job + + def alljobs(self, groups=None): + for options in self.options(groups, True): + yield Job(options) + for options in self.options(groups, False): + yield Job(options) + + def find(self, jobname): + for job in self.alljobs(): + if job.name == jobname: + return job + else: + raise AttributeError, "job '%s' not found" % jobname + + def job(self, options): + self.checkchildren(options) + options = [ (opt._group._number, opt) for opt in options ] + options.sort() + options = [ opt[1] for opt in options ] + job = Job(options) + return job + + def printinfo(self): + super(Configuration, self).printinfo() + print 'groups: %s' % [ g.name for g in self._groups ] + super(Configuration, self).printverbose() + +def JobFile(jobfile): + from os.path import expanduser, isfile, join as joinpath + filename = expanduser(jobfile) + + # Can't find filename in the current path, search sys.path + if not isfile(filename): + for path in sys.path: + testname = joinpath(path, filename) + if isfile(testname): + filename = testname + break + else: + raise AttributeError, \ + "Could not find file '%s'" % jobfile + + data = {} + execfile(filename, data) + if 'conf' not in data: + raise ImportError, 'cannot import name conf from %s' % jobfile + conf = data['conf'] + import jobfile + if not isinstance(conf, Configuration): + raise AttributeError, \ + 'conf in jobfile: %s (%s) is not type %s' % \ + (jobfile, type(conf), Configuration) + return conf + +def main(conf=None): + import sys + + usage = 'Usage: %s [-b] [-c] [-v] ' % sys.argv[0] + + try: + import getopt + opts, args = getopt.getopt(sys.argv[1:], '-bcv') + except getopt.GetoptError: + sys.exit(usage) + + both = False + checkpoint = False + verbose = False + for opt,arg in opts: + if opt == '-b': + both = True + checkpoint = True + if opt == '-c': + checkpoint = True + if opt == '-v': + verbose = True + + if conf is None: + if len(args) != 1: + raise AttributeError, usage + conf = JobFile(args[0]) + else: + if len(args) != 0: + raise AttributeError, usage + + if both: + jobs = conf.alljobs() + elif checkpoint: + jobs = conf.checkpoints() + else: + jobs = conf.jobs() + + for job in jobs: + if verbose: + job.printinfo() + else: + cpt = '' + if job._checkpoint: + cpt = job._checkpoint.name + print job.name, cpt + +if __name__ == '__main__': + main() diff --git a/src/python/m5/util/misc.py b/src/python/m5/util/misc.py new file mode 100644 index 000000000..094e3ed9a --- /dev/null +++ b/src/python/m5/util/misc.py @@ -0,0 +1,87 @@ +# Copyright (c) 2004-2006 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: Steve Reinhardt +# Nathan Binkert + +############################# +# +# Utility classes & methods +# +############################# + +class Singleton(type): + def __call__(cls, *args, **kwargs): + if hasattr(cls, '_instance'): + return cls._instance + + cls._instance = super(Singleton, cls).__call__(*args, **kwargs) + return cls._instance + +# Apply method to object. +# applyMethod(obj, 'meth', ) is equivalent to obj.meth() +def applyMethod(obj, meth, *args, **kwargs): + return getattr(obj, meth)(*args, **kwargs) + +# If the first argument is an (non-sequence) object, apply the named +# method with the given arguments. If the first argument is a +# sequence, apply the method to each element of the sequence (a la +# 'map'). +def applyOrMap(objOrSeq, meth, *args, **kwargs): + if not isinstance(objOrSeq, (list, tuple)): + return applyMethod(objOrSeq, meth, *args, **kwargs) + else: + return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] + +def crossproduct(items): + if not isinstance(items, (list, tuple)): + raise AttributeError, 'crossproduct works only on sequences' + + if not items: + yield None + return + + current = items[0] + remainder = items[1:] + + if not hasattr(current, '__iter__'): + current = [ current ] + + for item in current: + for rem in crossproduct(remainder): + data = [ item ] + if rem: + data += rem + yield data + +def flatten(items): + if not isinstance(items, (list, tuple)): + yield items + return + + for item in items: + for flat in flatten(item): + yield flat diff --git a/src/python/m5/util/multidict.py b/src/python/m5/util/multidict.py new file mode 100644 index 000000000..b5cd700ef --- /dev/null +++ b/src/python/m5/util/multidict.py @@ -0,0 +1,182 @@ +# Copyright (c) 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 + +__all__ = [ 'multidict' ] + +class multidict(object): + def __init__(self, parent = {}, **kwargs): + self.local = dict(**kwargs) + self.parent = parent + self.deleted = {} + + def __str__(self): + return str(dict(self.items())) + + def __repr__(self): + return `dict(self.items())` + + def __contains__(self, key): + return self.local.has_key(key) or self.parent.has_key(key) + + def __delitem__(self, key): + try: + del self.local[key] + except KeyError, e: + if key in self.parent: + self.deleted[key] = True + else: + raise KeyError, e + + def __setitem__(self, key, value): + self.deleted.pop(key, False) + self.local[key] = value + + def __getitem__(self, key): + try: + return self.local[key] + except KeyError, e: + if not self.deleted.get(key, False) and key in self.parent: + return self.parent[key] + else: + raise KeyError, e + + def __len__(self): + return len(self.local) + len(self.parent) + + def next(self): + for key,value in self.local.items(): + yield key,value + + if self.parent: + for key,value in self.parent.next(): + if key not in self.local and key not in self.deleted: + yield key,value + + def has_key(self, key): + return key in self + + def iteritems(self): + for item in self.next(): + yield item + + def items(self): + return [ item for item in self.next() ] + + def iterkeys(self): + for key,value in self.next(): + yield key + + def keys(self): + return [ key for key,value in self.next() ] + + def itervalues(self): + for key,value in self.next(): + yield value + + def values(self): + return [ value for key,value in self.next() ] + + def get(self, key, default=None): + try: + return self[key] + except KeyError, e: + return default + + def setdefault(self, key, default): + try: + return self[key] + except KeyError: + self.deleted.pop(key, False) + self.local[key] = default + return default + + def _dump(self): + print 'multidict dump' + node = self + while isinstance(node, multidict): + print ' ', node.local + node = node.parent + + def _dumpkey(self, key): + values = [] + node = self + while isinstance(node, multidict): + if key in node.local: + values.append(node.local[key]) + node = node.parent + print key, values + +if __name__ == '__main__': + test1 = multidict() + test2 = multidict(test1) + test3 = multidict(test2) + test4 = multidict(test3) + + test1['a'] = 'test1_a' + test1['b'] = 'test1_b' + test1['c'] = 'test1_c' + test1['d'] = 'test1_d' + test1['e'] = 'test1_e' + + test2['a'] = 'test2_a' + del test2['b'] + test2['c'] = 'test2_c' + del test1['a'] + + test2.setdefault('f', multidict) + + print 'test1>', test1.items() + print 'test2>', test2.items() + #print test1['a'] + print test1['b'] + print test1['c'] + print test1['d'] + print test1['e'] + + print test2['a'] + #print test2['b'] + print test2['c'] + print test2['d'] + print test2['e'] + + for key in test2.iterkeys(): + print key + + test2.get('g', 'foo') + #test2.get('b') + test2.get('b', 'bar') + test2.setdefault('b', 'blah') + print test1 + print test2 + print `test2` + + print len(test2) + + test3['a'] = [ 0, 1, 2, 3 ] + + print test4 diff --git a/src/python/m5/util/orderdict.py b/src/python/m5/util/orderdict.py new file mode 100644 index 000000000..3f755d299 --- /dev/null +++ b/src/python/m5/util/orderdict.py @@ -0,0 +1,80 @@ +# Copyright (c) 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 + +__all__ = [ 'orderdict' ] + +class orderdict(dict): + def __init__(self, d = {}): + self._keys = d.keys() + super(orderdict, self).__init__(d) + + def __setitem__(self, key, item): + super(orderdict, self).__setitem__(key, item) + if not hasattr(self, '_keys'): + self._keys = [key,] + if key not in self._keys: + self._keys.append(key) + + def __delitem__(self, key): + super(orderdict, self).__delitem__(key) + self._keys.remove(key) + + def clear(self): + super(orderdict, self).clear() + self._keys = [] + + def items(self): + for i in self._keys: + yield i, self[i] + + def keys(self): + return self._keys + + def popitem(self): + if len(self._keys) == 0: + raise KeyError('dictionary is empty') + else: + key = self._keys[-1] + val = self[key] + del self[key] + return key, val + + def setdefault(self, key, failobj = None): + super(orderdict, self).setdefault(key, failobj) + if key not in self._keys: + self._keys.append(key) + + def update(self, d): + for key in d.keys(): + if not self.has_key(key): + self._keys.append(key) + super(orderdict, self).update(d) + + def values(self): + for i in self._keys: + yield self[i] -- cgit v1.2.3 From 3d2e7797ccb554092a4140fc8e11407edd7eedc4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 20:39:31 -0700 Subject: params: Fix floating point parameters --- src/python/m5/params.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/params.py b/src/python/m5/params.py index a895549ca..c8d0d8f46 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -379,6 +379,13 @@ class Percent(CheckedInt): cxx_type = 'int'; min = 0; max = 100 class Float(ParamValue, float): cxx_type = 'double' + def __init__(self, value): + if isinstance(value, (int, long, float, NumericParamValue, Float)): + self.value = float(value) + else: + raise TypeError, "Can't convert object of type %s to Float" \ + % type(value).__name__ + def getValue(self): return float(self.value) @@ -895,7 +902,9 @@ class MemoryBandwidth(float,ParamValue): def getValue(self): # convert to seconds per byte - value = 1.0 / float(self) + value = float(self) + if value: + value = 1.0 / float(self) # convert to ticks per byte value = ticks.fromSeconds(value) return float(value) -- cgit v1.2.3 From 4afdc40d70db76d895cc9bfe6bf3786d379589b7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 20:42:45 -0700 Subject: params: Fix the memory bandwidth parameter --- src/python/m5/params.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/params.py b/src/python/m5/params.py index c8d0d8f46..938278541 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -892,7 +892,7 @@ class NetworkBandwidth(float,ParamValue): class MemoryBandwidth(float,ParamValue): cxx_type = 'float' - def __new__(self, value): + def __new__(cls, value): # we want the number of ticks per byte of data val = convert.toMemoryBandwidth(value) return super(cls, MemoryBandwidth).__new__(cls, val) -- cgit v1.2.3 From 779c31077c965e28575fca3c065d651fcc87c134 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 21:15:58 -0700 Subject: python: Separate the options parsing stuff. Remove options parsing stuff from main.py so things are a bit more obvious. --- src/python/SConscript | 1 + src/python/m5/main.py | 114 +++++++------------------------------ src/python/m5/options.py | 145 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 94 deletions(-) create mode 100644 src/python/m5/options.py (limited to 'src/python') diff --git a/src/python/SConscript b/src/python/SConscript index 0785b4307..cca9217b0 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -39,6 +39,7 @@ PySource('m5', 'm5/SimObject.py') PySource('m5', 'm5/convert.py') PySource('m5', 'm5/event.py') PySource('m5', 'm5/main.py') +PySource('m5', 'm5/options.py') PySource('m5', 'm5/params.py') PySource('m5', 'm5/proxy.py') PySource('m5', 'm5/simulate.py') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 5c3324224..8011c64b8 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -28,25 +28,17 @@ import code import datetime -import optparse import os import socket import sys from util import attrdict import defines +from options import OptionParser import traceflags __all__ = [ 'options', 'arguments', 'main' ] -usage="%prog [m5 options] script.py [script options]" -version="%prog 2.0" -brief_copyright=''' -Copyright (c) 2001-2008 -The Regents of The University of Michigan -All Rights Reserved -''' - def print_list(items, indent=4): line = ' ' * indent for i,item in enumerate(items): @@ -60,64 +52,19 @@ def print_list(items, indent=4): line += item print line -# there's only one option parsing done, so make it global and add some -# helper functions to make it work well. -parser = optparse.OptionParser(usage=usage, version=version, - description=brief_copyright, - formatter=optparse.TitledHelpFormatter()) -parser.disable_interspersed_args() - -# current option group -group = None - -def set_group(*args, **kwargs): - '''set the current option group''' - global group - if not args and not kwargs: - group = None - else: - group = parser.add_option_group(*args, **kwargs) - -class splitter(object): - def __init__(self, split): - self.split = split - def __call__(self, option, opt_str, value, parser): - getattr(parser.values, option.dest).extend(value.split(self.split)) - -def add_option(*args, **kwargs): - '''add an option to the current option group, or global none set''' - - # if action=split, but allows the option arguments - # themselves to be lists separated by the split variable''' - - if kwargs.get('action', None) == 'append' and 'split' in kwargs: - split = kwargs.pop('split') - kwargs['default'] = [] - kwargs['type'] = 'string' - kwargs['action'] = 'callback' - kwargs['callback'] = splitter(split) - - if group: - return group.add_option(*args, **kwargs) - - return parser.add_option(*args, **kwargs) - -def bool_option(name, default, help): - '''add a boolean option called --name and --no-name. - Display help depending on which is the default''' - - tname = '--%s' % name - fname = '--no-%s' % name - dest = name.replace('-', '_') - if default: - thelp = optparse.SUPPRESS_HELP - fhelp = help - else: - thelp = help - fhelp = optparse.SUPPRESS_HELP +usage="%prog [m5 options] script.py [script options]" +version="%prog 2.0" +brief_copyright=''' +Copyright (c) 2001-2008 +The Regents of The University of Michigan +All Rights Reserved +''' - add_option(tname, action="store_true", default=default, help=thelp) - add_option(fname, action="store_false", dest=dest, help=fhelp) +options = OptionParser(usage=usage, version=version, + description=brief_copyright) +add_option = options.add_option +set_group = options.set_group +usage = options.usage # Help options add_option('-A', "--authors", action="store_true", default=False, @@ -168,39 +115,13 @@ add_option("--trace-file", metavar="FILE", default="cout", add_option("--trace-ignore", metavar="EXPR", action='append', split=':', help="Ignore EXPR sim objects") -options = attrdict() -arguments = [] - -def usage(exitcode=None): - parser.print_help() - if exitcode is not None: - sys.exit(exitcode) - -def parse_args(): - _opts,args = parser.parse_args() - opts = attrdict(_opts.__dict__) - - # setting verbose and quiet at the same time doesn't make sense - if opts.verbose > 0 and opts.quiet > 0: - usage(2) - - # store the verbosity in a single variable. 0 is default, - # negative numbers represent quiet and positive values indicate verbose - opts.verbose -= opts.quiet - - del opts.quiet - - options.update(opts) - arguments.extend(args) - return opts,args - def main(): import defines import event import info import internal - parse_args() + arguments = options.parse_args() done = False @@ -261,6 +182,11 @@ def main(): if done: sys.exit(0) + # setting verbose and quiet at the same time doesn't make sense + if options.verbose > 0 and options.quiet > 0: + options.usage(2) + + verbose = options.verbose - options.quiet if options.verbose >= 0: print "M5 Simulator System" print brief_copyright @@ -282,7 +208,7 @@ def main(): if arguments and not os.path.isfile(arguments[0]): print "Script %s not found" % arguments[0] - usage(2) + options.usage(2) # tell C++ about output directory internal.core.setOutputDir(options.outdir) diff --git a/src/python/m5/options.py b/src/python/m5/options.py new file mode 100644 index 000000000..50eea429c --- /dev/null +++ b/src/python/m5/options.py @@ -0,0 +1,145 @@ +# Copyright (c) 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 + +import optparse +import sys +import util + +from optparse import * + +class nodefault(object): pass + +class splitter(object): + def __init__(self, split): + self.split = split + def __call__(self, option, opt_str, value, parser): + values = value.split(self.split) + dest = getattr(parser.values, option.dest) + if dest is None: + setattr(parser.values, option.dest, values) + else: + dest.extend(values) + +class OptionParser(object): + def __init__(self, *args, **kwargs): + kwargs.setdefault('formatter', optparse.TitledHelpFormatter()) + self._optparse = optparse.OptionParser(*args, **kwargs) + self._optparse.disable_interspersed_args() + + self._allopts = {} + self._defaults = {} + self._options = util.attrdict() + + # current option group + self._group = self._optparse + + def set_group(self, *args, **kwargs): + '''set the current option group''' + if not args and not kwargs: + self._group = self._optparse + else: + self._group = self._optparse.add_option_group(*args, **kwargs) + + def add_option(self, *args, **kwargs): + '''add an option to the current option group, or global none set''' + + # if action=split, but allows the option arguments + # themselves to be lists separated by the split variable''' + + if kwargs.get('action', None) == 'append' and 'split' in kwargs: + split = kwargs.pop('split') + kwargs['default'] = [] + kwargs['type'] = 'string' + kwargs['action'] = 'callback' + kwargs['callback'] = splitter(split) + + default = kwargs.pop('default', nodefault) + option = self._group.add_option(*args, **kwargs) + dest = option.dest + if dest not in self._allopts: + self._allopts[dest] = option + + if default != nodefault: + if dest not in self._options: + self._options[dest] = default + + return option + + def bool_option(self, name, default, help): + '''add a boolean option called --name and --no-name. + Display help depending on which is the default''' + + tname = '--%s' % name + fname = '--no-%s' % name + dest = name.replace('-', '_') + if default: + thelp = optparse.SUPPRESS_HELP + fhelp = help + else: + thelp = help + fhelp = optparse.SUPPRESS_HELP + + topt = self.add_option(tname, action="store_true", default=default, + help=thelp) + fopt = self.add_option(fname, action="store_false", dest=dest, + help=fhelp) + + return topt,fopt + + def __getattr__(self, attr): + if attr.startswith('_'): + return super(OptionParser, self).__getattr__(attr) + + if attr in self._options: + return self._options[attr] + + raise AttributeError, "Option %s not found" % attr + + def __setattr__(self, attr, value): + if attr.startswith('_'): + return super(OptionParser, self).__setattr__(attr, value) + + if attr in self._options: + self._options[attr] = value + + return super(OptionParser, self).__setattr__(attr, value) + + def parse_args(self): + opts,args = self._optparse.parse_args() + + for key,val in opts.__dict__.iteritems(): + if val is not None or key not in self._options: + self._options[key] = val + + return args + + def usage(self, exitcode=None): + self._optparse.print_help() + if exitcode is not None: + sys.exit(exitcode) + -- cgit v1.2.3 From fc48d1dcf55d7195bf79cddb93dfd341a5fada7e Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 21:15:59 -0700 Subject: Add .m5 configuration directory --- src/python/SConscript | 1 + src/python/m5/config.py | 42 ++++++++++++++++++++++++++++++++++++++++++ src/python/m5/main.py | 1 + 3 files changed, 44 insertions(+) create mode 100644 src/python/m5/config.py (limited to 'src/python') diff --git a/src/python/SConscript b/src/python/SConscript index cca9217b0..32bab4526 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -36,6 +36,7 @@ Source('swig/pyobject.cc') PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/SimObject.py') +PySource('m5', 'm5/config.py') PySource('m5', 'm5/convert.py') PySource('m5', 'm5/event.py') PySource('m5', 'm5/main.py') diff --git a/src/python/m5/config.py b/src/python/m5/config.py new file mode 100644 index 000000000..7fb531a18 --- /dev/null +++ b/src/python/m5/config.py @@ -0,0 +1,42 @@ +# 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 + +import os +from os.path import isdir, isfile, join as joinpath + +homedir = os.environ['HOME'] +confdir = os.environ.get('M5_CONFIG', joinpath(homedir, '.m5')) +def get(name): + if not isdir(confdir): + return None + conffile = joinpath(confdir, name) + if not isfile(conffile): + return None + + return conffile + diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 8011c64b8..c4f26c472 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -33,6 +33,7 @@ import socket import sys from util import attrdict +import config import defines from options import OptionParser import traceflags -- cgit v1.2.3 From bbeb8082a56b765181b769c5e1f41e173c0444fa Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 21:16:00 -0700 Subject: main: add .m5/options.py processing. This file is processed before arguments are parsed so that they can change the default options for various config parameters. --- src/python/m5/main.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index c4f26c472..4f28cf385 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -122,6 +122,13 @@ def main(): import info import internal + # load the options.py config file to allow people to set their own + # default options + options_file = config.get('options.py') + if options_file: + scope = { 'options' : options } + execfile(options_file, scope) + arguments = options.parse_args() done = False -- cgit v1.2.3 From b2036bfda88aa99304e48f26541e5d84ada34db9 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 21:51:08 -0700 Subject: Command line option to print out List of SimObjects and their parameters --- src/python/m5/main.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 4f28cf385..dbabd9600 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -116,6 +116,11 @@ add_option("--trace-file", metavar="FILE", default="cout", add_option("--trace-ignore", metavar="EXPR", action='append', split=':', help="Ignore EXPR sim objects") +# Help options +set_group("Help Options") +add_option("--list-sim-objects", action='store_true', default=False, + help="List all built-in SimObjects, their parameters and default values") + def main(): import defines import event @@ -187,6 +192,27 @@ def main(): print_list(traceflags.compoundFlagMap[flag], indent=8) print + if options.list_sim_objects: + import SimObject + done = True + print "SimObjects:" + objects = SimObject.allClasses.keys() + objects.sort() + for name in objects: + obj = SimObject.allClasses[name] + print " %s" % obj + params = obj._params.keys() + params.sort() + for pname in params: + param = obj._params[pname] + default = getattr(param, 'default', '') + print " %s" % pname + if default: + print " default: %s" % default + print " desc: %s" % param.desc + print + print + if done: sys.exit(0) -- cgit v1.2.3 From 6dedc645f7f54df021e0aa9a5b48015f984a2e39 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 15 Jun 2008 20:56:35 -0700 Subject: add compile flags to m5 --- src/python/swig/core.i | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/python') diff --git a/src/python/swig/core.i b/src/python/swig/core.i index 567eff591..53d992ac6 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -39,12 +39,14 @@ #include "sim/startup.hh" extern const char *compileDate; +std::vector compileFlags(); extern const char *hgRev; extern const char *hgDate; %} %include "stdint.i" %include "std_string.i" +%include "std_vector.i" %include "sim/host.hh" void setOutputDir(const std::string &dir); @@ -52,7 +54,12 @@ void setOutputFile(const std::string &file); void SimStartup(); void doExitCleanup(); +%immutable compileDate; char *compileDate; + +namespace std { %template(StringVector) vector; } +std::vector compileFlags(); + char *hgRev; char *hgDate; -- cgit v1.2.3 From b429b1759defba2f8da1f894f6a3500e3f2c78d2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 15 Jun 2008 21:26:33 -0700 Subject: params: Prevent people from setting attributes on vector params. --- src/python/m5/params.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 938278541..9394b11e2 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -166,6 +166,10 @@ class ParamDesc(object): class VectorParamValue(list): __metaclass__ = MetaParamValue + def __setattr__(self, attr, value): + raise AttributeError, \ + "Not allowed to set %s on '%s'" % (attr, type(self).__name__) + def ini_str(self): return ' '.join([v.ini_str() for v in self]) -- cgit v1.2.3 From c1584e422783a33731c7dfa23517d30bcecf28bc Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 18 Jun 2008 12:07:15 -0700 Subject: imported patch sim_object_params.diff --- src/python/generate.py | 1 + src/python/m5/SimObject.py | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src/python') diff --git a/src/python/generate.py b/src/python/generate.py index e6c36ecd2..7b69ad876 100644 --- a/src/python/generate.py +++ b/src/python/generate.py @@ -300,6 +300,7 @@ class Generate(object): print >>out, code + print >>out, '%%include "src/sim/sim_object_params.hh"' % obj for obj in ordered_objs: print >>out, '%%include "params/%s.hh"' % obj diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 41ed3df9e..4cf0f7a3d 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -396,13 +396,21 @@ class MetaSimObject(type): code += '#include "enums/%s.hh"\n' % ptype.__name__ code += "\n\n" + code += cls.cxx_struct(base, params) + + # close #ifndef __PARAMS__* guard + code += "\n#endif\n" + return code + + def cxx_struct(cls, base, params): + if cls == SimObject: + return '#include "sim/sim_object_params.hh"\n' + # now generate the actual param struct - code += "struct %sParams" % cls + code = "struct %sParams" % cls if base: code += " : public %sParams" % base code += "\n{\n" - if cls == SimObject: - code += " virtual ~%sParams() {}\n" % cls if not hasattr(cls, 'abstract') or not cls.abstract: if 'type' in cls.__dict__: code += " %s create();\n" % cls.cxx_type @@ -411,8 +419,6 @@ class MetaSimObject(type): code += "".join([" %s\n" % d for d in decls]) code += "};\n" - # close #ifndef __PARAMS__* guard - code += "\n#endif\n" return code def cxx_type_decl(cls): @@ -483,7 +489,6 @@ class SimObject(object): type = 'SimObject' abstract = True - name = Param.String("Object name") swig_objdecls = [ '%include "python/swig/sim_object.i"' ] # Initialize new instance. For objects with SimObject-valued @@ -762,7 +767,7 @@ class SimObject(object): cc_params_struct = getattr(m5.objects.params, '%sParams' % self.type) cc_params = cc_params_struct() - cc_params.object = self + cc_params.pyobj = self cc_params.name = str(self) param_names = self._params.keys() -- cgit v1.2.3 From 57b5de6b9f9150ceda46c52b3621e60f667138d4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 24 Jun 2008 15:48:45 -0400 Subject: Checkpoinging/SWIG: Undo part of changeset 5464 since it broke checkpointing. --- src/python/swig/event.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/swig/event.i b/src/python/swig/event.i index ee1f3d00b..9a2093c99 100644 --- a/src/python/swig/event.i +++ b/src/python/swig/event.i @@ -44,8 +44,8 @@ void create(PyObject *object, Tick when); -class CountedDrainEvent -{ +class Event; +class CountedDrainEvent : public Event { public: void setCount(int _count); }; -- cgit v1.2.3 From 8c4f18f6f5e5dd9ccc4ef54590a11d70ba001264 Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Wed, 23 Jul 2008 14:41:33 -0700 Subject: RemoteGDB: add an m5 command line option for setting or disabling remote gdb. --- src/python/m5/main.py | 3 +++ src/python/swig/debug.i | 7 ++----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index dbabd9600..2bbd72152 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -102,6 +102,8 @@ add_option("--stats-file", metavar="FILE", default="m5stats.txt", set_group("Debugging Options") add_option("--debug-break", metavar="TIME[,TIME]", action='append', split=',', help="Cycle to create a breakpoint") +add_option("--remote-gdb-port", type='int', default=7000, + help="Remote gdb base port") # Tracing options set_group("Trace Options") @@ -256,6 +258,7 @@ def main(): internal.stats.initText(options.stats_file) # set debugging options + internal.debug.setRemoteGDBPort(options.remote_gdb_port) for when in options.debug_break: internal.debug.schedBreakCycle(int(when)) diff --git a/src/python/swig/debug.i b/src/python/swig/debug.i index b542e9f82..1084d6936 100644 --- a/src/python/swig/debug.i +++ b/src/python/swig/debug.i @@ -31,16 +31,13 @@ %module debug %{ -// include these files when compiling debug_wrap.cc #include "sim/host.hh" +#include "sim/debug.hh" %} %include "stdint.i" %include "sim/host.hh" - -%inline %{ -extern void schedBreakCycle(Tick when); -%} +%include "sim/debug.hh" %wrapper %{ // fix up module name to reflect the fact that it's inside the m5 package -- cgit v1.2.3 From 4b1e0d235df59059a686c992f284278f5bfda2ad Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 31 Jul 2008 08:01:38 -0700 Subject: scons: Get rid of generate.py in the build system. I decided that separating some of the scons code into generate.py was just a bad idea because it caused the dependency system to get all messed up. If separation is the right way to go in the future, we should probably use the sconscript mechanism, not the mechanism that I just removed. --- src/python/generate.py | 561 ------------------------------------------------- 1 file changed, 561 deletions(-) delete mode 100644 src/python/generate.py (limited to 'src/python') diff --git a/src/python/generate.py b/src/python/generate.py deleted file mode 100644 index 7b69ad876..000000000 --- a/src/python/generate.py +++ /dev/null @@ -1,561 +0,0 @@ -# Copyright (c) 2004-2006 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 - -import imp -import py_compile -import sys -import zipfile - -from os.path import basename, exists, isdir, join - -class DictImporter(object): - '''This importer takes a dictionary of arbitrary module names that - map to arbitrary filenames.''' - def __init__(self, modules, build_env): - self.modules = modules - self.installed = set() - self.build_env = build_env - - def __del__(self): - self.unload() - - def unload(self): - import sys - for module in self.installed: - del sys.modules[module] - self.installed = set() - - def find_module(self, fullname, path): - if fullname == '__scons': - return self - - if fullname == 'm5.objects': - return self - - if fullname.startswith('m5.internal'): - return None - - if fullname in self.modules and exists(self.modules[fullname]): - return self - - return None - - def load_module(self, fullname): - mod = imp.new_module(fullname) - sys.modules[fullname] = mod - self.installed.add(fullname) - - mod.__loader__ = self - if fullname == 'm5.objects': - mod.__path__ = fullname.split('.') - return mod - - if fullname == '__scons': - mod.__dict__['m5_build_env'] = self.build_env - return mod - - srcfile = self.modules[fullname] - if basename(srcfile) == '__init__.py': - mod.__path__ = fullname.split('.') - mod.__file__ = srcfile - - exec file(srcfile, 'r') in mod.__dict__ - - return mod - -class ordered_dict(dict): - def keys(self): - keys = super(ordered_dict, self).keys() - keys.sort() - return keys - - def values(self): - return [ self[key] for key in self.keys() ] - - def items(self): - return [ (key,self[key]) for key in self.keys() ] - - def iterkeys(self): - for key in self.keys(): - yield key - - def itervalues(self): - for value in self.values(): - yield value - - def iteritems(self): - for key,value in self.items(): - yield key, value - -class Generate(object): - def __init__(self, py_sources, sim_objects, build_env): - self.py_sources = py_sources - self.py_modules = {} - for source in py_sources: - self.py_modules[source.modpath] = source.srcpath - - importer = DictImporter(self.py_modules, build_env) - - # install the python importer so we can grab stuff from the source - # tree itself. - sys.meta_path[0:0] = [ importer ] - - import m5 - self.m5 = m5 - - # import all sim objects so we can populate the all_objects list - # make sure that we're working with a list, then let's sort it - sim_objects = list(sim_objects) - sim_objects.sort() - for simobj in sim_objects: - exec('from m5.objects import %s' % simobj) - - # we need to unload all of the currently imported modules so that they - # will be re-imported the next time the sconscript is run - importer.unload() - sys.meta_path.remove(importer) - - self.sim_objects = m5.SimObject.allClasses - self.enums = m5.params.allEnums - - self.params = {} - for name,obj in self.sim_objects.iteritems(): - for param in obj._params.local.values(): - if not hasattr(param, 'swig_decl'): - continue - pname = param.ptype_str - if pname not in self.params: - self.params[pname] = param - - def createSimObjectParam(self, target, source, env): - assert len(target) == 1 and len(source) == 1 - - hh_file = file(target[0].abspath, 'w') - name = str(source[0].get_contents()) - obj = self.sim_objects[name] - - print >>hh_file, obj.cxx_decl() - - # Generate Python file containing a dict specifying the current - # build_env flags. - def makeDefinesPyFile(self, target, source, env): - f = file(str(target[0]), 'w') - print >>f, "m5_build_env = ", source[0] - f.close() - - # Generate python file containing info about the M5 source code - def makeInfoPyFile(self, target, source, env): - f = file(str(target[0]), 'w') - for src in source: - data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) - print >>f, "%s = %s" % (src, repr(data)) - f.close() - - # Generate the __init__.py file for m5.objects - def makeObjectsInitFile(self, target, source, env): - f = file(str(target[0]), 'w') - print >>f, 'from params import *' - print >>f, 'from m5.SimObject import *' - for module in source: - print >>f, 'from %s import *' % module.get_contents() - f.close() - - def createSwigParam(self, target, source, env): - assert len(target) == 1 and len(source) == 1 - - i_file = file(target[0].abspath, 'w') - name = str(source[0].get_contents()) - param = self.params[name] - - for line in param.swig_decl(): - print >>i_file, line - - def createEnumStrings(self, target, source, env): - assert len(target) == 1 and len(source) == 1 - - cc_file = file(target[0].abspath, 'w') - name = str(source[0].get_contents()) - obj = self.enums[name] - - print >>cc_file, obj.cxx_def() - cc_file.close() - - def createEnumParam(self, target, source, env): - assert len(target) == 1 and len(source) == 1 - - hh_file = file(target[0].abspath, 'w') - name = str(source[0].get_contents()) - obj = self.enums[name] - - print >>hh_file, obj.cxx_decl() - - def buildParams(self, target, source, env): - names = [ s.get_contents() for s in source ] - objs = [ self.sim_objects[name] for name in names ] - out = file(target[0].abspath, 'w') - - ordered_objs = [] - obj_seen = set() - def order_obj(obj): - name = str(obj) - if name in obj_seen: - return - - obj_seen.add(name) - if str(obj) != 'SimObject': - order_obj(obj.__bases__[0]) - - ordered_objs.append(obj) - - for obj in objs: - order_obj(obj) - - enums = set() - predecls = [] - pd_seen = set() - - def add_pds(*pds): - for pd in pds: - if pd not in pd_seen: - predecls.append(pd) - pd_seen.add(pd) - - for obj in ordered_objs: - params = obj._params.local.values() - for param in params: - ptype = param.ptype - if issubclass(ptype, self.m5.params.Enum): - if ptype not in enums: - enums.add(ptype) - pds = param.swig_predecls() - if isinstance(pds, (list, tuple)): - add_pds(*pds) - else: - add_pds(pds) - - print >>out, '%module params' - - print >>out, '%{' - for obj in ordered_objs: - print >>out, '#include "params/%s.hh"' % obj - print >>out, '%}' - - for pd in predecls: - print >>out, pd - - enums = list(enums) - enums.sort() - for enum in enums: - print >>out, '%%include "enums/%s.hh"' % enum.__name__ - print >>out - - for obj in ordered_objs: - if obj.swig_objdecls: - for decl in obj.swig_objdecls: - print >>out, decl - continue - - code = '' - base = obj.get_base() - - code += '// stop swig from creating/wrapping default ctor/dtor\n' - code += '%%nodefault %s;\n' % obj.cxx_class - code += 'class %s ' % obj.cxx_class - if base: - code += ': public %s' % base - code += ' {};\n' - - klass = obj.cxx_class; - if hasattr(obj, 'cxx_namespace'): - new_code = 'namespace %s {\n' % obj.cxx_namespace - new_code += code - new_code += '}\n' - code = new_code - klass = '%s::%s' % (obj.cxx_namespace, klass) - - print >>out, code - - print >>out, '%%include "src/sim/sim_object_params.hh"' % obj - for obj in ordered_objs: - print >>out, '%%include "params/%s.hh"' % obj - - def makeSwigInit(self, target, source, env): - f = file(str(target[0]), 'w') - print >>f, 'extern "C" {' - for module in source: - print >>f, ' void init_%s();' % module.get_contents() - print >>f, '}' - print >>f, 'void init_swig() {' - for module in source: - print >>f, ' init_%s();' % module.get_contents() - print >>f, '}' - f.close() - - def compilePyFile(self, target, source, env): - '''Action function to compile a .py into a .pyc''' - py_compile.compile(str(source[0]), str(target[0])) - - def buildPyZip(self, target, source, env): - '''Action function to build the zip archive. Uses the - PyZipFile module included in the standard Python library.''' - - py_compiled = {} - for s in self.py_sources: - compname = str(s.compiled) - assert compname not in py_compiled - py_compiled[compname] = s - - zf = zipfile.ZipFile(str(target[0]), 'w') - for s in source: - zipname = str(s) - arcname = py_compiled[zipname].arcname - zf.write(zipname, arcname) - zf.close() - - def traceFlagsPy(self, target, source, env): - assert(len(target) == 1) - - f = file(str(target[0]), 'w') - - allFlags = [] - for s in source: - val = eval(s.get_contents()) - allFlags.append(val) - - print >>f, 'baseFlags = [' - for flag, compound, desc in allFlags: - if not compound: - print >>f, " '%s'," % flag - print >>f, " ]" - print >>f - - print >>f, 'compoundFlags = [' - print >>f, " 'All'," - for flag, compound, desc in allFlags: - if compound: - print >>f, " '%s'," % flag - print >>f, " ]" - print >>f - - print >>f, "allFlags = frozenset(baseFlags + compoundFlags)" - print >>f - - print >>f, 'compoundFlagMap = {' - all = tuple([flag for flag,compound,desc in allFlags if not compound]) - print >>f, " 'All' : %s," % (all, ) - for flag, compound, desc in allFlags: - if compound: - print >>f, " '%s' : %s," % (flag, compound) - print >>f, " }" - print >>f - - print >>f, 'flagDescriptions = {' - print >>f, " 'All' : 'All flags'," - for flag, compound, desc in allFlags: - print >>f, " '%s' : '%s'," % (flag, desc) - print >>f, " }" - - f.close() - - def traceFlagsCC(self, target, source, env): - assert(len(target) == 1) - - f = file(str(target[0]), 'w') - - allFlags = [] - for s in source: - val = eval(s.get_contents()) - allFlags.append(val) - - # file header - print >>f, ''' -/* - * DO NOT EDIT THIS FILE! Automatically generated - */ - -#include "base/traceflags.hh" - -using namespace Trace; - -const char *Trace::flagStrings[] = -{''' - - # The string array is used by SimpleEnumParam to map the strings - # provided by the user to enum values. - for flag, compound, desc in allFlags: - if not compound: - print >>f, ' "%s",' % flag - - print >>f, ' "All",' - for flag, compound, desc in allFlags: - if compound: - print >>f, ' "%s",' % flag - - print >>f, '};' - print >>f - print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1) - print >>f - - # - # Now define the individual compound flag arrays. There is an array - # for each compound flag listing the component base flags. - # - all = tuple([flag for flag,compound,desc in allFlags if not compound]) - print >>f, 'static const Flags AllMap[] = {' - for flag, compound, desc in allFlags: - if not compound: - print >>f, " %s," % flag - print >>f, '};' - print >>f - - for flag, compound, desc in allFlags: - if not compound: - continue - print >>f, 'static const Flags %sMap[] = {' % flag - for flag in compound: - print >>f, " %s," % flag - print >>f, " (Flags)-1" - print >>f, '};' - print >>f - - # - # Finally the compoundFlags[] array maps the compound flags - # to their individual arrays/ - # - print >>f, 'const Flags *Trace::compoundFlags[] =' - print >>f, '{' - print >>f, ' AllMap,' - for flag, compound, desc in allFlags: - if compound: - print >>f, ' %sMap,' % flag - # file trailer - print >>f, '};' - - f.close() - - def traceFlagsHH(self, target, source, env): - assert(len(target) == 1) - - f = file(str(target[0]), 'w') - - allFlags = [] - for s in source: - val = eval(s.get_contents()) - allFlags.append(val) - - # file header boilerplate - print >>f, ''' -/* - * DO NOT EDIT THIS FILE! - * - * Automatically generated from traceflags.py - */ - -#ifndef __BASE_TRACE_FLAGS_HH__ -#define __BASE_TRACE_FLAGS_HH__ - -namespace Trace { - -enum Flags {''' - - # Generate the enum. Base flags come first, then compound flags. - idx = 0 - for flag, compound, desc in allFlags: - if not compound: - print >>f, ' %s = %d,' % (flag, idx) - idx += 1 - - numBaseFlags = idx - print >>f, ' NumFlags = %d,' % idx - - # put a comment in here to separate base from compound flags - print >>f, ''' -// The remaining enum values are *not* valid indices for Trace::flags. -// They are "compound" flags, which correspond to sets of base -// flags, and are used by changeFlag.''' - - print >>f, ' All = %d,' % idx - idx += 1 - for flag, compound, desc in allFlags: - if compound: - print >>f, ' %s = %d,' % (flag, idx) - idx += 1 - - numCompoundFlags = idx - numBaseFlags - print >>f, ' NumCompoundFlags = %d' % numCompoundFlags - - # trailer boilerplate - print >>f, '''\ -}; // enum Flags - -// Array of strings for SimpleEnumParam -extern const char *flagStrings[]; -extern const int numFlagStrings; - -// Array of arraay pointers: for each compound flag, gives the list of -// base flags to set. Inidividual flag arrays are terminated by -1. -extern const Flags *compoundFlags[]; - -/* namespace Trace */ } - -#endif // __BASE_TRACE_FLAGS_HH__ -''' - - f.close() - - def programInfo(self, target, source, env): - def gen_file(target, rev, node, date): - pi_stats = file(target, 'w') - print >>pi_stats, 'const char *hgRev = "%s:%s";' % (rev, node) - print >>pi_stats, 'const char *hgDate = "%s";' % date - pi_stats.close() - - target = str(target[0]) - scons_dir = str(source[0].get_contents()) - try: - import mercurial.demandimport, mercurial.hg, mercurial.ui - import mercurial.util, mercurial.node - if not exists(scons_dir) or not isdir(scons_dir) or \ - not exists(join(scons_dir, ".hg")): - raise ValueError - repo = mercurial.hg.repository(mercurial.ui.ui(), scons_dir) - rev = mercurial.node.nullrev + repo.changelog.count() - changenode = repo.changelog.node(rev) - changes = repo.changelog.read(changenode) - date = mercurial.util.datestr(changes[2]) - - gen_file(target, rev, mercurial.node.hex(changenode), date) - - mercurial.demandimport.disable() - except ImportError: - gen_file(target, "Unknown", "Unknown", "Unknown") - - except: - print "in except" - gen_file(target, "Unknown", "Unknown", "Unknown") - mercurial.demandimport.disable() -- cgit v1.2.3 From ede89c2d541051c2ed647e2967712e10b3c0fab0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 3 Aug 2008 18:19:54 -0700 Subject: libm5: Create a libm5 static library for embedding m5. This should allow m5 to be more easily embedded into other simulators. The m5 binary adds a simple main function which then calls into the m5 libarary to start the simulation. In order to make this work correctly, it was necessary embed python code directly into the library instead of the zipfile hack. This is because you can't just append the zipfile to the end of a library the way you can a binary. As a result, Python files that are part of the m5 simulator are now compile, marshalled, compressed, and then inserted into the library's data section with a certain symbol name. Additionally, a new Importer was needed to allow python to get at the embedded python code. Small additional changes include: - Get rid of the PYTHONHOME stuff since I don't think anyone ever used it, and it just confuses things. Easy enough to add back if I'm wrong. - Create a few new functions that are key to initializing and running the simulator: initSignals, initM5Python, m5Main. The original code for creating libm5 was inspired by a patch Michael Adler, though the code here was done by me. --- src/python/SConscript | 1 + src/python/importer.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++ src/python/m5/__init__.py | 2 +- src/python/swig/init.hh | 36 --------------------- 4 files changed, 82 insertions(+), 37 deletions(-) create mode 100644 src/python/importer.py delete mode 100644 src/python/swig/init.hh (limited to 'src/python') diff --git a/src/python/SConscript b/src/python/SConscript index 32bab4526..94119c77d 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -34,6 +34,7 @@ Import('*') Source('swig/pyevent.cc') Source('swig/pyobject.cc') +PySource('', 'importer.py') PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/SimObject.py') PySource('m5', 'm5/config.py') diff --git a/src/python/importer.py b/src/python/importer.py new file mode 100644 index 000000000..fe099fdb8 --- /dev/null +++ b/src/python/importer.py @@ -0,0 +1,80 @@ +# 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 + +# Simple importer that allows python to import data from a dict of +# code objects. The keys are the module path, and the items are the +# filename and bytecode of the file. +class CodeImporter(object): + def __init__(self): + self.modules = {} + + def add_module(self, filename, modpath, code): + if modpath in self.modules: + raise AttributeError, "%s already found in importer" + + self.modules[modpath] = (filename, code) + + def find_module(self, fullname, path): + if fullname in self.modules: + return self + + return None + + def load_module(self, fullname): + # Because the importer is created and initialized in its own + # little sandbox (in init.cc), the globals that were available + # when the importer module was loaded and CodeImporter was + # defined are not available when load_module is actually + # called. Soooo, the imports must live here. + import imp + import os + import sys + mod = imp.new_module(fullname) + sys.modules[fullname] = mod + + try: + mod.__loader__ = self + srcfile,code = self.modules[fullname] + if os.path.basename(srcfile) == '__init__.py': + mod.__path__ = fullname.split('.') + mod.__file__ = srcfile + + exec code in mod.__dict__ + except Exception: + del sys.modules[fullname] + raise + + return mod + +# Create an importer and add it to the meta_path so future imports can +# use it. There's currently nothing in the importer, but calls to +# add_module can be used to add code. +import sys +importer = CodeImporter() +add_module = importer.add_module +sys.meta_path.append(importer) diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index f21bb362e..7b071bccd 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -91,7 +91,7 @@ else: if running_m5: from event import * from simulate import * - from main import options + from main import options, main import stats import SimObject diff --git a/src/python/swig/init.hh b/src/python/swig/init.hh deleted file mode 100644 index 23d2c19a9..000000000 --- a/src/python/swig/init.hh +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2006 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 __PYTHON_SWIG_INIT_HH__ -#define __PYTHON_SWIG_INIT_HH__ - -void init_swig(); - -#endif // __PYTHON_SWIG_INIT_HH__ -- cgit v1.2.3 From 50ef39af82413ef463609f24173b22af13fad268 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 3 Aug 2008 18:19:55 -0700 Subject: sockets: Add a function to disable all listening sockets. When invoking several copies of m5 on the same machine at the same time, there can be a race for TCP ports for the terminal connections or remote gdb. Expose a function to disable those ports, and have the regression scripts disable them. There are some SimObjects that have no other function than to be used with ports (NativeTrace and EtherTap), so they will panic if the ports are disabled. --- src/python/m5/simulate.py | 2 ++ src/python/swig/core.i | 3 +++ 2 files changed, 5 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index 3d91da368..e4dbd5784 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -182,3 +182,5 @@ def switchCpus(cpuList): for old_cpu, new_cpu in cpuList: new_cpu.takeOverFrom(old_cpu) + +from internal.core import disableAllListeners diff --git a/src/python/swig/core.i b/src/python/swig/core.i index 53d992ac6..3d360c017 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -34,6 +34,7 @@ %{ #include "python/swig/pyobject.hh" +#include "base/socket.hh" #include "sim/core.hh" #include "sim/host.hh" #include "sim/startup.hh" @@ -42,6 +43,7 @@ extern const char *compileDate; std::vector compileFlags(); extern const char *hgRev; extern const char *hgDate; +inline void disableAllListeners() { ListenSocket::disableAll(); } %} %include "stdint.i" @@ -53,6 +55,7 @@ void setOutputDir(const std::string &dir); void setOutputFile(const std::string &file); void SimStartup(); void doExitCleanup(); +void disableAllListeners(); %immutable compileDate; char *compileDate; -- cgit v1.2.3 From fe8aeff362844838c60ff31e444573fb7e9a7793 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 4 Aug 2008 00:40:31 -0400 Subject: Add -r/-e options to redirect stdout/stderr. Better than using shell since it automatically uses -d directory for output files (creating it as needed). --- src/python/m5/main.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 2bbd72152..c9b1940dc 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -82,6 +82,14 @@ add_option('-N', "--release-notes", action="store_true", default=False, # Options for configuring the base simulator add_option('-d', "--outdir", metavar="DIR", default=".", help="Set the output directory to DIR [Default: %default]") +add_option('-r', "--redirect-stdout", action="store_true", default=False, + help="Redirect stdout (& stderr, without -e) to file") +add_option('-e', "--redirect-stderr", action="store_true", default=False, + help="Redirect stderr to file") +add_option("--stdout-file", metavar="FILE", default="simout", + help="Filename for -r redirection [Default: %default]") +add_option("--stderr-file", metavar="FILE", default="simerr", + help="Filename for -e redirection [Default: %default]") add_option('-i', "--interactive", action="store_true", default=False, help="Invoke the interactive interpreter after running the script") add_option("--pdb", action="store_true", default=False, @@ -138,6 +146,33 @@ def main(): arguments = options.parse_args() + if not os.path.isdir(options.outdir): + os.makedirs(options.outdir) + + # These filenames are used only if the redirect_std* options are set + stdout_file = os.path.join(options.outdir, options.stdout_file) + stderr_file = os.path.join(options.outdir, options.stderr_file) + + # Print redirection notices here before doing any redirection + if options.redirect_stdout and not options.redirect_stderr: + print "Redirecting stdout and stderr to", stdout_file + else: + if options.redirect_stdout: + print "Redirecting stdout to", stdout_file + if options.redirect_stderr: + print "Redirecting stderr to", stderr_file + + # Now redirect stdout/stderr as desired + if options.redirect_stdout: + redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) + os.dup2(redir_fd, sys.stdout.fileno()) + if not options.redirect_stderr: + os.dup2(redir_fd, sys.stderr.fileno()) + + if options.redirect_stderr: + redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) + os.dup2(redir_fd, sys.stderr.fileno()) + done = False if options.build_info: -- cgit v1.2.3 From 58c63ea8b1f56dd0c33ef3d36f5c6a58ce3f28fe Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 4 Aug 2008 01:45:12 -0400 Subject: Get rid of outputStream... wasn't really being used (except for warn()) and new -r/-e options make it not worth fixing. --- src/python/swig/core.i | 1 - 1 file changed, 1 deletion(-) (limited to 'src/python') diff --git a/src/python/swig/core.i b/src/python/swig/core.i index 3d360c017..b0773ca68 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -52,7 +52,6 @@ inline void disableAllListeners() { ListenSocket::disableAll(); } %include "sim/host.hh" void setOutputDir(const std::string &dir); -void setOutputFile(const std::string &file); void SimStartup(); void doExitCleanup(); void disableAllListeners(); -- cgit v1.2.3 From 3448a122085797a902e776f47bfe69a078bfca5e Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 4 Aug 2008 01:46:46 -0400 Subject: Make time format in 'started' line same as 'compiled'. Also make -B output consistent with normal header, and only include actual build options. --- src/python/m5/main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index c9b1940dc..1e217715c 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -180,8 +180,8 @@ def main(): print 'Build information:' print print 'compiled %s' % internal.core.cvar.compileDate; - print 'started %s' % datetime.datetime.now().ctime() - print 'executing on %s' % socket.gethostname() + print "revision %s" % internal.core.cvar.hgRev + print "commit date %s" % internal.core.cvar.hgDate print 'build options:' keys = defines.m5_build_env.keys() keys.sort() @@ -263,12 +263,12 @@ def main(): print brief_copyright print print "M5 compiled %s" % internal.core.cvar.compileDate; - print "M5 started %s" % datetime.datetime.now().ctime() - print "M5 executing on %s" % socket.gethostname() - print "M5 revision %s" % internal.core.cvar.hgRev print "M5 commit date %s" % internal.core.cvar.hgDate + print "M5 started %s" % datetime.datetime.now().strftime("%b %e %Y %X") + print "M5 executing on %s" % socket.gethostname() + print "command line:", for argv in sys.argv: print argv, -- cgit v1.2.3 From 3a3e356f4e61e86f6f1427dd85cf1e41fa9125c0 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 10 Sep 2008 14:26:15 -0400 Subject: style: Remove non-leading tabs everywhere they shouldn't be. Developers should configure their editors to not insert tabs --- src/python/m5/SimObject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 4cf0f7a3d..64f4ec5af 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -729,7 +729,7 @@ class SimObject(object): self._children[child].unproxy_all() def print_ini(self, ini_file): - print >>ini_file, '[' + self.path() + ']' # .ini section header + print >>ini_file, '[' + self.path() + ']' # .ini section header instanceDict[self.path()] = self @@ -756,7 +756,7 @@ class SimObject(object): if port != None: print >>ini_file, '%s=%s' % (port_name, port.ini_str()) - print >>ini_file # blank line between objects + print >>ini_file # blank line between objects for child in child_names: self._children[child].print_ini(ini_file) -- cgit v1.2.3 From 7bf6a219db91406df91d4e9323b47e6d70ed73fb Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 29 Sep 2008 23:30:14 -0700 Subject: Make overriding port assignments in Python work, and print better error messages when it doesn't. --- src/python/m5/params.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 9394b11e2..081bd342e 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1004,6 +1004,7 @@ class PortRef(object): if self.peer and not proxy.isproxy(self.peer): print "warning: overwriting port", self, \ "value", self.peer, "with", other + self.peer.peer = None self.peer = other if proxy.isproxy(other): other.set_param_desc(PortParamDesc()) @@ -1046,6 +1047,8 @@ class PortRef(object): if self.ccConnected: # already done this return peer = self.peer + if not self.peer: # nothing to connect to + return connectPorts(self.simobj.getCCObject(), self.name, self.index, peer.simobj.getCCObject(), peer.name, peer.index) self.ccConnected = True -- cgit v1.2.3 From 6b2bb53fd6e59dee0c5524029c9422e2885d00d2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 6 Oct 2008 09:31:51 -0700 Subject: python: cleanup options parsing stuff so that it properly deals with defaults. While we're at it, make it possible to run main.py in a somewhat standalone mode again so that we can test things without compiling. --- src/python/m5/main.py | 57 +++++++++++++++++++++++++++++------------------- src/python/m5/options.py | 39 +++++++++++++++------------------ 2 files changed, 52 insertions(+), 44 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 1e217715c..66a422efa 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -34,9 +34,7 @@ import sys from util import attrdict import config -import defines from options import OptionParser -import traceflags __all__ = [ 'options', 'arguments', 'main' ] @@ -132,7 +130,6 @@ add_option("--list-sim-objects", action='store_true', default=False, help="List all built-in SimObjects, their parameters and default values") def main(): - import defines import event import info import internal @@ -176,6 +173,8 @@ def main(): done = False if options.build_info: + import defines + done = True print 'Build information:' print @@ -217,6 +216,8 @@ def main(): print if options.trace_help: + import traceflags + done = True print "Base Flags:" print_list(traceflags.baseFlags, indent=4) @@ -297,27 +298,30 @@ def main(): for when in options.debug_break: internal.debug.schedBreakCycle(int(when)) - on_flags = [] - off_flags = [] - for flag in options.trace_flags: - off = False - if flag.startswith('-'): - flag = flag[1:] - off = True - if flag not in traceflags.allFlags: - print >>sys.stderr, "invalid trace flag '%s'" % flag - sys.exit(1) - - if off: - off_flags.append(flag) - else: - on_flags.append(flag) + if options.trace_flags: + import traceflags + + on_flags = [] + off_flags = [] + for flag in options.trace_flags: + off = False + if flag.startswith('-'): + flag = flag[1:] + off = True + if flag not in traceflags.allFlags: + print >>sys.stderr, "invalid trace flag '%s'" % flag + sys.exit(1) - for flag in on_flags: - internal.trace.set(flag) + if off: + off_flags.append(flag) + else: + on_flags.append(flag) - for flag in off_flags: - internal.trace.clear(flag) + for flag in on_flags: + internal.trace.set(flag) + + for flag in off_flags: + internal.trace.clear(flag) if options.trace_start: def enable_trace(): @@ -358,7 +362,14 @@ def main(): if __name__ == '__main__': from pprint import pprint - parse_args() + # load the options.py config file to allow people to set their own + # default options + options_file = config.get('options.py') + if options_file: + scope = { 'options' : options } + execfile(options_file, scope) + + arguments = options.parse_args() print 'opts:' pprint(options, indent=4) diff --git a/src/python/m5/options.py b/src/python/m5/options.py index 50eea429c..1f534a314 100644 --- a/src/python/m5/options.py +++ b/src/python/m5/options.py @@ -28,7 +28,6 @@ import optparse import sys -import util from optparse import * @@ -45,19 +44,20 @@ class splitter(object): else: dest.extend(values) -class OptionParser(object): +class OptionParser(dict): def __init__(self, *args, **kwargs): kwargs.setdefault('formatter', optparse.TitledHelpFormatter()) self._optparse = optparse.OptionParser(*args, **kwargs) self._optparse.disable_interspersed_args() self._allopts = {} - self._defaults = {} - self._options = util.attrdict() # current option group self._group = self._optparse + def set_defaults(self, *args, **kwargs): + return self._optparse.set_defaults(*args, **kwargs) + def set_group(self, *args, **kwargs): '''set the current option group''' if not args and not kwargs: @@ -78,16 +78,11 @@ class OptionParser(object): kwargs['action'] = 'callback' kwargs['callback'] = splitter(split) - default = kwargs.pop('default', nodefault) option = self._group.add_option(*args, **kwargs) dest = option.dest if dest not in self._allopts: self._allopts[dest] = option - if default != nodefault: - if dest not in self._options: - self._options[dest] = default - return option def bool_option(self, name, default, help): @@ -113,28 +108,30 @@ class OptionParser(object): def __getattr__(self, attr): if attr.startswith('_'): - return super(OptionParser, self).__getattr__(attr) + return super(OptionParser, self).__getattribute__(attr) - if attr in self._options: - return self._options[attr] + if attr in self: + return self[attr] - raise AttributeError, "Option %s not found" % attr + return super(OptionParser, self).__getattribute__(attr) def __setattr__(self, attr, value): if attr.startswith('_'): - return super(OptionParser, self).__setattr__(attr, value) - - if attr in self._options: - self._options[attr] = value - - return super(OptionParser, self).__setattr__(attr, value) + super(OptionParser, self).__setattr__(attr, value) + elif attr in self._allopts: + defaults = { attr : value } + self.set_defaults(**defaults) + if attr in self: + self[attr] = value + else: + super(OptionParser, self).__setattr__(attr, value) def parse_args(self): opts,args = self._optparse.parse_args() for key,val in opts.__dict__.iteritems(): - if val is not None or key not in self._options: - self._options[key] = val + if val is not None or key not in self: + self[key] = val return args -- cgit v1.2.3 From 68c75c589b2e006292f623bd6428754d7d590f01 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:23 -0700 Subject: pdb: Try to make pdb work better. I've done a few things here. First, I invoke the script a little bit differently so that pdb doesn't get confused. Second, I've stored the actual filename in the module's __file__ so that pdb can find the source file on your machine. --- src/python/m5/main.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 66a422efa..1f9a21899 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -338,7 +338,10 @@ def main(): sys.argv = arguments sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path - scope = { '__file__' : sys.argv[0], + filename = sys.argv[0] + filedata = file(filename, 'r').read() + filecode = compile(filedata, filename, 'exec') + scope = { '__file__' : filename, '__name__' : '__m5_main__' } # we want readline if we're doing anything interactive @@ -348,11 +351,24 @@ def main(): # if pdb was requested, execfile the thing under pdb, otherwise, # just do the execfile normally if options.pdb: - from pdb import Pdb - debugger = Pdb() - debugger.run('execfile("%s")' % sys.argv[0], scope) + import pdb + import traceback + + pdb = pdb.Pdb() + try: + pdb.run(filecode, scope) + except SystemExit: + print "The program exited via sys.exit(). Exit status: ", + print sys.exc_info()[1] + except: + traceback.print_exc() + print "Uncaught exception. Entering post mortem debugging" + t = sys.exc_info()[2] + while t.tb_next is not None: + t = t.tb_next + pdb.interaction(t.tb_frame,t) else: - execfile(sys.argv[0], scope) + exec filecode in scope # once the script is done if options.interactive: -- cgit v1.2.3 From 8291d9db0a0bdeecb2a13f28962893ed3659230e Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:23 -0700 Subject: eventq: Major API change for the Event and EventQueue structures. Since the early days of M5, an event needed to know which event queue it was on, and that data was required at the time of construction of the event object. In the future parallelized M5, this sort of requirement does not work well since the proper event queue will not always be known at the time of construction of an event. Now, events are created, and the EventQueue itself has the schedule function, e.g. eventq->schedule(event, when). To simplify the syntax, I created a class called EventManager which holds a pointer to an EventQueue and provides the schedule interface that is a proxy for the EventQueue. The intent is that objects that frequently schedule events can be derived from EventManager and then they have the schedule interface. SimObject and Port are examples of objects that will become EventManagers. The end result is that any SimObject can just call schedule(event, when) and it will just call that SimObject's eventq->schedule function. Of course, some objects may have more than one EventQueue, so this interface might not be perfect for those, but they should be relatively few. --- src/python/m5/event.py | 33 ++++++++++++++++++++++++--------- src/python/swig/event.i | 26 ++++++++++++++------------ src/python/swig/pyevent.cc | 38 +++++++++++++++++++++++++++++++++++--- src/python/swig/pyevent.hh | 28 +++------------------------- 4 files changed, 76 insertions(+), 49 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/event.py b/src/python/m5/event.py index 2d6497464..5d50448e7 100644 --- a/src/python/m5/event.py +++ b/src/python/m5/event.py @@ -26,17 +26,32 @@ # # Authors: Nathan Binkert -from internal.event import create -from internal.event import SimLoopExitEvent as SimExit +import internal.event -class ProgressEvent(object): - def __init__(self, period): - self.period = int(period) - self.schedule() +from internal.event import PythonEvent, SimLoopExitEvent as SimExit + +mainq = internal.event.cvar.mainEventQueue + +def create(obj, priority=None): + if priority is None: + priority = internal.event.Event.Default_Pri + return internal.event.PythonEvent(obj, priority) - def schedule(self): - create(self, m5.curTick() + self.period) +class Event(PythonEvent): + def __init__(self, priority=None): + if priority is None: + priority = internal.event.Event.Default_Pri + super(PythonEvent, self).__init__(self, priority) + +class ProgressEvent(Event): + def __init__(self, eventq, period): + super(ProgressEvent, self).__init__() + self.period = int(period) + self.eventq = eventq + self.eventq.schedule(self, m5.curTick() + self.period) def __call__(self): print "Progress! Time now %fs" % (m5.curTick()/1e12) - self.schedule() + self.eventq.schedule(self, m5.curTick() + self.period) + +__all__ = [ 'create', 'Event', 'ProgressEvent', 'SimExit', 'mainq' ] diff --git a/src/python/swig/event.i b/src/python/swig/event.i index 9a2093c99..10d75d2de 100644 --- a/src/python/swig/event.i +++ b/src/python/swig/event.i @@ -32,34 +32,36 @@ %{ #include "python/swig/pyevent.hh" - +#include "sim/host.hh" +#include "sim/eventq.hh" #include "sim/sim_events.hh" #include "sim/sim_exit.hh" #include "sim/simulate.hh" %} +#pragma SWIG nowarn=350,351 + +%import "base/fast_alloc.hh" +%import "sim/serialize.hh" + %include "stdint.i" %include "std_string.i" %include "sim/host.hh" +%include "sim/eventq.hh" +%include "python/swig/pyevent.hh" -void create(PyObject *object, Tick when); - -class Event; -class CountedDrainEvent : public Event { - public: +struct CountedDrainEvent : public Event +{ void setCount(int _count); }; -CountedDrainEvent *createCountedDrain(); -void cleanupCountedDrain(Event *drain_event); - // minimal definition of SimExitEvent interface to wrap -class SimLoopExitEvent { +class SimLoopExitEvent : public Event +{ public: std::string getCause(); int getCode(); - SimLoopExitEvent(EventQueue *q, Tick _when, Tick _repeat, - const std::string &_cause, int c = 0); + SimLoopExitEvent(const std::string &_cause, int c, Tick _repeat = 0); }; %exception simulate { diff --git a/src/python/swig/pyevent.cc b/src/python/swig/pyevent.cc index 7f23b8874..bf993bc3e 100644 --- a/src/python/swig/pyevent.cc +++ b/src/python/swig/pyevent.cc @@ -33,8 +33,8 @@ #include "python/swig/pyevent.hh" #include "sim/async.hh" -PythonEvent::PythonEvent(PyObject *obj, Tick when, Priority priority) - : Event(&mainEventQueue, priority), object(obj) +PythonEvent::PythonEvent(PyObject *obj, Priority priority) + : Event(priority), object(obj) { if (object == NULL) panic("Passed in invalid object"); @@ -42,7 +42,6 @@ PythonEvent::PythonEvent(PyObject *obj, Tick when, Priority priority) Py_INCREF(object); setFlags(AutoDelete); - schedule(when); } PythonEvent::~PythonEvent() @@ -67,3 +66,36 @@ PythonEvent::process() async_exception = true; } } + +Event * +createCountedDrain() +{ + return new CountedDrainEvent(); +} + +void +cleanupCountedDrain(Event *counted_drain) +{ + CountedDrainEvent *event = + dynamic_cast(counted_drain); + if (event == NULL) { + fatal("Called cleanupCountedDrain() on an event that was not " + "a CountedDrainEvent."); + } + assert(event->getCount() == 0); + delete event; +} + +#if 0 +Event * +create(PyObject *object, Event::Priority priority) +{ + return new PythonEvent(object, priority); +} + +void +destroy(Event *event) +{ + delete event; +} +#endif diff --git a/src/python/swig/pyevent.hh b/src/python/swig/pyevent.hh index 65e80e9e4..c6d6ac993 100644 --- a/src/python/swig/pyevent.hh +++ b/src/python/swig/pyevent.hh @@ -40,35 +40,13 @@ class PythonEvent : public Event PyObject *object; public: - PythonEvent(PyObject *obj, Tick when, Priority priority = Default_Pri); + PythonEvent(PyObject *obj, Event::Priority priority); ~PythonEvent(); virtual void process(); }; -inline void -create(PyObject *object, Tick when) -{ - new PythonEvent(object, when); -} - -inline Event * -createCountedDrain() -{ - return new CountedDrainEvent(); -} - -inline void -cleanupCountedDrain(Event *counted_drain) -{ - CountedDrainEvent *event = - dynamic_cast(counted_drain); - if (event == NULL) { - fatal("Called cleanupCountedDrain() on an event that was not " - "a CountedDrainEvent."); - } - assert(event->getCount() == 0); - delete event; -} +Event *createCountedDrain(); +void cleanupCountedDrain(Event *counted_drain); #endif // __PYTHON_SWIG_PYEVENT_HH__ -- cgit v1.2.3 From e06321091d4e931ff1a4d753e56d76f9746c3cd2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:24 -0700 Subject: eventq: convert all usage of events to use the new API. For now, there is still a single global event queue, but this is necessary for making the steps towards a parallelized m5. --- src/python/m5/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 1f9a21899..a4324a1d6 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -326,7 +326,9 @@ def main(): if options.trace_start: def enable_trace(): internal.trace.cvar.enabled = True - event.create(enable_trace, int(options.trace_start)) + + e = event.create(enable_trace) + event.mainq.schedule(e, options.trace_start) else: internal.trace.cvar.enabled = True -- cgit v1.2.3 From 94b08bed07d13106381a0bb692bf0d879c5353d4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 22:19:39 -0700 Subject: SimObjects: Clean up handling of C++ namespaces. Make them easier to express by only having the cxx_type parameter which has the full namespace name, and drop the cxx_namespace thing. Add support for multiple levels of namespace. --- src/python/m5/SimObject.py | 64 ++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 47 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 64f4ec5af..ac81582f3 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -123,7 +123,6 @@ instanceDict = {} class MetaSimObject(type): # Attributes that can be set only at initialization time init_keywords = { 'abstract' : types.BooleanType, - 'cxx_namespace' : types.StringType, 'cxx_class' : types.StringType, 'cxx_type' : types.StringType, 'cxx_predecls' : types.ListType, @@ -190,36 +189,31 @@ class MetaSimObject(type): # the following is not true is when we define the SimObject # class itself (in which case the multidicts have no parent). if isinstance(base, MetaSimObject): + cls._base = base cls._params.parent = base._params cls._ports.parent = base._ports cls._values.parent = base._values cls._port_refs.parent = base._port_refs # mark base as having been subclassed base._instantiated = True + else: + cls._base = None # default keyword values if 'type' in cls._value_dict: - _type = cls._value_dict['type'] if 'cxx_class' not in cls._value_dict: - cls._value_dict['cxx_class'] = _type + cls._value_dict['cxx_class'] = cls._value_dict['type'] - namespace = cls._value_dict.get('cxx_namespace', None) - - _cxx_class = cls._value_dict['cxx_class'] - if 'cxx_type' not in cls._value_dict: - t = _cxx_class + '*' - if namespace: - t = '%s::%s' % (namespace, t) - cls._value_dict['cxx_type'] = t + cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class'] + if 'cxx_predecls' not in cls._value_dict: # A forward class declaration is sufficient since we are # just declaring a pointer. - decl = 'class %s;' % _cxx_class - if namespace: - namespaces = namespace.split('::') - namespaces.reverse() - for namespace in namespaces: - decl = 'namespace %s { %s }' % (namespace, decl) + class_path = cls._value_dict['cxx_class'].split('::') + class_path.reverse() + decl = 'class %s;' % class_path[0] + for ns in class_path[1:]: + decl = 'namespace %s { %s }' % (ns, decl) cls._value_dict['cxx_predecls'] = [decl] if 'swig_predecls' not in cls._value_dict: @@ -351,12 +345,6 @@ class MetaSimObject(type): def __str__(cls): return cls.__name__ - def get_base(cls): - if str(cls) == 'SimObject': - return None - - return cls.__bases__[0].type - def cxx_decl(cls): code = "#ifndef __PARAMS__%s\n" % cls code += "#define __PARAMS__%s\n\n" % cls @@ -387,16 +375,15 @@ class MetaSimObject(type): code += "\n".join(predecls2) code += "\n\n"; - base = cls.get_base() - if base: - code += '#include "params/%s.hh"\n\n' % base + if cls._base: + code += '#include "params/%s.hh"\n\n' % cls._base.type for ptype in ptypes: if issubclass(ptype, Enum): code += '#include "enums/%s.hh"\n' % ptype.__name__ code += "\n\n" - code += cls.cxx_struct(base, params) + code += cls.cxx_struct(cls._base, params) # close #ifndef __PARAMS__* guard code += "\n#endif\n" @@ -409,7 +396,7 @@ class MetaSimObject(type): # now generate the actual param struct code = "struct %sParams" % cls if base: - code += " : public %sParams" % base + code += " : public %sParams" % base.type code += "\n{\n" if not hasattr(cls, 'abstract') or not cls.abstract: if 'type' in cls.__dict__: @@ -421,24 +408,7 @@ class MetaSimObject(type): return code - def cxx_type_decl(cls): - base = cls.get_base() - code = '' - - if base: - code += '#include "%s_type.h"\n' % base - - # now generate dummy code for inheritance - code += "struct %s" % cls.cxx_class - if base: - code += " : public %s" % base.cxx_class - code += "\n{};\n" - - return code - def swig_decl(cls): - base = cls.get_base() - code = '%%module %s\n' % cls code += '%{\n' @@ -466,8 +436,8 @@ class MetaSimObject(type): code += "\n".join(predecls2) code += "\n\n"; - if base: - code += '%%import "params/%s.i"\n\n' % base + if cls._base: + code += '%%import "params/%s.i"\n\n' % cls._base.type for ptype in ptypes: if issubclass(ptype, Enum): -- cgit v1.2.3 From 84364f36d0f763d3cef9847396fa4195184cb930 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 10 Oct 2008 10:15:00 -0700 Subject: python: Add a utility for nested attribute dicts. Change attrdict so that attributes that begin with an underscore don't go into the dict. --- src/python/m5/util/attrdict.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py index 44479c456..56f67217b 100644 --- a/src/python/m5/util/attrdict.py +++ b/src/python/m5/util/attrdict.py @@ -26,16 +26,17 @@ # # Authors: Nathan Binkert -__all__ = [ 'attrdict', 'optiondict' ] +__all__ = [ 'attrdict', 'multiattrdict', 'optiondict' ] class attrdict(dict): + """Wrap dict, so you can use attribute access to get/set elements""" def __getattr__(self, attr): if attr in self: return self.__getitem__(attr) return super(attrdict, self).__getattribute__(attr) def __setattr__(self, attr, value): - if attr in dir(self): + if attr in dir(self) or attr.startswith('_'): return super(attrdict, self).__setattr__(attr, value) return self.__setitem__(attr, value) @@ -44,13 +45,23 @@ class attrdict(dict): return self.__delitem__(attr) return super(attrdict, self).__delattr__(attr, value) +class multiattrdict(attrdict): + """Wrap attrdict so that nested attribute accesses automatically create + nested dictionaries.""" + def __getattr__(self, attr): + try: + return super(multiattrdict, self).__getattr__(attr) + except AttributeError: + d = optiondict() + setattr(self, attr, d) + return d + class optiondict(attrdict): + """Modify attrdict so that a missing attribute just returns None""" def __getattr__(self, attr): try: return super(optiondict, self).__getattr__(attr) except AttributeError: - #d = optionsdict() - #setattr(self, attr, d) return None if __name__ == '__main__': @@ -68,3 +79,9 @@ if __name__ == '__main__': del x.z print dir(x) print(x) + + x = multiattrdict() + x.y.z = 9 + print x + print x.y + print x.y.z -- cgit v1.2.3 From 70dbe61ffc8dae4fc2ecc252f963a760a4387517 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 10 Oct 2008 10:15:01 -0700 Subject: jobfile: Add support for dictionaries as jobfile options. If the same dictionary option is seen in several options, those dictionaries are composed. If you define the same dictionary key in multiple options, the system flags an error. Also, clean up the jobfile code so that it is more debuggable. --- src/python/m5/util/jobfile.py | 52 ++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/util/jobfile.py b/src/python/m5/util/jobfile.py index 5e015c4ad..c830895f6 100644 --- a/src/python/m5/util/jobfile.py +++ b/src/python/m5/util/jobfile.py @@ -28,8 +28,8 @@ import sys -from attrdict import attrdict, optiondict -from misc import crossproduct, flatten +from attrdict import optiondict +from misc import crossproduct class Data(object): def __init__(self, name, desc, **kwargs): @@ -41,9 +41,29 @@ class Data(object): if not isinstance(obj, Data): raise AttributeError, "can only update from Data object" - for k,v in obj.__dict__.iteritems(): - if not k.startswith('_'): - self.__dict__[k] = v + for key,val in obj.__dict__.iteritems(): + if key.startswith('_') or key in ('name', 'desc'): + continue + + if key not in self.__dict__: + self.__dict__[key] = val + continue + + if not isinstance(val, dict): + if self.__dict__[key] == val: + continue + + raise AttributeError, \ + "%s specified more than once old: %s new: %s" % \ + (key, self.__dict__[key], val) + + d = self.__dict__[key] + for k,v in val.iteritems(): + if k in d: + raise AttributeError, \ + "%s specified more than once in %s" % (k, key) + d[k] = v + if hasattr(self, 'system') and hasattr(obj, 'system'): if self.system != obj.system: raise AttributeError, \ @@ -93,6 +113,14 @@ class Data(object): result[key] = self[key] return result + def __repr__(self): + d = {} + for key,value in self.__dict__.iteritems(): + if not key.startswith('_'): + d[key] = value + + return "<%s: %s>" % (type(self).__name__, d) + def __str__(self): return self.name @@ -391,18 +419,12 @@ def JobFile(jobfile): execfile(filename, data) if 'conf' not in data: raise ImportError, 'cannot import name conf from %s' % jobfile - conf = data['conf'] - import jobfile - if not isinstance(conf, Configuration): - raise AttributeError, \ - 'conf in jobfile: %s (%s) is not type %s' % \ - (jobfile, type(conf), Configuration) - return conf + return data['conf'] def main(conf=None): - import sys - - usage = 'Usage: %s [-b] [-c] [-v] ' % sys.argv[0] + usage = 'Usage: %s [-b] [-c] [-v]' % sys.argv[0] + if conf is None: + usage += ' ' try: import getopt -- cgit v1.2.3 From afb279b1bb8f7c01a74c4fe783ce14365916e920 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 10 Oct 2008 10:18:28 -0700 Subject: output: Make panic/fatal/warn more flexible so we can add some new ones. The major thrust of this change is to limit the amount of code duplication surrounding the code for these functions. This code also adds two new message types called info and hack. Info is meant to be less harsh than warn so people don't get confused and start thinking that the simulator is broken. Hack is a way for people to add runtime messages indicating that the simulator just executed a code "hack" that should probably be fixed. The benefit of knowing about these code hacks is that it will let people know what sorts of inaccuracies or potential bugs might be entering their experiments. Finally, I've added some flags to turn on and off these message types so command line options can change them. --- src/python/swig/core.i | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/python') diff --git a/src/python/swig/core.i b/src/python/swig/core.i index b0773ca68..566998639 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -34,6 +34,7 @@ %{ #include "python/swig/pyobject.hh" +#include "base/misc.hh" #include "base/socket.hh" #include "sim/core.hh" #include "sim/host.hh" @@ -76,6 +77,10 @@ void unserializeAll(const std::string &cpt_dir); void initAll(); void regAllStats(); +bool want_warn, warn_verbose; +bool want_info, info_verbose; +bool want_hack, hack_verbose; + %wrapper %{ // fix up module name to reflect the fact that it's inside the m5 package #undef SWIG_name -- cgit v1.2.3 From 5b07448cf12460090af588b332e813af3419d645 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 14 Oct 2008 09:34:11 -0700 Subject: eventq: make python events actually work --- src/python/m5/event.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/event.py b/src/python/m5/event.py index 5d50448e7..2b43e578e 100644 --- a/src/python/m5/event.py +++ b/src/python/m5/event.py @@ -26,6 +26,7 @@ # # Authors: Nathan Binkert +import m5 import internal.event from internal.event import PythonEvent, SimLoopExitEvent as SimExit @@ -41,7 +42,7 @@ class Event(PythonEvent): def __init__(self, priority=None): if priority is None: priority = internal.event.Event.Default_Pri - super(PythonEvent, self).__init__(self, priority) + super(Event, self).__init__(self, priority) class ProgressEvent(Event): def __init__(self, eventq, period): -- cgit v1.2.3 From cfa32d8de737847f04bfa6e5e89375c870c3869b Mon Sep 17 00:00:00 2001 From: Clint Smullen Date: Mon, 27 Oct 2008 19:46:01 -0400 Subject: Checkpointing: createCountedDrain function, it was only returning an Event, which does not expose a setCount method to Python. Signed-off By: Ali Saidi --- src/python/swig/pyevent.cc | 2 +- src/python/swig/pyevent.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/swig/pyevent.cc b/src/python/swig/pyevent.cc index bf993bc3e..a201e0185 100644 --- a/src/python/swig/pyevent.cc +++ b/src/python/swig/pyevent.cc @@ -67,7 +67,7 @@ PythonEvent::process() } } -Event * +CountedDrainEvent * createCountedDrain() { return new CountedDrainEvent(); diff --git a/src/python/swig/pyevent.hh b/src/python/swig/pyevent.hh index c6d6ac993..22b562de1 100644 --- a/src/python/swig/pyevent.hh +++ b/src/python/swig/pyevent.hh @@ -46,7 +46,7 @@ class PythonEvent : public Event virtual void process(); }; -Event *createCountedDrain(); +CountedDrainEvent *createCountedDrain(); void cleanupCountedDrain(Event *counted_drain); #endif // __PYTHON_SWIG_PYEVENT_HH__ -- cgit v1.2.3 From 4e02e7c217a1ee81dc16c378582697dd5a14de47 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 10 Nov 2008 11:51:18 -0800 Subject: python: Fix the reference counting for python events placed on the eventq. We need to add a reference when an object is put on the C++ queue, and remove a reference when the object is removed from the queue. This was not happening before and caused a memory problem. --- src/python/m5/event.py | 2 +- src/python/swig/event.i | 29 +++++++++++++++++++++++++++++ src/python/swig/pyevent.cc | 23 ++++------------------- src/python/swig/pyevent.hh | 3 +++ 4 files changed, 37 insertions(+), 20 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/event.py b/src/python/m5/event.py index 2b43e578e..ce003defb 100644 --- a/src/python/m5/event.py +++ b/src/python/m5/event.py @@ -36,7 +36,7 @@ mainq = internal.event.cvar.mainEventQueue def create(obj, priority=None): if priority is None: priority = internal.event.Event.Default_Pri - return internal.event.PythonEvent(obj, priority) + return PythonEvent(obj, priority) class Event(PythonEvent): def __init__(self, priority=None): diff --git a/src/python/swig/event.i b/src/python/swig/event.i index 10d75d2de..b40e59a4b 100644 --- a/src/python/swig/event.i +++ b/src/python/swig/event.i @@ -41,6 +41,35 @@ #pragma SWIG nowarn=350,351 +%extend EventQueue { + void + schedule(Event *event, Tick when) + { + // Any python event that are scheduled must have their + // internal object's refcount incremented so that the object + // sticks around while it is in the event queue. + PythonEvent *pyevent = dynamic_cast(event); + if (pyevent) + pyevent->incref(); + $self->schedule(event, when); + } + + void + deschedule(Event *event) + { + $self->deschedule(event); + + // Now that we're removing the python object from the event + // queue, we need to decrement its reference count. + PythonEvent *pyevent = dynamic_cast(event); + if (pyevent) + pyevent->decref(); + } +} + +%ignore EventQueue::schedule; +%ignore EventQueue::deschedule; + %import "base/fast_alloc.hh" %import "sim/serialize.hh" diff --git a/src/python/swig/pyevent.cc b/src/python/swig/pyevent.cc index a201e0185..0695ed2d3 100644 --- a/src/python/swig/pyevent.cc +++ b/src/python/swig/pyevent.cc @@ -38,15 +38,10 @@ PythonEvent::PythonEvent(PyObject *obj, Priority priority) { if (object == NULL) panic("Passed in invalid object"); - - Py_INCREF(object); - - setFlags(AutoDelete); } PythonEvent::~PythonEvent() { - Py_DECREF(object); } void @@ -65,6 +60,10 @@ PythonEvent::process() async_event = true; async_exception = true; } + + // Since the object has been removed from the event queue, its + // reference count must be decremented. + Py_DECREF(object); } CountedDrainEvent * @@ -85,17 +84,3 @@ cleanupCountedDrain(Event *counted_drain) assert(event->getCount() == 0); delete event; } - -#if 0 -Event * -create(PyObject *object, Event::Priority priority) -{ - return new PythonEvent(object, priority); -} - -void -destroy(Event *event) -{ - delete event; -} -#endif diff --git a/src/python/swig/pyevent.hh b/src/python/swig/pyevent.hh index 22b562de1..9006a0404 100644 --- a/src/python/swig/pyevent.hh +++ b/src/python/swig/pyevent.hh @@ -43,6 +43,9 @@ class PythonEvent : public Event PythonEvent(PyObject *obj, Event::Priority priority); ~PythonEvent(); + void incref() { Py_INCREF(object); } + void decref() { Py_DECREF(object); } + virtual void process(); }; -- cgit v1.2.3 From ce4c9a7c10f9a2f91736592f32dcfeb317f17820 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 17 Nov 2008 12:41:50 -0800 Subject: Sort trace flags before printing them. --- src/python/m5/main.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index a4324a1d6..e1403203d 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -220,9 +220,11 @@ def main(): done = True print "Base Flags:" + traceflags.baseFlags.sort() print_list(traceflags.baseFlags, indent=4) print print "Compound Flags:" + traceflags.compoundFlags.sort() for flag in traceflags.compoundFlags: if flag == 'All': continue -- cgit v1.2.3 From e08c6be9feb5d381ca45afc581cf6efb090f0dd7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 6 Dec 2008 14:18:18 -0800 Subject: SimObject: change naming of vectors so there are the same numbers of digits. i.e. we used to have Foo0, Foo1, ..., Foo10, Foo11, ..., Foo100 now we have Foo000, Foo001, ..., Foo010, Foo011, ..., Foo100 --- src/python/m5/SimObject.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index ac81582f3..868f969a6 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -27,7 +27,9 @@ # Authors: Steve Reinhardt # Nathan Binkert -import sys, types +import math +import sys +import types import proxy import m5 @@ -627,8 +629,9 @@ class SimObject(object): if len(value) == 1: value[0]._maybe_set_parent(self, attr) else: + width = int(math.ceil(math.log(len(value))/math.log(10))) for i,v in enumerate(value): - v._maybe_set_parent(self, "%s%d" % (attr, i)) + v._maybe_set_parent(self, "%s%0*d" % (attr, width, i)) self._values[attr] = value -- cgit v1.2.3 From a0d322be4021891ee21edb4424e4af1957a50d0a Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 6 Dec 2008 14:18:18 -0800 Subject: traceflags: Make "All" a valid trace flag. --- src/python/m5/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index e1403203d..d34cca357 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -310,7 +310,7 @@ def main(): if flag.startswith('-'): flag = flag[1:] off = True - if flag not in traceflags.allFlags: + if flag not in traceflags.allFlags and flag != "All": print >>sys.stderr, "invalid trace flag '%s'" % flag sys.exit(1) -- cgit v1.2.3 From 19273164da50011d59b7f362026f8e80260807d4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 8 Dec 2008 07:16:40 -0800 Subject: output: Change default output directory and files and update tests. --HG-- rename : tests/long/00.gzip/ref/alpha/tru64/o3-timing/stderr => tests/long/00.gzip/ref/alpha/tru64/o3-timing/simerr rename : tests/long/00.gzip/ref/alpha/tru64/o3-timing/stdout => tests/long/00.gzip/ref/alpha/tru64/o3-timing/simout rename : tests/long/00.gzip/ref/alpha/tru64/o3-timing/m5stats.txt => tests/long/00.gzip/ref/alpha/tru64/o3-timing/stats.txt rename : tests/long/00.gzip/ref/alpha/tru64/simple-atomic/stderr => tests/long/00.gzip/ref/alpha/tru64/simple-atomic/simerr rename : tests/long/00.gzip/ref/alpha/tru64/simple-atomic/stdout => tests/long/00.gzip/ref/alpha/tru64/simple-atomic/simout rename : tests/long/00.gzip/ref/alpha/tru64/simple-atomic/m5stats.txt => tests/long/00.gzip/ref/alpha/tru64/simple-atomic/stats.txt rename : tests/long/00.gzip/ref/alpha/tru64/simple-timing/stderr => tests/long/00.gzip/ref/alpha/tru64/simple-timing/simerr rename : tests/long/00.gzip/ref/alpha/tru64/simple-timing/stdout => tests/long/00.gzip/ref/alpha/tru64/simple-timing/simout rename : tests/long/00.gzip/ref/alpha/tru64/simple-timing/m5stats.txt => tests/long/00.gzip/ref/alpha/tru64/simple-timing/stats.txt rename : tests/long/00.gzip/ref/sparc/linux/o3-timing/stderr => tests/long/00.gzip/ref/sparc/linux/o3-timing/simerr rename : tests/long/00.gzip/ref/sparc/linux/o3-timing/stdout => tests/long/00.gzip/ref/sparc/linux/o3-timing/simout rename : tests/long/00.gzip/ref/sparc/linux/o3-timing/m5stats.txt => tests/long/00.gzip/ref/sparc/linux/o3-timing/stats.txt rename : tests/long/00.gzip/ref/sparc/linux/simple-atomic/stderr => tests/long/00.gzip/ref/sparc/linux/simple-atomic/simerr rename : tests/long/00.gzip/ref/sparc/linux/simple-atomic/stdout => tests/long/00.gzip/ref/sparc/linux/simple-atomic/simout rename : tests/long/00.gzip/ref/sparc/linux/simple-atomic/m5stats.txt => tests/long/00.gzip/ref/sparc/linux/simple-atomic/stats.txt rename : tests/long/00.gzip/ref/sparc/linux/simple-timing/stderr => tests/long/00.gzip/ref/sparc/linux/simple-timing/simerr rename : tests/long/00.gzip/ref/sparc/linux/simple-timing/stdout => tests/long/00.gzip/ref/sparc/linux/simple-timing/simout rename : tests/long/00.gzip/ref/sparc/linux/simple-timing/m5stats.txt => tests/long/00.gzip/ref/sparc/linux/simple-timing/stats.txt rename : tests/long/00.gzip/ref/x86/linux/simple-atomic/stderr => tests/long/00.gzip/ref/x86/linux/simple-atomic/simerr rename : tests/long/00.gzip/ref/x86/linux/simple-atomic/stdout => tests/long/00.gzip/ref/x86/linux/simple-atomic/simout rename : tests/long/00.gzip/ref/x86/linux/simple-atomic/m5stats.txt => tests/long/00.gzip/ref/x86/linux/simple-atomic/stats.txt rename : tests/long/00.gzip/ref/x86/linux/simple-timing/stderr => tests/long/00.gzip/ref/x86/linux/simple-timing/simerr rename : tests/long/00.gzip/ref/x86/linux/simple-timing/stdout => tests/long/00.gzip/ref/x86/linux/simple-timing/simout rename : tests/long/00.gzip/ref/x86/linux/simple-timing/m5stats.txt => tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt rename : tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3-dual/stderr => tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3-dual/simerr rename : tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3-dual/stdout => tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3-dual/simout rename : tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3-dual/m5stats.txt => tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3-dual/stats.txt rename : tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3/stderr => tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3/simerr rename : tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3/stdout => tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3/simout rename : tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3/m5stats.txt => tests/long/10.linux-boot/ref/alpha/linux/tsunami-o3/stats.txt rename : tests/long/10.mcf/ref/sparc/linux/simple-atomic/stderr => tests/long/10.mcf/ref/sparc/linux/simple-atomic/simerr rename : tests/long/10.mcf/ref/sparc/linux/simple-atomic/stdout => tests/long/10.mcf/ref/sparc/linux/simple-atomic/simout rename : tests/long/10.mcf/ref/sparc/linux/simple-atomic/m5stats.txt => tests/long/10.mcf/ref/sparc/linux/simple-atomic/stats.txt rename : tests/long/10.mcf/ref/sparc/linux/simple-timing/stderr => tests/long/10.mcf/ref/sparc/linux/simple-timing/simerr rename : tests/long/10.mcf/ref/sparc/linux/simple-timing/stdout => tests/long/10.mcf/ref/sparc/linux/simple-timing/simout rename : tests/long/10.mcf/ref/sparc/linux/simple-timing/m5stats.txt => tests/long/10.mcf/ref/sparc/linux/simple-timing/stats.txt rename : tests/long/10.mcf/ref/x86/linux/simple-atomic/stderr => tests/long/10.mcf/ref/x86/linux/simple-atomic/simerr rename : tests/long/10.mcf/ref/x86/linux/simple-atomic/stdout => tests/long/10.mcf/ref/x86/linux/simple-atomic/simout rename : tests/long/10.mcf/ref/x86/linux/simple-atomic/m5stats.txt => tests/long/10.mcf/ref/x86/linux/simple-atomic/stats.txt rename : tests/long/10.mcf/ref/x86/linux/simple-timing/stderr => tests/long/10.mcf/ref/x86/linux/simple-timing/simerr rename : tests/long/10.mcf/ref/x86/linux/simple-timing/stdout => tests/long/10.mcf/ref/x86/linux/simple-timing/simout rename : tests/long/10.mcf/ref/x86/linux/simple-timing/m5stats.txt => tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt rename : tests/long/20.parser/ref/x86/linux/simple-atomic/stderr => tests/long/20.parser/ref/x86/linux/simple-atomic/simerr rename : tests/long/20.parser/ref/x86/linux/simple-atomic/stdout => tests/long/20.parser/ref/x86/linux/simple-atomic/simout rename : tests/long/20.parser/ref/x86/linux/simple-atomic/m5stats.txt => tests/long/20.parser/ref/x86/linux/simple-atomic/stats.txt rename : tests/long/20.parser/ref/x86/linux/simple-timing/stderr => tests/long/20.parser/ref/x86/linux/simple-timing/simerr rename : tests/long/20.parser/ref/x86/linux/simple-timing/stdout => tests/long/20.parser/ref/x86/linux/simple-timing/simout rename : tests/long/20.parser/ref/x86/linux/simple-timing/m5stats.txt => tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt rename : tests/long/30.eon/ref/alpha/tru64/o3-timing/stderr => tests/long/30.eon/ref/alpha/tru64/o3-timing/simerr rename : tests/long/30.eon/ref/alpha/tru64/o3-timing/stdout => tests/long/30.eon/ref/alpha/tru64/o3-timing/simout rename : tests/long/30.eon/ref/alpha/tru64/o3-timing/m5stats.txt => tests/long/30.eon/ref/alpha/tru64/o3-timing/stats.txt rename : tests/long/30.eon/ref/alpha/tru64/simple-atomic/stderr => tests/long/30.eon/ref/alpha/tru64/simple-atomic/simerr rename : tests/long/30.eon/ref/alpha/tru64/simple-atomic/stdout => tests/long/30.eon/ref/alpha/tru64/simple-atomic/simout rename : tests/long/30.eon/ref/alpha/tru64/simple-atomic/m5stats.txt => tests/long/30.eon/ref/alpha/tru64/simple-atomic/stats.txt rename : tests/long/30.eon/ref/alpha/tru64/simple-timing/stderr => tests/long/30.eon/ref/alpha/tru64/simple-timing/simerr rename : tests/long/30.eon/ref/alpha/tru64/simple-timing/stdout => tests/long/30.eon/ref/alpha/tru64/simple-timing/simout rename : tests/long/30.eon/ref/alpha/tru64/simple-timing/m5stats.txt => tests/long/30.eon/ref/alpha/tru64/simple-timing/stats.txt rename : tests/long/40.perlbmk/ref/alpha/tru64/o3-timing/stderr => tests/long/40.perlbmk/ref/alpha/tru64/o3-timing/simerr rename : tests/long/40.perlbmk/ref/alpha/tru64/o3-timing/stdout => tests/long/40.perlbmk/ref/alpha/tru64/o3-timing/simout rename : tests/long/40.perlbmk/ref/alpha/tru64/o3-timing/m5stats.txt => tests/long/40.perlbmk/ref/alpha/tru64/o3-timing/stats.txt rename : tests/long/40.perlbmk/ref/alpha/tru64/simple-atomic/stderr => tests/long/40.perlbmk/ref/alpha/tru64/simple-atomic/simerr rename : tests/long/40.perlbmk/ref/alpha/tru64/simple-atomic/stdout => tests/long/40.perlbmk/ref/alpha/tru64/simple-atomic/simout rename : tests/long/40.perlbmk/ref/alpha/tru64/simple-atomic/m5stats.txt => tests/long/40.perlbmk/ref/alpha/tru64/simple-atomic/stats.txt rename : tests/long/40.perlbmk/ref/alpha/tru64/simple-timing/stderr => tests/long/40.perlbmk/ref/alpha/tru64/simple-timing/simerr rename : tests/long/40.perlbmk/ref/alpha/tru64/simple-timing/stdout => tests/long/40.perlbmk/ref/alpha/tru64/simple-timing/simout rename : tests/long/40.perlbmk/ref/alpha/tru64/simple-timing/m5stats.txt => tests/long/40.perlbmk/ref/alpha/tru64/simple-timing/stats.txt rename : tests/long/50.vortex/ref/alpha/tru64/o3-timing/stderr => tests/long/50.vortex/ref/alpha/tru64/o3-timing/simerr rename : tests/long/50.vortex/ref/alpha/tru64/o3-timing/stdout => tests/long/50.vortex/ref/alpha/tru64/o3-timing/simout rename : tests/long/50.vortex/ref/alpha/tru64/o3-timing/m5stats.txt => tests/long/50.vortex/ref/alpha/tru64/o3-timing/stats.txt rename : tests/long/50.vortex/ref/alpha/tru64/simple-atomic/stderr => tests/long/50.vortex/ref/alpha/tru64/simple-atomic/simerr rename : tests/long/50.vortex/ref/alpha/tru64/simple-atomic/stdout => tests/long/50.vortex/ref/alpha/tru64/simple-atomic/simout rename : tests/long/50.vortex/ref/alpha/tru64/simple-atomic/m5stats.txt => tests/long/50.vortex/ref/alpha/tru64/simple-atomic/stats.txt rename : tests/long/50.vortex/ref/alpha/tru64/simple-timing/stderr => tests/long/50.vortex/ref/alpha/tru64/simple-timing/simerr rename : tests/long/50.vortex/ref/alpha/tru64/simple-timing/stdout => tests/long/50.vortex/ref/alpha/tru64/simple-timing/simout rename : tests/long/50.vortex/ref/alpha/tru64/simple-timing/m5stats.txt => tests/long/50.vortex/ref/alpha/tru64/simple-timing/stats.txt rename : tests/long/50.vortex/ref/sparc/linux/simple-atomic/stderr => tests/long/50.vortex/ref/sparc/linux/simple-atomic/simerr rename : tests/long/50.vortex/ref/sparc/linux/simple-atomic/stdout => tests/long/50.vortex/ref/sparc/linux/simple-atomic/simout rename : tests/long/50.vortex/ref/sparc/linux/simple-atomic/m5stats.txt => tests/long/50.vortex/ref/sparc/linux/simple-atomic/stats.txt rename : tests/long/50.vortex/ref/sparc/linux/simple-timing/stderr => tests/long/50.vortex/ref/sparc/linux/simple-timing/simerr rename : tests/long/50.vortex/ref/sparc/linux/simple-timing/stdout => tests/long/50.vortex/ref/sparc/linux/simple-timing/simout rename : tests/long/50.vortex/ref/sparc/linux/simple-timing/m5stats.txt => tests/long/50.vortex/ref/sparc/linux/simple-timing/stats.txt rename : tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stderr => tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simerr rename : tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stdout => tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout rename : tests/long/60.bzip2/ref/alpha/tru64/o3-timing/m5stats.txt => tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt rename : tests/long/60.bzip2/ref/alpha/tru64/simple-atomic/stderr => tests/long/60.bzip2/ref/alpha/tru64/simple-atomic/simerr rename : tests/long/60.bzip2/ref/alpha/tru64/simple-atomic/stdout => tests/long/60.bzip2/ref/alpha/tru64/simple-atomic/simout rename : tests/long/60.bzip2/ref/alpha/tru64/simple-atomic/m5stats.txt => tests/long/60.bzip2/ref/alpha/tru64/simple-atomic/stats.txt rename : tests/long/60.bzip2/ref/alpha/tru64/simple-timing/stderr => tests/long/60.bzip2/ref/alpha/tru64/simple-timing/simerr rename : tests/long/60.bzip2/ref/alpha/tru64/simple-timing/stdout => tests/long/60.bzip2/ref/alpha/tru64/simple-timing/simout rename : tests/long/60.bzip2/ref/alpha/tru64/simple-timing/m5stats.txt => tests/long/60.bzip2/ref/alpha/tru64/simple-timing/stats.txt rename : tests/long/60.bzip2/ref/x86/linux/simple-atomic/stderr => tests/long/60.bzip2/ref/x86/linux/simple-atomic/simerr rename : tests/long/60.bzip2/ref/x86/linux/simple-atomic/stdout => tests/long/60.bzip2/ref/x86/linux/simple-atomic/simout rename : tests/long/60.bzip2/ref/x86/linux/simple-atomic/m5stats.txt => tests/long/60.bzip2/ref/x86/linux/simple-atomic/stats.txt rename : tests/long/60.bzip2/ref/x86/linux/simple-timing/stderr => tests/long/60.bzip2/ref/x86/linux/simple-timing/simerr rename : tests/long/60.bzip2/ref/x86/linux/simple-timing/stdout => tests/long/60.bzip2/ref/x86/linux/simple-timing/simout rename : tests/long/60.bzip2/ref/x86/linux/simple-timing/m5stats.txt => tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt rename : tests/long/70.twolf/ref/alpha/tru64/o3-timing/stderr => tests/long/70.twolf/ref/alpha/tru64/o3-timing/simerr rename : tests/long/70.twolf/ref/alpha/tru64/o3-timing/stdout => tests/long/70.twolf/ref/alpha/tru64/o3-timing/simout rename : tests/long/70.twolf/ref/alpha/tru64/o3-timing/m5stats.txt => tests/long/70.twolf/ref/alpha/tru64/o3-timing/stats.txt rename : tests/long/70.twolf/ref/alpha/tru64/simple-atomic/stderr => tests/long/70.twolf/ref/alpha/tru64/simple-atomic/simerr rename : tests/long/70.twolf/ref/alpha/tru64/simple-atomic/stdout => tests/long/70.twolf/ref/alpha/tru64/simple-atomic/simout rename : tests/long/70.twolf/ref/alpha/tru64/simple-atomic/m5stats.txt => tests/long/70.twolf/ref/alpha/tru64/simple-atomic/stats.txt rename : tests/long/70.twolf/ref/alpha/tru64/simple-timing/stderr => tests/long/70.twolf/ref/alpha/tru64/simple-timing/simerr rename : tests/long/70.twolf/ref/alpha/tru64/simple-timing/stdout => tests/long/70.twolf/ref/alpha/tru64/simple-timing/simout rename : tests/long/70.twolf/ref/alpha/tru64/simple-timing/m5stats.txt => tests/long/70.twolf/ref/alpha/tru64/simple-timing/stats.txt rename : tests/long/70.twolf/ref/sparc/linux/simple-atomic/stderr => tests/long/70.twolf/ref/sparc/linux/simple-atomic/simerr rename : tests/long/70.twolf/ref/sparc/linux/simple-atomic/stdout => tests/long/70.twolf/ref/sparc/linux/simple-atomic/simout rename : tests/long/70.twolf/ref/sparc/linux/simple-atomic/m5stats.txt => tests/long/70.twolf/ref/sparc/linux/simple-atomic/stats.txt rename : tests/long/70.twolf/ref/sparc/linux/simple-timing/stderr => tests/long/70.twolf/ref/sparc/linux/simple-timing/simerr rename : tests/long/70.twolf/ref/sparc/linux/simple-timing/stdout => tests/long/70.twolf/ref/sparc/linux/simple-timing/simout rename : tests/long/70.twolf/ref/sparc/linux/simple-timing/m5stats.txt => tests/long/70.twolf/ref/sparc/linux/simple-timing/stats.txt rename : tests/long/70.twolf/ref/x86/linux/simple-atomic/stderr => tests/long/70.twolf/ref/x86/linux/simple-atomic/simerr rename : tests/long/70.twolf/ref/x86/linux/simple-atomic/stdout => tests/long/70.twolf/ref/x86/linux/simple-atomic/simout rename : tests/long/70.twolf/ref/x86/linux/simple-atomic/m5stats.txt => tests/long/70.twolf/ref/x86/linux/simple-atomic/stats.txt rename : tests/long/70.twolf/ref/x86/linux/simple-timing/stderr => tests/long/70.twolf/ref/x86/linux/simple-timing/simerr rename : tests/long/70.twolf/ref/x86/linux/simple-timing/stdout => tests/long/70.twolf/ref/x86/linux/simple-timing/simout rename : tests/long/70.twolf/ref/x86/linux/simple-timing/m5stats.txt => tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt rename : tests/long/80.solaris-boot/ref/sparc/solaris/t1000-simple-atomic/stderr => tests/long/80.solaris-boot/ref/sparc/solaris/t1000-simple-atomic/simerr rename : tests/long/80.solaris-boot/ref/sparc/solaris/t1000-simple-atomic/stdout => tests/long/80.solaris-boot/ref/sparc/solaris/t1000-simple-atomic/simout rename : tests/long/80.solaris-boot/ref/sparc/solaris/t1000-simple-atomic/m5stats.txt => tests/long/80.solaris-boot/ref/sparc/solaris/t1000-simple-atomic/stats.txt rename : tests/quick/00.hello/ref/alpha/linux/o3-timing/stderr => tests/quick/00.hello/ref/alpha/linux/o3-timing/simerr rename : tests/quick/00.hello/ref/alpha/linux/o3-timing/stdout => tests/quick/00.hello/ref/alpha/linux/o3-timing/simout rename : tests/quick/00.hello/ref/alpha/linux/o3-timing/m5stats.txt => tests/quick/00.hello/ref/alpha/linux/o3-timing/stats.txt rename : tests/quick/00.hello/ref/alpha/linux/simple-atomic/stderr => tests/quick/00.hello/ref/alpha/linux/simple-atomic/simerr rename : tests/quick/00.hello/ref/alpha/linux/simple-atomic/stdout => tests/quick/00.hello/ref/alpha/linux/simple-atomic/simout rename : tests/quick/00.hello/ref/alpha/linux/simple-atomic/m5stats.txt => tests/quick/00.hello/ref/alpha/linux/simple-atomic/stats.txt rename : tests/quick/00.hello/ref/alpha/linux/simple-timing/stderr => tests/quick/00.hello/ref/alpha/linux/simple-timing/simerr rename : tests/quick/00.hello/ref/alpha/linux/simple-timing/stdout => tests/quick/00.hello/ref/alpha/linux/simple-timing/simout rename : tests/quick/00.hello/ref/alpha/linux/simple-timing/m5stats.txt => tests/quick/00.hello/ref/alpha/linux/simple-timing/stats.txt rename : tests/quick/00.hello/ref/alpha/tru64/o3-timing/stderr => tests/quick/00.hello/ref/alpha/tru64/o3-timing/simerr rename : tests/quick/00.hello/ref/alpha/tru64/o3-timing/stdout => tests/quick/00.hello/ref/alpha/tru64/o3-timing/simout rename : tests/quick/00.hello/ref/alpha/tru64/o3-timing/m5stats.txt => tests/quick/00.hello/ref/alpha/tru64/o3-timing/stats.txt rename : tests/quick/00.hello/ref/alpha/tru64/simple-atomic/stderr => tests/quick/00.hello/ref/alpha/tru64/simple-atomic/simerr rename : tests/quick/00.hello/ref/alpha/tru64/simple-atomic/stdout => tests/quick/00.hello/ref/alpha/tru64/simple-atomic/simout rename : tests/quick/00.hello/ref/alpha/tru64/simple-atomic/m5stats.txt => tests/quick/00.hello/ref/alpha/tru64/simple-atomic/stats.txt rename : tests/quick/00.hello/ref/alpha/tru64/simple-timing/stderr => tests/quick/00.hello/ref/alpha/tru64/simple-timing/simerr rename : tests/quick/00.hello/ref/alpha/tru64/simple-timing/stdout => tests/quick/00.hello/ref/alpha/tru64/simple-timing/simout rename : tests/quick/00.hello/ref/alpha/tru64/simple-timing/m5stats.txt => tests/quick/00.hello/ref/alpha/tru64/simple-timing/stats.txt rename : tests/quick/00.hello/ref/mips/linux/simple-atomic/stderr => tests/quick/00.hello/ref/mips/linux/simple-atomic/simerr rename : tests/quick/00.hello/ref/mips/linux/simple-atomic/stdout => tests/quick/00.hello/ref/mips/linux/simple-atomic/simout rename : tests/quick/00.hello/ref/mips/linux/simple-atomic/m5stats.txt => tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt rename : tests/quick/00.hello/ref/mips/linux/simple-timing/stderr => tests/quick/00.hello/ref/mips/linux/simple-timing/simerr rename : tests/quick/00.hello/ref/mips/linux/simple-timing/stdout => tests/quick/00.hello/ref/mips/linux/simple-timing/simout rename : tests/quick/00.hello/ref/mips/linux/simple-timing/m5stats.txt => tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt rename : tests/quick/00.hello/ref/sparc/linux/simple-atomic/stderr => tests/quick/00.hello/ref/sparc/linux/simple-atomic/simerr rename : tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout => tests/quick/00.hello/ref/sparc/linux/simple-atomic/simout rename : tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt => tests/quick/00.hello/ref/sparc/linux/simple-atomic/stats.txt rename : tests/quick/00.hello/ref/sparc/linux/simple-timing/stderr => tests/quick/00.hello/ref/sparc/linux/simple-timing/simerr rename : tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout => tests/quick/00.hello/ref/sparc/linux/simple-timing/simout rename : tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt => tests/quick/00.hello/ref/sparc/linux/simple-timing/stats.txt rename : tests/quick/00.hello/ref/x86/linux/simple-atomic/stderr => tests/quick/00.hello/ref/x86/linux/simple-atomic/simerr rename : tests/quick/00.hello/ref/x86/linux/simple-atomic/stdout => tests/quick/00.hello/ref/x86/linux/simple-atomic/simout rename : tests/quick/00.hello/ref/x86/linux/simple-atomic/m5stats.txt => tests/quick/00.hello/ref/x86/linux/simple-atomic/stats.txt rename : tests/quick/00.hello/ref/x86/linux/simple-timing/stderr => tests/quick/00.hello/ref/x86/linux/simple-timing/simerr rename : tests/quick/00.hello/ref/x86/linux/simple-timing/stdout => tests/quick/00.hello/ref/x86/linux/simple-timing/simout rename : tests/quick/00.hello/ref/x86/linux/simple-timing/m5stats.txt => tests/quick/00.hello/ref/x86/linux/simple-timing/stats.txt rename : tests/quick/01.hello-2T-smt/ref/alpha/linux/o3-timing/stderr => tests/quick/01.hello-2T-smt/ref/alpha/linux/o3-timing/simerr rename : tests/quick/01.hello-2T-smt/ref/alpha/linux/o3-timing/stdout => tests/quick/01.hello-2T-smt/ref/alpha/linux/o3-timing/simout rename : tests/quick/01.hello-2T-smt/ref/alpha/linux/o3-timing/m5stats.txt => tests/quick/01.hello-2T-smt/ref/alpha/linux/o3-timing/stats.txt rename : tests/quick/02.insttest/ref/sparc/linux/o3-timing/stderr => tests/quick/02.insttest/ref/sparc/linux/o3-timing/simerr rename : tests/quick/02.insttest/ref/sparc/linux/o3-timing/stdout => tests/quick/02.insttest/ref/sparc/linux/o3-timing/simout rename : tests/quick/02.insttest/ref/sparc/linux/o3-timing/m5stats.txt => tests/quick/02.insttest/ref/sparc/linux/o3-timing/stats.txt rename : tests/quick/02.insttest/ref/sparc/linux/simple-atomic/stderr => tests/quick/02.insttest/ref/sparc/linux/simple-atomic/simerr rename : tests/quick/02.insttest/ref/sparc/linux/simple-atomic/stdout => tests/quick/02.insttest/ref/sparc/linux/simple-atomic/simout rename : tests/quick/02.insttest/ref/sparc/linux/simple-atomic/m5stats.txt => tests/quick/02.insttest/ref/sparc/linux/simple-atomic/stats.txt rename : tests/quick/02.insttest/ref/sparc/linux/simple-timing/stderr => tests/quick/02.insttest/ref/sparc/linux/simple-timing/simerr rename : tests/quick/02.insttest/ref/sparc/linux/simple-timing/stdout => tests/quick/02.insttest/ref/sparc/linux/simple-timing/simout rename : tests/quick/02.insttest/ref/sparc/linux/simple-timing/m5stats.txt => tests/quick/02.insttest/ref/sparc/linux/simple-timing/stats.txt rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/stderr => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/simerr rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/stdout => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/simout rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/m5stats.txt => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic-dual/stats.txt rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/stderr => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/simerr rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/stdout => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/simout rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/m5stats.txt => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-atomic/stats.txt rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/stderr => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/simerr rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/stdout => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/simout rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/m5stats.txt => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing-dual/stats.txt rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/stderr => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/simerr rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/stdout => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/simout rename : tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/m5stats.txt => tests/quick/10.linux-boot/ref/alpha/linux/tsunami-simple-timing/stats.txt rename : tests/quick/20.eio-short/ref/alpha/eio/detailed/stderr => tests/quick/20.eio-short/ref/alpha/eio/detailed/simerr rename : tests/quick/20.eio-short/ref/alpha/eio/detailed/stdout => tests/quick/20.eio-short/ref/alpha/eio/detailed/simout rename : tests/quick/20.eio-short/ref/alpha/eio/detailed/m5stats.txt => tests/quick/20.eio-short/ref/alpha/eio/detailed/stats.txt rename : tests/quick/20.eio-short/ref/alpha/eio/simple-atomic/stderr => tests/quick/20.eio-short/ref/alpha/eio/simple-atomic/simerr rename : tests/quick/20.eio-short/ref/alpha/eio/simple-atomic/stdout => tests/quick/20.eio-short/ref/alpha/eio/simple-atomic/simout rename : tests/quick/20.eio-short/ref/alpha/eio/simple-atomic/m5stats.txt => tests/quick/20.eio-short/ref/alpha/eio/simple-atomic/stats.txt rename : tests/quick/20.eio-short/ref/alpha/eio/simple-timing/stderr => tests/quick/20.eio-short/ref/alpha/eio/simple-timing/simerr rename : tests/quick/20.eio-short/ref/alpha/eio/simple-timing/stdout => tests/quick/20.eio-short/ref/alpha/eio/simple-timing/simout rename : tests/quick/20.eio-short/ref/alpha/eio/simple-timing/m5stats.txt => tests/quick/20.eio-short/ref/alpha/eio/simple-timing/stats.txt rename : tests/quick/30.eio-mp/ref/alpha/eio/simple-atomic-mp/stderr => tests/quick/30.eio-mp/ref/alpha/eio/simple-atomic-mp/simerr rename : tests/quick/30.eio-mp/ref/alpha/eio/simple-atomic-mp/stdout => tests/quick/30.eio-mp/ref/alpha/eio/simple-atomic-mp/simout rename : tests/quick/30.eio-mp/ref/alpha/eio/simple-atomic-mp/m5stats.txt => tests/quick/30.eio-mp/ref/alpha/eio/simple-atomic-mp/stats.txt rename : tests/quick/30.eio-mp/ref/alpha/eio/simple-timing-mp/stderr => tests/quick/30.eio-mp/ref/alpha/eio/simple-timing-mp/simerr rename : tests/quick/30.eio-mp/ref/alpha/eio/simple-timing-mp/stdout => tests/quick/30.eio-mp/ref/alpha/eio/simple-timing-mp/simout rename : tests/quick/30.eio-mp/ref/alpha/eio/simple-timing-mp/m5stats.txt => tests/quick/30.eio-mp/ref/alpha/eio/simple-timing-mp/stats.txt rename : tests/quick/50.memtest/ref/alpha/linux/memtest/stderr => tests/quick/50.memtest/ref/alpha/linux/memtest/simerr rename : tests/quick/50.memtest/ref/alpha/linux/memtest/stdout => tests/quick/50.memtest/ref/alpha/linux/memtest/simout rename : tests/quick/50.memtest/ref/alpha/linux/memtest/m5stats.txt => tests/quick/50.memtest/ref/alpha/linux/memtest/stats.txt rename : tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/stderr => tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/simerr rename : tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/stdout => tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/simout rename : tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/m5stats.txt => tests/quick/80.netperf-stream/ref/alpha/linux/twosys-tsunami-simple-atomic/stats.txt --- src/python/m5/main.py | 9 +++++++-- src/python/m5/simulate.py | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index d34cca357..4853c8908 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -78,7 +78,7 @@ add_option('-N', "--release-notes", action="store_true", default=False, help="Show the release notes") # Options for configuring the base simulator -add_option('-d', "--outdir", metavar="DIR", default=".", +add_option('-d', "--outdir", metavar="DIR", default="m5out", help="Set the output directory to DIR [Default: %default]") add_option('-r', "--redirect-stdout", action="store_true", default=False, help="Redirect stdout (& stderr, without -e) to file") @@ -101,9 +101,14 @@ add_option('-v', "--verbose", action="count", default=0, # Statistics options set_group("Statistics Options") -add_option("--stats-file", metavar="FILE", default="m5stats.txt", +add_option("--stats-file", metavar="FILE", default="stats.txt", help="Sets the output file for statistics [Default: %default]") +# Configuration Options +set_group("Configuration Options") +add_option("--dump-config", metavar="FILE", default="config.ini", + help="Dump configuration output file [Default: %default]") + # Debugging options set_group("Debugging Options") add_option("--debug-break", metavar="TIME[,TIME]", action='append', split=',', diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index e4dbd5784..617ac3be2 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -46,9 +46,10 @@ def instantiate(root): root.unproxy_all() - ini_file = file(os.path.join(options.outdir, 'config.ini'), 'w') - root.print_ini(ini_file) - ini_file.close() # close config.ini + if options.dump_config: + ini_file = file(os.path.join(options.outdir, options.dump_config), 'w') + root.print_ini(ini_file) + ini_file.close() # Initialize the global statistics internal.stats.initSimStats() -- cgit v1.2.3 From f15f252d4e45f74a3b6e5ef0a7afacc656480792 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 19 Jan 2009 09:59:13 -0800 Subject: python: Rework how things are imported --- src/python/m5/__init__.py | 18 +++++++++--------- src/python/swig/core.i | 26 ++++++++++++++++---------- 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 7b071bccd..4151d1a13 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -77,18 +77,18 @@ env.update(os.environ) # importing *you*). try: import internal - running_m5 = True except ImportError: - running_m5 = False + internal = None -if running_m5: - import defines - build_env.update(defines.m5_build_env) -else: - import __scons - build_env.update(__scons.m5_build_env) +import defines +build_env.update(defines.buildEnv) + +if internal: + defines.compileDate = internal.core.compileDate + for k,v in internal.core.__dict__.iteritems(): + if k.startswith('flag_'): + setattr(defines, k[5:], v) -if running_m5: from event import * from simulate import * from main import options, main diff --git a/src/python/swig/core.i b/src/python/swig/core.i index 566998639..c567bea4d 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -41,15 +41,24 @@ #include "sim/startup.hh" extern const char *compileDate; -std::vector compileFlags(); -extern const char *hgRev; -extern const char *hgDate; + +#ifdef DEBUG +const bool flag_DEBUG = true; +#else +const bool flag_DEBUG = false; +#endif +#ifdef NDEBUG +const bool flag_NDEBUG = true; +#else +const bool flag_NDEBUG = false; +#endif +const bool flag_TRACING_ON = TRACING_ON; + inline void disableAllListeners() { ListenSocket::disableAll(); } %} %include "stdint.i" %include "std_string.i" -%include "std_vector.i" %include "sim/host.hh" void setOutputDir(const std::string &dir); @@ -59,12 +68,9 @@ void disableAllListeners(); %immutable compileDate; char *compileDate; - -namespace std { %template(StringVector) vector; } -std::vector compileFlags(); - -char *hgRev; -char *hgDate; +const bool flag_DEBUG; +const bool flag_NDEBUG; +const bool flag_TRACING_ON; void setClockFrequency(Tick ticksPerSecond); -- cgit v1.2.3 From 0876c822dd25e57e8811ceb31f67a3536c9855b0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 19 Jan 2009 09:59:13 -0800 Subject: tracing: panic() if people try to use tracing, but TRACING_ON is not set. Also clean things up so that help strings can more easily be added. Move the help function into trace.py --- src/python/SConscript | 1 + src/python/m5/main.py | 44 +++++++++++++++++++------------------------- src/python/m5/trace.py | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 src/python/m5/trace.py (limited to 'src/python') diff --git a/src/python/SConscript b/src/python/SConscript index 94119c77d..726254c1d 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -48,6 +48,7 @@ PySource('m5', 'm5/simulate.py') PySource('m5', 'm5/smartdict.py') PySource('m5', 'm5/stats.py') PySource('m5', 'm5/ticks.py') +PySource('m5', 'm5/trace.py') PySource('m5.util', 'm5/util/__init__.py') PySource('m5.util', 'm5/util/attrdict.py') PySource('m5.util', 'm5/util/jobfile.py') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 4853c8908..4e9714705 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -138,6 +138,13 @@ def main(): import event import info import internal + import trace + + def check_tracing(): + if defines.TRACING_ON: + return + + panic("Tracing is not enabled. Compile with TRACING_ON") # load the options.py config file to allow people to set their own # default options @@ -221,21 +228,9 @@ def main(): print if options.trace_help: - import traceflags - done = True - print "Base Flags:" - traceflags.baseFlags.sort() - print_list(traceflags.baseFlags, indent=4) - print - print "Compound Flags:" - traceflags.compoundFlags.sort() - for flag in traceflags.compoundFlags: - if flag == 'All': - continue - print " %s:" % flag - print_list(traceflags.compoundFlagMap[flag], indent=8) - print + check_tracing() + trace.help() if options.list_sim_objects: import SimObject @@ -306,7 +301,7 @@ def main(): internal.debug.schedBreakCycle(int(when)) if options.trace_flags: - import traceflags + check_tracing() on_flags = [] off_flags = [] @@ -315,7 +310,7 @@ def main(): if flag.startswith('-'): flag = flag[1:] off = True - if flag not in traceflags.allFlags and flag != "All": + if flag not in trace.flags.all and flag != "All": print >>sys.stderr, "invalid trace flag '%s'" % flag sys.exit(1) @@ -325,24 +320,23 @@ def main(): on_flags.append(flag) for flag in on_flags: - internal.trace.set(flag) + trace.set(flag) for flag in off_flags: - internal.trace.clear(flag) + trace.clear(flag) if options.trace_start: - def enable_trace(): - internal.trace.cvar.enabled = True - - e = event.create(enable_trace) + check_tracing() + e = event.create(trace.enable) event.mainq.schedule(e, options.trace_start) else: - internal.trace.cvar.enabled = True + trace.enable() - internal.trace.output(options.trace_file) + trace.output(options.trace_file) for ignore in options.trace_ignore: - internal.trace.ignore(ignore) + check_tracing() + trace.ignore(ignore) sys.argv = arguments sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py new file mode 100644 index 000000000..9e2351dbe --- /dev/null +++ b/src/python/m5/trace.py @@ -0,0 +1,20 @@ +import internal +import traceflags as flags + +from internal.trace import clear, output, set, ignore + +def enable(): + internal.trace.cvar.enabled = True + +def help(): + print "Base Flags:" + for flag in trace.flags.basic: + print " %s: %s" % (flag, trace.flags.descriptions[flag]) + print + print "Compound Flags:" + for flag in trace.flags.compound: + if flag == 'All': + continue + print " %s: %s" % (flag, trace.flags.descriptions[flag]) + print_list(trace.flags.compoundMap[flag], indent=8) + print -- cgit v1.2.3 From da14789c32e14c62cdb0e11957607955e2a19c8a Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 19 Jan 2009 09:59:15 -0800 Subject: python: Try to isolate the stuff that's in the m5.internal package a bit more. --- src/python/SConscript | 2 ++ src/python/m5/__init__.py | 1 + src/python/m5/core.py | 5 +++++ src/python/m5/debug.py | 3 +++ src/python/m5/main.py | 34 +++++++++++++++++----------------- 5 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 src/python/m5/core.py create mode 100644 src/python/m5/debug.py (limited to 'src/python') diff --git a/src/python/SConscript b/src/python/SConscript index 726254c1d..a767545ec 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -39,6 +39,8 @@ PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/SimObject.py') PySource('m5', 'm5/config.py') PySource('m5', 'm5/convert.py') +PySource('m5', 'm5/core.py') +PySource('m5', 'm5/debug.py') PySource('m5', 'm5/event.py') PySource('m5', 'm5/main.py') PySource('m5', 'm5/options.py') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 4151d1a13..3a6d39499 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -93,6 +93,7 @@ if internal: from simulate import * from main import options, main import stats + import core import SimObject import params diff --git a/src/python/m5/core.py b/src/python/m5/core.py new file mode 100644 index 000000000..34590016e --- /dev/null +++ b/src/python/m5/core.py @@ -0,0 +1,5 @@ +import internal + +def setOutputDir(dir): + internal.core.setOutputDir(dir) + diff --git a/src/python/m5/debug.py b/src/python/m5/debug.py new file mode 100644 index 000000000..74c397562 --- /dev/null +++ b/src/python/m5/debug.py @@ -0,0 +1,3 @@ +import internal + +from internal.debug import schedBreakCycle, setRemoteGDBPort diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 4e9714705..19ceaf10d 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -135,9 +135,12 @@ add_option("--list-sim-objects", action='store_true', default=False, help="List all built-in SimObjects, their parameters and default values") def main(): + import core + import debug + import defines import event import info - import internal + import stats import trace def check_tracing(): @@ -185,19 +188,17 @@ def main(): done = False if options.build_info: - import defines - done = True print 'Build information:' print - print 'compiled %s' % internal.core.cvar.compileDate; - print "revision %s" % internal.core.cvar.hgRev - print "commit date %s" % internal.core.cvar.hgDate + print 'compiled %s' % defines.compileDate; + print "revision %s:%s" % (defines.hgRev, defines.hgId) + print "commit date %s" % defines.hgDate print 'build options:' - keys = defines.m5_build_env.keys() + keys = defines.buildEnv.keys() keys.sort() for key in keys: - val = defines.m5_build_env[key] + val = defines.buildEnv[key] print ' %s = %s' % (key, val) print @@ -265,9 +266,10 @@ def main(): print "M5 Simulator System" print brief_copyright print - print "M5 compiled %s" % internal.core.cvar.compileDate; - print "M5 revision %s" % internal.core.cvar.hgRev - print "M5 commit date %s" % internal.core.cvar.hgDate + + print "M5 compiled %s" % defines.compileDate; + print "M5 revision %s:%s" % (defines.hgRev, defines.hgId) + print "M5 commit date %s" % defines.hgDate print "M5 started %s" % datetime.datetime.now().strftime("%b %e %Y %X") print "M5 executing on %s" % socket.gethostname() @@ -285,20 +287,18 @@ def main(): options.usage(2) # tell C++ about output directory - internal.core.setOutputDir(options.outdir) + core.setOutputDir(options.outdir) # update the system path with elements from the -p option sys.path[0:0] = options.path - import objects - # set stats options - internal.stats.initText(options.stats_file) + stats.initText(options.stats_file) # set debugging options - internal.debug.setRemoteGDBPort(options.remote_gdb_port) + debug.setRemoteGDBPort(options.remote_gdb_port) for when in options.debug_break: - internal.debug.schedBreakCycle(int(when)) + debug.schedBreakCycle(int(when)) if options.trace_flags: check_tracing() -- cgit v1.2.3 From 81b8c0c79a0ed55f2d81fc66bf7e4667f708c1de Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 19 Jan 2009 14:43:09 -0800 Subject: python: add fatal() function to the m5 package and use it --- src/python/m5/__init__.py | 11 +++++++++++ src/python/m5/main.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 3a6d39499..97b22ef2a 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -36,10 +36,21 @@ import smartdict MaxTick = 2**63 - 1 # define this here so we can use it right away if necessary + +# panic() should be called when something happens that should never +# ever happen regardless of what the user does (i.e., an acutal m5 +# bug). def panic(string): print >>sys.stderr, 'panic:', string sys.exit(1) +# fatal() should be called when the simulation cannot continue due to +# some condition that is the user's fault (bad configuration, invalid +# arguments, etc.) and not a simulator bug. +def fatal(string): + print >>sys.stderr, 'fatal:', string + sys.exit(1) + # force scalars to one-element lists for uniformity def makeList(objOrList): if isinstance(objOrList, list): diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 19ceaf10d..38adac632 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -147,7 +147,7 @@ def main(): if defines.TRACING_ON: return - panic("Tracing is not enabled. Compile with TRACING_ON") + fatal("Tracing is not enabled. Compile with TRACING_ON") # load the options.py config file to allow people to set their own # default options -- cgit v1.2.3 From 35a85a4e86143c5bf23d5b74c14856792a0a624c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 30 Jan 2009 19:08:13 -0500 Subject: Config: Cause a fatal() when a parameter without a default value isn't set(FS #315). --- src/python/m5/SimObject.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 868f969a6..2b5dd1bc2 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -748,7 +748,8 @@ class SimObject(object): for param in param_names: value = self._values.get(param) if value is None: - continue + m5.fatal("%s.%s without default or user set value" \ + % (self.path(), param)) value = value.getValue() if isinstance(self._params[param], VectorParamDesc): -- cgit v1.2.3 From f4291aac256622546a5a51dce109599007f5b3cb Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 30 Jan 2009 20:04:15 -0500 Subject: Errors: Print a URL with a hash of the format string to find more information about an error. --- src/python/m5/SimObject.py | 4 ++-- src/python/m5/__init__.py | 20 ++++++++++++++++---- src/python/m5/params.py | 4 ++-- 3 files changed, 20 insertions(+), 8 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 2b5dd1bc2..1db9c7495 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -748,8 +748,8 @@ class SimObject(object): for param in param_names: value = self._values.get(param) if value is None: - m5.fatal("%s.%s without default or user set value" \ - % (self.path(), param)) + m5.fatal("%s.%s without default or user set value", + self.path(), param) value = value.getValue() if isinstance(self._params[param], VectorParamDesc): diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 97b22ef2a..733258acf 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -37,18 +37,30 @@ MaxTick = 2**63 - 1 # define this here so we can use it right away if necessary +def errorURL(prefix, s): + try: + import zlib + hashstr = "%x" % zlib.crc32(s) + except: + hashstr = "UnableToHash" + return "For more information see: http://www.m5sim.org/%s/%s" % \ + (prefix, hashstr) + + # panic() should be called when something happens that should never # ever happen regardless of what the user does (i.e., an acutal m5 # bug). -def panic(string): - print >>sys.stderr, 'panic:', string +def panic(fmt, *args): + print >>sys.stderr, 'panic:', fmt % args + print >>sys.stderr, errorURL('panic',fmt) sys.exit(1) # fatal() should be called when the simulation cannot continue due to # some condition that is the user's fault (bad configuration, invalid # arguments, etc.) and not a simulator bug. -def fatal(string): - print >>sys.stderr, 'fatal:', string +def fatal(fmt, *args): + print >>sys.stderr, 'fatal:', fmt % args + print >>sys.stderr, errorURL('fatal',fmt) sys.exit(1) # force scalars to one-element lists for uniformity diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 081bd342e..18eeac0d1 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -327,8 +327,8 @@ class CheckedIntType(MetaParamValue): if not (hasattr(cls, 'min') and hasattr(cls, 'max')): if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): panic("CheckedInt subclass %s must define either\n" \ - " 'min' and 'max' or 'size' and 'unsigned'\n" \ - % name); + " 'min' and 'max' or 'size' and 'unsigned'\n", + name); if cls.unsigned: cls.min = 0 cls.max = 2 ** cls.size - 1 -- cgit v1.2.3 From be5d350afc829acf87aad5e8701f3f67476edc8b Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 30 Jan 2009 20:04:57 -0500 Subject: SCons: Fix how we get Mercurial revision information since internals keep changing. --- src/python/m5/main.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 38adac632..3edeccc10 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -192,8 +192,7 @@ def main(): print 'Build information:' print print 'compiled %s' % defines.compileDate; - print "revision %s:%s" % (defines.hgRev, defines.hgId) - print "commit date %s" % defines.hgDate + print "revision %s" % defines.hgRev print 'build options:' keys = defines.buildEnv.keys() keys.sort() @@ -268,8 +267,7 @@ def main(): print print "M5 compiled %s" % defines.compileDate; - print "M5 revision %s:%s" % (defines.hgRev, defines.hgId) - print "M5 commit date %s" % defines.hgDate + print "M5 revision %s" % defines.hgRev print "M5 started %s" % datetime.datetime.now().strftime("%b %e %Y %X") print "M5 executing on %s" % socket.gethostname() -- cgit v1.2.3 From 64eb0dc9cdd22b8c1e55ff7faaae1cae83c0a1a9 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 4 Feb 2009 16:26:15 -0800 Subject: some new files are missing copyright notices --- src/python/m5/core.py | 28 ++++++++++++++++++++++++++++ src/python/m5/debug.py | 28 ++++++++++++++++++++++++++++ src/python/m5/trace.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) (limited to 'src/python') diff --git a/src/python/m5/core.py b/src/python/m5/core.py index 34590016e..232fe2ceb 100644 --- a/src/python/m5/core.py +++ b/src/python/m5/core.py @@ -1,3 +1,31 @@ +# 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 + import internal def setOutputDir(dir): diff --git a/src/python/m5/debug.py b/src/python/m5/debug.py index 74c397562..cd40b8fa3 100644 --- a/src/python/m5/debug.py +++ b/src/python/m5/debug.py @@ -1,3 +1,31 @@ +# 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 + import internal from internal.debug import schedBreakCycle, setRemoteGDBPort diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py index 9e2351dbe..c97263c9b 100644 --- a/src/python/m5/trace.py +++ b/src/python/m5/trace.py @@ -1,3 +1,31 @@ +# 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 + import internal import traceflags as flags -- cgit v1.2.3 From e0f425bb94a5b67c1128cc05c490dc78f0841290 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 15 Feb 2009 20:39:12 -0800 Subject: traceflags: fix --trace-help --- src/python/m5/main.py | 13 ------------- src/python/m5/trace.py | 11 ++++++----- src/python/m5/util/__init__.py | 13 +++++++++++++ 3 files changed, 19 insertions(+), 18 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 3edeccc10..09847c093 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -38,19 +38,6 @@ from options import OptionParser __all__ = [ 'options', 'arguments', 'main' ] -def print_list(items, indent=4): - line = ' ' * indent - for i,item in enumerate(items): - if len(line) + len(item) > 76: - print line - line = ' ' * indent - - if i < len(items) - 1: - line += '%s, ' % item - else: - line += item - print line - usage="%prog [m5 options] script.py [script options]" version="%prog 2.0" brief_copyright=''' diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py index c97263c9b..14bab77a3 100644 --- a/src/python/m5/trace.py +++ b/src/python/m5/trace.py @@ -28,6 +28,7 @@ import internal import traceflags as flags +import util from internal.trace import clear, output, set, ignore @@ -36,13 +37,13 @@ def enable(): def help(): print "Base Flags:" - for flag in trace.flags.basic: - print " %s: %s" % (flag, trace.flags.descriptions[flag]) + for flag in flags.basic: + print " %s: %s" % (flag, flags.descriptions[flag]) print print "Compound Flags:" - for flag in trace.flags.compound: + for flag in flags.compound: if flag == 'All': continue - print " %s: %s" % (flag, trace.flags.descriptions[flag]) - print_list(trace.flags.compoundMap[flag], indent=8) + print " %s: %s" % (flag, flags.descriptions[flag]) + util.print_list(flags.compoundMap[flag], indent=8) print diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py index f82de696a..5c4a066c6 100644 --- a/src/python/m5/util/__init__.py +++ b/src/python/m5/util/__init__.py @@ -30,3 +30,16 @@ from attrdict import attrdict, optiondict from misc import * from multidict import multidict import jobfile + +def print_list(items, indent=4): + line = ' ' * indent + for i,item in enumerate(items): + if len(line) + len(item) > 76: + print line + line = ' ' * indent + + if i < len(items) - 1: + line += '%s, ' % item + else: + line += item + print line -- cgit v1.2.3 From c41c9cf3a68bbda47b2304daeb145555dd63e5d3 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 18 Feb 2009 10:00:15 -0800 Subject: events: Make trace events happen at the right priority. Also, while we're at it, remember that priorities are in the Event class and add a disable method to disable tracing. --- src/python/m5/event.py | 7 +++++-- src/python/m5/main.py | 2 +- src/python/m5/trace.py | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/event.py b/src/python/m5/event.py index ce003defb..35095599d 100644 --- a/src/python/m5/event.py +++ b/src/python/m5/event.py @@ -35,13 +35,16 @@ mainq = internal.event.cvar.mainEventQueue def create(obj, priority=None): if priority is None: - priority = internal.event.Event.Default_Pri + priority = Event.Default_Pri return PythonEvent(obj, priority) + +# As a reminder, priorities found in sim/eventq.hh are stuck into the +# Event class by swig class Event(PythonEvent): def __init__(self, priority=None): if priority is None: - priority = internal.event.Event.Default_Pri + priority = Event.Default_Pri super(Event, self).__init__(self, priority) class ProgressEvent(Event): diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 09847c093..f562835da 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -312,7 +312,7 @@ def main(): if options.trace_start: check_tracing() - e = event.create(trace.enable) + e = event.create(trace.enable, Event.Trace_Enable_Pri) event.mainq.schedule(e, options.trace_start) else: trace.enable() diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py index 14bab77a3..17aa6196c 100644 --- a/src/python/m5/trace.py +++ b/src/python/m5/trace.py @@ -32,6 +32,9 @@ import util from internal.trace import clear, output, set, ignore +def disable(): + internal.trace.cvar.enabled = False + def enable(): internal.trace.cvar.enabled = True -- cgit v1.2.3 From 894925f1350409c40106aa6a0cc4d5cc31fa2b84 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 26 Feb 2009 19:29:16 -0500 Subject: Trace: fix the --trace-start option --- src/python/m5/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index f562835da..98019b197 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -312,7 +312,7 @@ def main(): if options.trace_start: check_tracing() - e = event.create(trace.enable, Event.Trace_Enable_Pri) + e = event.create(trace.enable, event.Event.Trace_Enable_Pri) event.mainq.schedule(e, options.trace_start) else: trace.enable() -- cgit v1.2.3 From 6fd4bc34a154601ba0a74e41875094c20076e091 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 26 Feb 2009 19:29:17 -0500 Subject: CPA: Add new object for gathering critical path annotations. --- src/python/m5/SimObject.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 1db9c7495..8ef22be4e 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -65,6 +65,7 @@ from params import * # There are a few things we need that aren't in params.__all__ since # normal users don't need them from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector +from proxy import * noDot = False try: @@ -667,7 +668,7 @@ class SimObject(object): match_obj = self._values[pname] if found_obj != None and found_obj != match_obj: raise AttributeError, \ - 'parent.any matched more than one: %s' % obj.path + 'parent.any matched more than one: %s and %s' % (found_obj.path, match_obj.path) found_obj = match_obj return found_obj, found_obj != None -- cgit v1.2.3 From 6f787e3d368eb248aee0854d99ed55e332d80170 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 5 Mar 2009 19:09:53 -0800 Subject: stats: create an enable phase, and a prepare phase. Enable more or less takes the place of check, but also allows stats to do some other configuration. Prepare moves all of the code that readies a stat for dumping into a separate function in preparation for supporting serialization of certain pieces of statistics data. While we're at it, clean up the visitor code and some of the python code. --- src/python/m5/core.py | 7 +++++++ src/python/m5/simulate.py | 14 ++++++++------ src/python/m5/stats.py | 19 ++++++++++++++++--- src/python/swig/stats.i | 3 ++- 4 files changed, 33 insertions(+), 10 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/core.py b/src/python/m5/core.py index 232fe2ceb..1d7985be6 100644 --- a/src/python/m5/core.py +++ b/src/python/m5/core.py @@ -27,7 +27,14 @@ # Authors: Nathan Binkert import internal +from internal.core import initAll, regAllStats def setOutputDir(dir): internal.core.setOutputDir(dir) +def initAll(): + internal.core.initAll() + +def regAllStats(): + internal.core.regAllStats() + diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index 617ac3be2..45992fe85 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -33,6 +33,8 @@ import sys # import the SWIG-wrapped main C++ functions import internal +import core +import stats from main import options import SimObject import ticks @@ -52,23 +54,23 @@ def instantiate(root): ini_file.close() # Initialize the global statistics - internal.stats.initSimStats() + stats.initSimStats() # Create the C++ sim objects and connect ports root.createCCObject() root.connectPorts() # Do a second pass to finish initializing the sim objects - internal.core.initAll() + core.initAll() # Do a third pass to initialize statistics - internal.core.regAllStats() + core.regAllStats() - # Check to make sure that the stats package is properly initialized - internal.stats.check() + # We're done registering statistics. Enable the stats package now. + stats.enable() # Reset to put the stats in a consistent state. - internal.stats.reset() + stats.reset() def doDot(root): dot = pydot.Dot() diff --git a/src/python/m5/stats.py b/src/python/m5/stats.py index 041a3f58d..5bd9d5f6a 100644 --- a/src/python/m5/stats.py +++ b/src/python/m5/stats.py @@ -28,9 +28,6 @@ import internal -from internal.stats import dump -from internal.stats import initSimStats -from internal.stats import reset from internal.stats import StatEvent as event def initText(filename, desc=True, compat=True): @@ -44,3 +41,19 @@ def initMySQL(host, database, user='', passwd='', project='test', name='test', internal.stats.initMySQL(host, database, user, passwd, project, name, sample) + +def initSimStats(): + internal.stats.initSimStats() + +def enable(): + internal.stats.enable() + +def dump(): + # Currently prepare happens in the dump, but we should maybe move + # that out. + + #internal.stats.prepare() + internal.stats.dump() + +def reset(): + internal.stats.reset() diff --git a/src/python/swig/stats.i b/src/python/swig/stats.i index d36f82dbc..284df8ff8 100644 --- a/src/python/swig/stats.i +++ b/src/python/swig/stats.i @@ -48,7 +48,8 @@ void initMySQL(std::string host, std::string database, std::string user, void StatEvent(bool dump, bool reset, Tick when = curTick, Tick repeat = 0); -void check(); +void enable(); +void prepare(); void dump(); void reset(); -- cgit v1.2.3 From 4f1855484c1fe148d66b2dbc2dc0d7964b578c5c Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 7 Mar 2009 16:58:51 -0800 Subject: Fix up regression execution to better handle tests that end abnormally. E.g., mark aborts due to assertion failures as failed tests, but those that get killed by the user as needing to be rerun, etc. --- src/python/m5/config.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/python') diff --git a/src/python/m5/config.py b/src/python/m5/config.py index 7fb531a18..c28f6675a 100644 --- a/src/python/m5/config.py +++ b/src/python/m5/config.py @@ -29,10 +29,18 @@ import os from os.path import isdir, isfile, join as joinpath -homedir = os.environ['HOME'] -confdir = os.environ.get('M5_CONFIG', joinpath(homedir, '.m5')) + +confdir = os.environ.get('M5_CONFIG') + +if not confdir: + # HOME is not set when running regressions, due to use of scons + # Execute() function. + homedir = os.environ.get('HOME') + if homedir and isdir(joinpath(homedir, '.m5')): + confdir = joinpath(homedir, '.m5') + def get(name): - if not isdir(confdir): + if not confdir: return None conffile = joinpath(confdir, name) if not isfile(conffile): -- cgit v1.2.3