Adding gem5 source to svn.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
75
simulators/gem5/src/python/SConscript
Normal file
75
simulators/gem5/src/python/SConscript
Normal file
@ -0,0 +1,75 @@
|
||||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2004-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: Steve Reinhardt
|
||||
# Nathan Binkert
|
||||
|
||||
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')
|
||||
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')
|
||||
PySource('m5', 'm5/params.py')
|
||||
PySource('m5', 'm5/proxy.py')
|
||||
PySource('m5', 'm5/simulate.py')
|
||||
PySource('m5', 'm5/ticks.py')
|
||||
PySource('m5', 'm5/trace.py')
|
||||
PySource('m5.objects', 'm5/objects/__init__.py')
|
||||
PySource('m5.stats', 'm5/stats/__init__.py')
|
||||
PySource('m5.util', 'm5/util/__init__.py')
|
||||
PySource('m5.util', 'm5/util/attrdict.py')
|
||||
PySource('m5.util', 'm5/util/code_formatter.py')
|
||||
PySource('m5.util', 'm5/util/convert.py')
|
||||
PySource('m5.util', 'm5/util/dot_writer.py')
|
||||
PySource('m5.util', 'm5/util/grammar.py')
|
||||
PySource('m5.util', 'm5/util/jobfile.py')
|
||||
PySource('m5.util', 'm5/util/multidict.py')
|
||||
PySource('m5.util', 'm5/util/orderdict.py')
|
||||
PySource('m5.util', 'm5/util/region.py')
|
||||
PySource('m5.util', 'm5/util/smartdict.py')
|
||||
PySource('m5.util', 'm5/util/sorteddict.py')
|
||||
PySource('m5.util', 'm5/util/terminal.py')
|
||||
|
||||
SwigSource('m5.internal', 'swig/core.i')
|
||||
SwigSource('m5.internal', 'swig/debug.i')
|
||||
SwigSource('m5.internal', 'swig/event.i')
|
||||
SwigSource('m5.internal', 'swig/pyobject.i')
|
||||
SwigSource('m5.internal', 'swig/range.i')
|
||||
SwigSource('m5.internal', 'swig/stats.i')
|
||||
SwigSource('m5.internal', 'swig/trace.i')
|
||||
PySource('m5.internal', 'm5/internal/__init__.py')
|
||||
PySource('m5.internal', 'm5/internal/params.py')
|
||||
86
simulators/gem5/src/python/importer.py
Normal file
86
simulators/gem5/src/python/importer.py
Normal file
@ -0,0 +1,86 @@
|
||||
# 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, abspath, modpath, code):
|
||||
if modpath in self.modules:
|
||||
raise AttributeError, "%s already found in importer" % modpath
|
||||
|
||||
self.modules[modpath] = (filename, abspath, 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,abspath,code = self.modules[fullname]
|
||||
|
||||
override = os.environ.get('M5_OVERRIDE_PY_SOURCE', 'false').lower()
|
||||
if override in ('true', 'yes') and os.path.exists(abspath):
|
||||
src = file(abspath, 'r').read()
|
||||
code = compile(src, abspath, 'exec')
|
||||
|
||||
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)
|
||||
1124
simulators/gem5/src/python/m5/SimObject.py
Normal file
1124
simulators/gem5/src/python/m5/SimObject.py
Normal file
File diff suppressed because it is too large
Load Diff
53
simulators/gem5/src/python/m5/__init__.py
Normal file
53
simulators/gem5/src/python/m5/__init__.py
Normal file
@ -0,0 +1,53 @@
|
||||
# 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 useful subpackages of M5, but *only* when run as an m5
|
||||
# script. This is mostly to keep backward compatibility with existing
|
||||
# scripts while allowing new SCons code to operate properly.
|
||||
|
||||
try:
|
||||
# Try to import something that's generated by swig
|
||||
import internal
|
||||
|
||||
# Try to grab something from it in case demandimport is being used
|
||||
internal.core.curTick
|
||||
except ImportError:
|
||||
# The import failed
|
||||
internal = None
|
||||
|
||||
if internal:
|
||||
import SimObject
|
||||
import core
|
||||
import objects
|
||||
import params
|
||||
import stats
|
||||
import util
|
||||
|
||||
from event import *
|
||||
from main import main
|
||||
from simulate import *
|
||||
50
simulators/gem5/src/python/m5/config.py
Normal file
50
simulators/gem5/src/python/m5/config.py
Normal file
@ -0,0 +1,50 @@
|
||||
# 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
|
||||
|
||||
|
||||
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 confdir:
|
||||
return None
|
||||
conffile = joinpath(confdir, name)
|
||||
if not isfile(conffile):
|
||||
return None
|
||||
|
||||
return conffile
|
||||
|
||||
32
simulators/gem5/src/python/m5/core.py
Normal file
32
simulators/gem5/src/python/m5/core.py
Normal file
@ -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
|
||||
|
||||
import internal
|
||||
|
||||
def setOutputDir(dir):
|
||||
internal.core.setOutputDir(dir)
|
||||
105
simulators/gem5/src/python/m5/debug.py
Normal file
105
simulators/gem5/src/python/m5/debug.py
Normal file
@ -0,0 +1,105 @@
|
||||
# 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 UserDict import DictMixin
|
||||
|
||||
import internal
|
||||
|
||||
from internal.debug import SimpleFlag, CompoundFlag
|
||||
from internal.debug import schedBreakCycle, setRemoteGDBPort
|
||||
from m5.util import printList
|
||||
|
||||
def help():
|
||||
print "Base Flags:"
|
||||
for name in sorted(flags):
|
||||
if name == 'All':
|
||||
continue
|
||||
flag = flags[name]
|
||||
children = [c for c in flag.kids() ]
|
||||
if not children:
|
||||
print " %s: %s" % (name, flag.desc())
|
||||
print
|
||||
print "Compound Flags:"
|
||||
for name in sorted(flags):
|
||||
if name == 'All':
|
||||
continue
|
||||
flag = flags[name]
|
||||
children = [c for c in flag.kids() ]
|
||||
if children:
|
||||
print " %s: %s" % (name, flag.desc())
|
||||
printList([ c.name() for c in children ], indent=8)
|
||||
print
|
||||
|
||||
class AllFlags(DictMixin):
|
||||
def __init__(self):
|
||||
self._version = -1
|
||||
self._dict = {}
|
||||
|
||||
def _update(self):
|
||||
current_version = internal.debug.getAllFlagsVersion()
|
||||
if self._version == current_version:
|
||||
return
|
||||
|
||||
self._dict.clear()
|
||||
for flag in internal.debug.getAllFlags():
|
||||
self._dict[flag.name()] = flag
|
||||
self._version = current_version
|
||||
|
||||
def __contains__(self, item):
|
||||
self._update()
|
||||
return item in self._dict
|
||||
|
||||
def __getitem__(self, item):
|
||||
self._update()
|
||||
return self._dict[item]
|
||||
|
||||
def keys(self):
|
||||
self._update()
|
||||
return self._dict.keys()
|
||||
|
||||
def values(self):
|
||||
self._update()
|
||||
return self._dict.values()
|
||||
|
||||
def items(self):
|
||||
self._update()
|
||||
return self._dict.items()
|
||||
|
||||
def iterkeys(self):
|
||||
self._update()
|
||||
return self._dict.iterkeys()
|
||||
|
||||
def itervalues(self):
|
||||
self._update()
|
||||
return self._dict.itervalues()
|
||||
|
||||
def iteritems(self):
|
||||
self._update()
|
||||
return self._dict.iteritems()
|
||||
|
||||
flags = AllFlags()
|
||||
61
simulators/gem5/src/python/m5/event.py
Normal file
61
simulators/gem5/src/python/m5/event.py
Normal file
@ -0,0 +1,61 @@
|
||||
# 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
|
||||
|
||||
import m5
|
||||
import internal.event
|
||||
|
||||
from internal.event import PythonEvent, SimLoopExitEvent as SimExit
|
||||
|
||||
mainq = internal.event.cvar.mainEventQueue
|
||||
|
||||
def create(obj, priority=None):
|
||||
if priority is None:
|
||||
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 = Event.Default_Pri
|
||||
super(Event, 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.eventq.schedule(self, m5.curTick() + self.period)
|
||||
|
||||
__all__ = [ 'create', 'Event', 'ProgressEvent', 'SimExit', 'mainq' ]
|
||||
33
simulators/gem5/src/python/m5/internal/__init__.py
Normal file
33
simulators/gem5/src/python/m5/internal/__init__.py
Normal file
@ -0,0 +1,33 @@
|
||||
# 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
|
||||
|
||||
import core
|
||||
import debug
|
||||
import event
|
||||
import stats
|
||||
import trace
|
||||
37
simulators/gem5/src/python/m5/internal/params.py
Normal file
37
simulators/gem5/src/python/m5/internal/params.py
Normal file
@ -0,0 +1,37 @@
|
||||
# Copyright (c) 2010 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
|
||||
|
||||
try:
|
||||
modules = __loader__.modules
|
||||
except NameError:
|
||||
modules = { }
|
||||
|
||||
for module in modules.iterkeys():
|
||||
if module.startswith('m5.internal.param_') or \
|
||||
module.startswith('m5.internal.enum_'):
|
||||
exec "from %s import *" % module
|
||||
375
simulators/gem5/src/python/m5/main.py
Normal file
375
simulators/gem5/src/python/m5/main.py
Normal file
@ -0,0 +1,375 @@
|
||||
# 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 code
|
||||
import datetime
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
|
||||
__all__ = [ 'options', 'arguments', 'main' ]
|
||||
|
||||
usage="%prog [gem5 options] script.py [script options]"
|
||||
version="%prog 2.0"
|
||||
brief_copyright=\
|
||||
"gem5 is copyrighted software; use the --copyright option for details."
|
||||
|
||||
def parse_options():
|
||||
import config
|
||||
from options import OptionParser
|
||||
|
||||
options = OptionParser(usage=usage, version=version,
|
||||
description=brief_copyright)
|
||||
option = options.add_option
|
||||
group = options.set_group
|
||||
|
||||
# Help options
|
||||
option('-B', "--build-info", action="store_true", default=False,
|
||||
help="Show build information")
|
||||
option('-C', "--copyright", action="store_true", default=False,
|
||||
help="Show full copyright information")
|
||||
option('-R', "--readme", action="store_true", default=False,
|
||||
help="Show the readme")
|
||||
|
||||
# Options for configuring the base simulator
|
||||
option('-d', "--outdir", metavar="DIR", default="m5out",
|
||||
help="Set the output directory to DIR [Default: %default]")
|
||||
option('-r', "--redirect-stdout", action="store_true", default=False,
|
||||
help="Redirect stdout (& stderr, without -e) to file")
|
||||
option('-e', "--redirect-stderr", action="store_true", default=False,
|
||||
help="Redirect stderr to file")
|
||||
option("--stdout-file", metavar="FILE", default="simout",
|
||||
help="Filename for -r redirection [Default: %default]")
|
||||
option("--stderr-file", metavar="FILE", default="simerr",
|
||||
help="Filename for -e redirection [Default: %default]")
|
||||
option('-i', "--interactive", action="store_true", default=False,
|
||||
help="Invoke the interactive interpreter after running the script")
|
||||
option("--pdb", action="store_true", default=False,
|
||||
help="Invoke the python debugger before running the script")
|
||||
option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':',
|
||||
help="Prepend PATH to the system path when invoking the script")
|
||||
option('-q', "--quiet", action="count", default=0,
|
||||
help="Reduce verbosity")
|
||||
option('-v', "--verbose", action="count", default=0,
|
||||
help="Increase verbosity")
|
||||
|
||||
# Statistics options
|
||||
group("Statistics Options")
|
||||
option("--stats-file", metavar="FILE", default="stats.txt",
|
||||
help="Sets the output file for statistics [Default: %default]")
|
||||
|
||||
# Configuration Options
|
||||
group("Configuration Options")
|
||||
option("--dump-config", metavar="FILE", default="config.ini",
|
||||
help="Dump configuration output file [Default: %default]")
|
||||
option("--json-config", metavar="FILE", default="config.json",
|
||||
help="Create JSON output of the configuration [Default: %default]")
|
||||
option("--dot-config", metavar="FILE", default="config.dot",
|
||||
help="Create DOT & pdf outputs of the configuration [Default: %default]")
|
||||
|
||||
# Debugging options
|
||||
group("Debugging Options")
|
||||
option("--debug-break", metavar="TIME[,TIME]", action='append', split=',',
|
||||
help="Cycle to create a breakpoint")
|
||||
option("--debug-help", action='store_true',
|
||||
help="Print help on trace flags")
|
||||
option("--debug-flags", metavar="FLAG[,FLAG]", action='append', split=',',
|
||||
help="Sets the flags for tracing (-FLAG disables a flag)")
|
||||
option("--remote-gdb-port", type='int', default=7000,
|
||||
help="Remote gdb base port (set to 0 to disable listening)")
|
||||
|
||||
# Tracing options
|
||||
group("Trace Options")
|
||||
option("--trace-start", metavar="TIME", type='int',
|
||||
help="Start tracing at TIME (must be in ticks)")
|
||||
option("--trace-file", metavar="FILE", default="cout",
|
||||
help="Sets the output file for tracing [Default: %default]")
|
||||
option("--trace-ignore", metavar="EXPR", action='append', split=':',
|
||||
help="Ignore EXPR sim objects")
|
||||
|
||||
# Help options
|
||||
group("Help Options")
|
||||
option("--list-sim-objects", action='store_true', default=False,
|
||||
help="List all built-in SimObjects, their params and default values")
|
||||
|
||||
# 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()
|
||||
return options,arguments
|
||||
|
||||
def interact(scope):
|
||||
banner = "gem5 Interactive Console"
|
||||
sys.argv = []
|
||||
try:
|
||||
from IPython.Shell import IPShellEmbed
|
||||
ipshell = IPShellEmbed(banner=banner,user_ns=scope)
|
||||
ipshell()
|
||||
except ImportError:
|
||||
code.InteractiveConsole(scope).interact(banner)
|
||||
|
||||
def main(*args):
|
||||
import m5
|
||||
|
||||
import core
|
||||
import debug
|
||||
import defines
|
||||
import event
|
||||
import info
|
||||
import stats
|
||||
import trace
|
||||
|
||||
from util import fatal
|
||||
|
||||
if len(args) == 0:
|
||||
options, arguments = parse_options()
|
||||
elif len(args) == 2:
|
||||
options, arguments = args
|
||||
else:
|
||||
raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args)
|
||||
|
||||
m5.options = options
|
||||
|
||||
def check_tracing():
|
||||
if defines.TRACING_ON:
|
||||
return
|
||||
|
||||
fatal("Tracing is not enabled. Compile with TRACING_ON")
|
||||
|
||||
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:
|
||||
done = True
|
||||
print 'Build information:'
|
||||
print
|
||||
print 'compiled %s' % defines.compileDate;
|
||||
print 'build options:'
|
||||
keys = defines.buildEnv.keys()
|
||||
keys.sort()
|
||||
for key in keys:
|
||||
val = defines.buildEnv[key]
|
||||
print ' %s = %s' % (key, val)
|
||||
print
|
||||
|
||||
if options.copyright:
|
||||
done = True
|
||||
print info.COPYING
|
||||
print
|
||||
|
||||
if options.readme:
|
||||
done = True
|
||||
print 'Readme:'
|
||||
print
|
||||
print info.README
|
||||
print
|
||||
|
||||
if options.debug_help:
|
||||
done = True
|
||||
check_tracing()
|
||||
debug.help()
|
||||
|
||||
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)
|
||||
|
||||
# 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 "gem5 Simulator System. http://gem5.org"
|
||||
print brief_copyright
|
||||
print
|
||||
|
||||
print "gem5 compiled %s" % defines.compileDate;
|
||||
|
||||
print "gem5 started %s" % \
|
||||
datetime.datetime.now().strftime("%b %e %Y %X")
|
||||
print "gem5 executing on %s" % socket.gethostname()
|
||||
|
||||
print "command line:",
|
||||
for argv in sys.argv:
|
||||
print argv,
|
||||
print
|
||||
|
||||
# check to make sure we can find the listed script
|
||||
if not arguments or not os.path.isfile(arguments[0]):
|
||||
if arguments and not os.path.isfile(arguments[0]):
|
||||
print "Script %s not found" % arguments[0]
|
||||
|
||||
options.usage(2)
|
||||
|
||||
# tell C++ about output directory
|
||||
core.setOutputDir(options.outdir)
|
||||
|
||||
# update the system path with elements from the -p option
|
||||
sys.path[0:0] = options.path
|
||||
|
||||
# set stats options
|
||||
stats.initText(options.stats_file)
|
||||
|
||||
# set debugging options
|
||||
debug.setRemoteGDBPort(options.remote_gdb_port)
|
||||
for when in options.debug_break:
|
||||
debug.schedBreakCycle(int(when))
|
||||
|
||||
if options.debug_flags:
|
||||
check_tracing()
|
||||
|
||||
on_flags = []
|
||||
off_flags = []
|
||||
for flag in options.debug_flags:
|
||||
off = False
|
||||
if flag.startswith('-'):
|
||||
flag = flag[1:]
|
||||
off = True
|
||||
|
||||
if flag not in debug.flags:
|
||||
print >>sys.stderr, "invalid debug flag '%s'" % flag
|
||||
sys.exit(1)
|
||||
|
||||
if off:
|
||||
debug.flags[flag].disable()
|
||||
else:
|
||||
debug.flags[flag].enable()
|
||||
|
||||
if options.trace_start:
|
||||
check_tracing()
|
||||
e = event.create(trace.enable, event.Event.Trace_Enable_Pri)
|
||||
event.mainq.schedule(e, options.trace_start)
|
||||
else:
|
||||
trace.enable()
|
||||
|
||||
trace.output(options.trace_file)
|
||||
|
||||
for ignore in options.trace_ignore:
|
||||
check_tracing()
|
||||
trace.ignore(ignore)
|
||||
|
||||
sys.argv = arguments
|
||||
sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
|
||||
|
||||
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
|
||||
if options.interactive or options.pdb:
|
||||
exec "import readline" in scope
|
||||
|
||||
# if pdb was requested, execfile the thing under pdb, otherwise,
|
||||
# just do the execfile normally
|
||||
if options.pdb:
|
||||
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:
|
||||
exec filecode in scope
|
||||
|
||||
# once the script is done
|
||||
if options.interactive:
|
||||
interact(scope)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from pprint import pprint
|
||||
|
||||
options, arguments = parse_options()
|
||||
|
||||
print 'opts:'
|
||||
pprint(options, indent=4)
|
||||
print
|
||||
|
||||
print 'args:'
|
||||
pprint(arguments, indent=4)
|
||||
39
simulators/gem5/src/python/m5/objects/__init__.py
Normal file
39
simulators/gem5/src/python/m5/objects/__init__.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2010 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 m5.internal import params
|
||||
from m5.SimObject import *
|
||||
|
||||
try:
|
||||
modules = __loader__.modules
|
||||
except NameError:
|
||||
modules = { }
|
||||
|
||||
for module in modules.iterkeys():
|
||||
if module.startswith('m5.objects.'):
|
||||
exec "from %s import *" % module
|
||||
142
simulators/gem5/src/python/m5/options.py
Normal file
142
simulators/gem5/src/python/m5/options.py
Normal file
@ -0,0 +1,142 @@
|
||||
# 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
|
||||
|
||||
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(dict):
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs.setdefault('formatter', optparse.TitledHelpFormatter())
|
||||
self._optparse = optparse.OptionParser(*args, **kwargs)
|
||||
self._optparse.disable_interspersed_args()
|
||||
|
||||
self._allopts = {}
|
||||
|
||||
# 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:
|
||||
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)
|
||||
|
||||
option = self._group.add_option(*args, **kwargs)
|
||||
dest = option.dest
|
||||
if dest not in self._allopts:
|
||||
self._allopts[dest] = option
|
||||
|
||||
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).__getattribute__(attr)
|
||||
|
||||
if attr in self:
|
||||
return self[attr]
|
||||
|
||||
return super(OptionParser, self).__getattribute__(attr)
|
||||
|
||||
def __setattr__(self, attr, value):
|
||||
if attr.startswith('_'):
|
||||
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:
|
||||
self[key] = val
|
||||
|
||||
return args
|
||||
|
||||
def usage(self, exitcode=None):
|
||||
self._optparse.print_help()
|
||||
if exitcode is not None:
|
||||
sys.exit(exitcode)
|
||||
|
||||
1644
simulators/gem5/src/python/m5/params.py
Normal file
1644
simulators/gem5/src/python/m5/params.py
Normal file
File diff suppressed because it is too large
Load Diff
228
simulators/gem5/src/python/m5/proxy.py
Normal file
228
simulators/gem5/src/python/m5/proxy.py
Normal file
@ -0,0 +1,228 @@
|
||||
# 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
|
||||
|
||||
#####################################################################
|
||||
#
|
||||
# Proxy object support.
|
||||
#
|
||||
#####################################################################
|
||||
|
||||
import copy
|
||||
|
||||
class BaseProxy(object):
|
||||
def __init__(self, search_self, search_up):
|
||||
self._search_self = search_self
|
||||
self._search_up = search_up
|
||||
self._multiplier = None
|
||||
|
||||
def __str__(self):
|
||||
if self._search_self and not self._search_up:
|
||||
s = 'Self'
|
||||
elif not self._search_self and self._search_up:
|
||||
s = 'Parent'
|
||||
else:
|
||||
s = 'ConfusedProxy'
|
||||
return s + '.' + self.path()
|
||||
|
||||
def __setattr__(self, attr, value):
|
||||
if not attr.startswith('_'):
|
||||
raise AttributeError, \
|
||||
"cannot set attribute '%s' on proxy object" % attr
|
||||
super(BaseProxy, self).__setattr__(attr, value)
|
||||
|
||||
# support multiplying proxies by constants
|
||||
def __mul__(self, other):
|
||||
if not isinstance(other, (int, long, float)):
|
||||
raise TypeError, "Proxy multiplier must be integer"
|
||||
if self._multiplier == None:
|
||||
self._multiplier = other
|
||||
else:
|
||||
# support chained multipliers
|
||||
self._multiplier *= other
|
||||
return self
|
||||
|
||||
__rmul__ = __mul__
|
||||
|
||||
def _mulcheck(self, result):
|
||||
if self._multiplier == None:
|
||||
return result
|
||||
return result * self._multiplier
|
||||
|
||||
def unproxy(self, base):
|
||||
obj = base
|
||||
done = False
|
||||
|
||||
if self._search_self:
|
||||
result, done = self.find(obj)
|
||||
|
||||
if self._search_up:
|
||||
while not done:
|
||||
obj = obj._parent
|
||||
if not obj:
|
||||
break
|
||||
result, done = self.find(obj)
|
||||
|
||||
if not done:
|
||||
raise AttributeError, \
|
||||
"Can't resolve proxy '%s' of type '%s' from '%s'" % \
|
||||
(self.path(), self._pdesc.ptype_str, base.path())
|
||||
|
||||
if isinstance(result, BaseProxy):
|
||||
if result == self:
|
||||
raise RuntimeError, "Cycle in unproxy"
|
||||
result = result.unproxy(obj)
|
||||
|
||||
return self._mulcheck(result)
|
||||
|
||||
def getindex(obj, index):
|
||||
if index == None:
|
||||
return obj
|
||||
try:
|
||||
obj = obj[index]
|
||||
except TypeError:
|
||||
if index != 0:
|
||||
raise
|
||||
# if index is 0 and item is not subscriptable, just
|
||||
# use item itself (so cpu[0] works on uniprocessors)
|
||||
return obj
|
||||
getindex = staticmethod(getindex)
|
||||
|
||||
# This method should be called once the proxy is assigned to a
|
||||
# particular parameter or port to set the expected type of the
|
||||
# resolved proxy
|
||||
def set_param_desc(self, pdesc):
|
||||
self._pdesc = pdesc
|
||||
|
||||
class AttrProxy(BaseProxy):
|
||||
def __init__(self, search_self, search_up, attr):
|
||||
super(AttrProxy, self).__init__(search_self, search_up)
|
||||
self._attr = attr
|
||||
self._modifiers = []
|
||||
|
||||
def __getattr__(self, attr):
|
||||
# python uses __bases__ internally for inheritance
|
||||
if attr.startswith('_'):
|
||||
return super(AttrProxy, self).__getattr__(self, attr)
|
||||
if hasattr(self, '_pdesc'):
|
||||
raise AttributeError, "Attribute reference on bound proxy"
|
||||
# Return a copy of self rather than modifying self in place
|
||||
# since self could be an indirect reference via a variable or
|
||||
# parameter
|
||||
new_self = copy.deepcopy(self)
|
||||
new_self._modifiers.append(attr)
|
||||
return new_self
|
||||
|
||||
# support indexing on proxies (e.g., Self.cpu[0])
|
||||
def __getitem__(self, key):
|
||||
if not isinstance(key, int):
|
||||
raise TypeError, "Proxy object requires integer index"
|
||||
if hasattr(self, '_pdesc'):
|
||||
raise AttributeError, "Index operation on bound proxy"
|
||||
new_self = copy.deepcopy(self)
|
||||
new_self._modifiers.append(key)
|
||||
return new_self
|
||||
|
||||
def find(self, obj):
|
||||
try:
|
||||
val = getattr(obj, self._attr)
|
||||
except:
|
||||
return None, False
|
||||
while isproxy(val):
|
||||
val = val.unproxy(obj)
|
||||
for m in self._modifiers:
|
||||
if isinstance(m, str):
|
||||
val = getattr(val, m)
|
||||
elif isinstance(m, int):
|
||||
val = val[m]
|
||||
else:
|
||||
assert("Item must be string or integer")
|
||||
while isproxy(val):
|
||||
val = val.unproxy(obj)
|
||||
return val, True
|
||||
|
||||
def path(self):
|
||||
p = self._attr
|
||||
for m in self._modifiers:
|
||||
if isinstance(m, str):
|
||||
p += '.%s' % m
|
||||
elif isinstance(m, int):
|
||||
p += '[%d]' % m
|
||||
else:
|
||||
assert("Item must be string or integer")
|
||||
return p
|
||||
|
||||
class AnyProxy(BaseProxy):
|
||||
def find(self, obj):
|
||||
return obj.find_any(self._pdesc.ptype)
|
||||
|
||||
def path(self):
|
||||
return 'any'
|
||||
|
||||
# The AllProxy traverses the entire sub-tree (not only the children)
|
||||
# and adds all objects of a specific type
|
||||
class AllProxy(BaseProxy):
|
||||
def find(self, obj):
|
||||
return obj.find_all(self._pdesc.ptype)
|
||||
|
||||
def path(self):
|
||||
return 'all'
|
||||
|
||||
def isproxy(obj):
|
||||
if isinstance(obj, (BaseProxy, params.EthernetAddr)):
|
||||
return True
|
||||
elif isinstance(obj, (list, tuple)):
|
||||
for v in obj:
|
||||
if isproxy(v):
|
||||
return True
|
||||
return False
|
||||
|
||||
class ProxyFactory(object):
|
||||
def __init__(self, search_self, search_up):
|
||||
self.search_self = search_self
|
||||
self.search_up = search_up
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr == 'any':
|
||||
return AnyProxy(self.search_self, self.search_up)
|
||||
elif attr == 'all':
|
||||
if self.search_up:
|
||||
assert("Parant.all is not supported")
|
||||
return AllProxy(self.search_self, self.search_up)
|
||||
else:
|
||||
return AttrProxy(self.search_self, self.search_up, attr)
|
||||
|
||||
# global objects for handling proxies
|
||||
Parent = ProxyFactory(search_self = False, search_up = True)
|
||||
Self = ProxyFactory(search_self = True, search_up = False)
|
||||
|
||||
# limit exports on 'from proxy import *'
|
||||
__all__ = ['Parent', 'Self']
|
||||
|
||||
# see comment on imports at end of __init__.py.
|
||||
import params # for EthernetAddr
|
||||
233
simulators/gem5/src/python/m5/simulate.py
Normal file
233
simulators/gem5/src/python/m5/simulate.py
Normal file
@ -0,0 +1,233 @@
|
||||
# Copyright (c) 2012 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# Copyright (c) 2005 The Regents of The University of Michigan
|
||||
# Copyright (c) 2010 Advanced Micro Devices, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Nathan Binkert
|
||||
# Steve Reinhardt
|
||||
|
||||
import atexit
|
||||
import os
|
||||
import sys
|
||||
|
||||
# import the SWIG-wrapped main C++ functions
|
||||
import internal
|
||||
import core
|
||||
import stats
|
||||
import SimObject
|
||||
import ticks
|
||||
import objects
|
||||
from m5.util.dot_writer import do_dot
|
||||
|
||||
from util import fatal
|
||||
from util import attrdict
|
||||
|
||||
# define a MaxTick parameter
|
||||
MaxTick = 2**63 - 1
|
||||
|
||||
# The final hook to generate .ini files. Called from the user script
|
||||
# once the config is built.
|
||||
def instantiate(ckpt_dir=None):
|
||||
from m5 import options
|
||||
|
||||
root = objects.Root.getInstance()
|
||||
|
||||
if not root:
|
||||
fatal("Need to instantiate Root() before calling instantiate()")
|
||||
|
||||
# we need to fix the global frequency
|
||||
ticks.fixGlobalFrequency()
|
||||
|
||||
# Make sure SimObject-valued params are in the configuration
|
||||
# hierarchy so we catch them with future descendants() walks
|
||||
for obj in root.descendants(): obj.adoptOrphanParams()
|
||||
|
||||
# Unproxy in sorted order for determinism
|
||||
for obj in root.descendants(): obj.unproxyParams()
|
||||
|
||||
if options.dump_config:
|
||||
ini_file = file(os.path.join(options.outdir, options.dump_config), 'w')
|
||||
# Print ini sections in sorted order for easier diffing
|
||||
for obj in sorted(root.descendants(), key=lambda o: o.path()):
|
||||
obj.print_ini(ini_file)
|
||||
ini_file.close()
|
||||
|
||||
if options.json_config:
|
||||
try:
|
||||
import json
|
||||
json_file = file(os.path.join(options.outdir, options.json_config), 'w')
|
||||
d = root.get_config_as_dict()
|
||||
json.dump(d, json_file, indent=4)
|
||||
json_file.close()
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
do_dot(root, options.outdir, options.dot_config)
|
||||
|
||||
# Initialize the global statistics
|
||||
stats.initSimStats()
|
||||
|
||||
# Create the C++ sim objects and connect ports
|
||||
for obj in root.descendants(): obj.createCCObject()
|
||||
for obj in root.descendants(): obj.connectPorts()
|
||||
|
||||
# Do a second pass to finish initializing the sim objects
|
||||
for obj in root.descendants(): obj.init()
|
||||
|
||||
# Do a third pass to initialize statistics
|
||||
for obj in root.descendants(): obj.regStats()
|
||||
for obj in root.descendants(): obj.regFormulas()
|
||||
|
||||
# We're done registering statistics. Enable the stats package now.
|
||||
stats.enable()
|
||||
|
||||
# Restore checkpoint (if any)
|
||||
if ckpt_dir:
|
||||
ckpt = internal.core.getCheckpoint(ckpt_dir)
|
||||
internal.core.unserializeGlobals(ckpt);
|
||||
for obj in root.descendants(): obj.loadState(ckpt)
|
||||
need_resume.append(root)
|
||||
else:
|
||||
for obj in root.descendants(): obj.initState()
|
||||
|
||||
# Reset to put the stats in a consistent state.
|
||||
stats.reset()
|
||||
|
||||
need_resume = []
|
||||
need_startup = True
|
||||
def simulate(*args, **kwargs):
|
||||
global need_resume, need_startup
|
||||
|
||||
if need_startup:
|
||||
root = objects.Root.getInstance()
|
||||
for obj in root.descendants(): obj.startup()
|
||||
need_startup = False
|
||||
|
||||
for root in need_resume:
|
||||
resume(root)
|
||||
need_resume = []
|
||||
|
||||
return internal.event.simulate(*args, **kwargs)
|
||||
|
||||
# Export curTick to user script.
|
||||
def curTick():
|
||||
return internal.core.curTick()
|
||||
|
||||
# Python exit handlers happen in reverse order. We want to dump stats last.
|
||||
atexit.register(stats.dump)
|
||||
|
||||
# register our C++ exit callback function with Python
|
||||
atexit.register(internal.core.doExitCleanup)
|
||||
|
||||
# This loops until all objects have been fully drained.
|
||||
def doDrain(root):
|
||||
all_drained = drain(root)
|
||||
while (not all_drained):
|
||||
all_drained = drain(root)
|
||||
|
||||
# Tries to drain all objects. Draining might not be completed unless
|
||||
# all objects return that they are drained on the first call. This is
|
||||
# because as objects drain they may cause other objects to no longer
|
||||
# be drained.
|
||||
def drain(root):
|
||||
all_drained = False
|
||||
drain_event = internal.event.createCountedDrain()
|
||||
unready_objs = sum(obj.drain(drain_event) for obj in root.descendants())
|
||||
# If we've got some objects that can't drain immediately, then simulate
|
||||
if unready_objs > 0:
|
||||
drain_event.setCount(unready_objs)
|
||||
simulate()
|
||||
else:
|
||||
all_drained = True
|
||||
internal.event.cleanupCountedDrain(drain_event)
|
||||
return all_drained
|
||||
|
||||
def resume(root):
|
||||
for obj in root.descendants(): obj.resume()
|
||||
|
||||
def checkpoint(dir):
|
||||
root = objects.Root.getInstance()
|
||||
if not isinstance(root, objects.Root):
|
||||
raise TypeError, "Checkpoint must be called on a root object."
|
||||
doDrain(root)
|
||||
print "Writing checkpoint"
|
||||
internal.core.serializeAll(dir)
|
||||
resume(root)
|
||||
|
||||
def changeToAtomic(system):
|
||||
if not isinstance(system, (objects.Root, objects.System)):
|
||||
raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
|
||||
(type(system), objects.Root, objects.System)
|
||||
if system.getMemoryMode() != objects.params.atomic:
|
||||
doDrain(system)
|
||||
print "Changing memory mode to atomic"
|
||||
for obj in system.descendants():
|
||||
obj.changeTiming(objects.params.atomic)
|
||||
|
||||
def changeToTiming(system):
|
||||
if not isinstance(system, (objects.Root, objects.System)):
|
||||
raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
|
||||
(type(system), objects.Root, objects.System)
|
||||
|
||||
if system.getMemoryMode() != objects.params.timing:
|
||||
doDrain(system)
|
||||
print "Changing memory mode to timing"
|
||||
for obj in system.descendants():
|
||||
obj.changeTiming(objects.params.timing)
|
||||
|
||||
def switchCpus(cpuList):
|
||||
print "switching cpus"
|
||||
if not isinstance(cpuList, list):
|
||||
raise RuntimeError, "Must pass a list to this function"
|
||||
for item in cpuList:
|
||||
if not isinstance(item, tuple) or len(item) != 2:
|
||||
raise RuntimeError, "List must have tuples of (oldCPU,newCPU)"
|
||||
|
||||
for old_cpu, new_cpu in cpuList:
|
||||
if not isinstance(old_cpu, objects.BaseCPU):
|
||||
raise TypeError, "%s is not of type BaseCPU" % old_cpu
|
||||
if not isinstance(new_cpu, objects.BaseCPU):
|
||||
raise TypeError, "%s is not of type BaseCPU" % new_cpu
|
||||
|
||||
# Now all of the CPUs are ready to be switched out
|
||||
for old_cpu, new_cpu in cpuList:
|
||||
old_cpu._ccObject.switchOut()
|
||||
|
||||
for old_cpu, new_cpu in cpuList:
|
||||
new_cpu.takeOverFrom(old_cpu)
|
||||
|
||||
from internal.core import disableAllListeners
|
||||
141
simulators/gem5/src/python/m5/stats/__init__.py
Normal file
141
simulators/gem5/src/python/m5/stats/__init__.py
Normal file
@ -0,0 +1,141 @@
|
||||
# Copyright (c) 2007 The Regents of The University of Michigan
|
||||
# Copyright (c) 2010 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 m5
|
||||
|
||||
from m5 import internal
|
||||
from m5.internal.stats import schedStatEvent as schedEvent
|
||||
from m5.objects import Root
|
||||
from m5.util import attrdict, fatal
|
||||
|
||||
outputList = []
|
||||
def initText(filename, desc=True):
|
||||
output = internal.stats.initText(filename, desc)
|
||||
outputList.append(output)
|
||||
|
||||
def initSimStats():
|
||||
internal.stats.initSimStats()
|
||||
|
||||
names = []
|
||||
stats_dict = {}
|
||||
stats_list = []
|
||||
raw_stats_list = []
|
||||
def enable():
|
||||
'''Enable the statistics package. Before the statistics package is
|
||||
enabled, all statistics must be created and initialized and once
|
||||
the package is enabled, no more statistics can be created.'''
|
||||
__dynamic_cast = []
|
||||
for k, v in internal.stats.__dict__.iteritems():
|
||||
if k.startswith('dynamic_'):
|
||||
__dynamic_cast.append(v)
|
||||
|
||||
for stat in internal.stats.statsList():
|
||||
for cast in __dynamic_cast:
|
||||
val = cast(stat)
|
||||
if val is not None:
|
||||
stats_list.append(val)
|
||||
raw_stats_list.append(val)
|
||||
break
|
||||
else:
|
||||
fatal("unknown stat type %s", stat)
|
||||
|
||||
for stat in stats_list:
|
||||
if not stat.check() or not stat.baseCheck():
|
||||
fatal("stat check failed for '%s' %d\n", stat.name, stat.id)
|
||||
|
||||
if not (stat.flags & flags.display):
|
||||
stat.name = "__Stat%06d" % stat.id
|
||||
|
||||
def less(stat1, stat2):
|
||||
v1 = stat1.name.split('.')
|
||||
v2 = stat2.name.split('.')
|
||||
return v1 < v2
|
||||
|
||||
stats_list.sort(less)
|
||||
for stat in stats_list:
|
||||
stats_dict[stat.name] = stat
|
||||
stat.enable()
|
||||
|
||||
internal.stats.enable();
|
||||
|
||||
def prepare():
|
||||
'''Prepare all stats for data access. This must be done before
|
||||
dumping and serialization.'''
|
||||
|
||||
for stat in stats_list:
|
||||
stat.prepare()
|
||||
|
||||
lastDump = 0
|
||||
def dump():
|
||||
'''Dump all statistics data to the registered outputs'''
|
||||
|
||||
curTick = m5.curTick()
|
||||
|
||||
global lastDump
|
||||
assert lastDump <= curTick
|
||||
if lastDump == curTick:
|
||||
return
|
||||
lastDump = curTick
|
||||
|
||||
internal.stats.processDumpQueue()
|
||||
|
||||
prepare()
|
||||
|
||||
for output in outputList:
|
||||
if output.valid():
|
||||
output.begin()
|
||||
for stat in stats_list:
|
||||
output.visit(stat)
|
||||
output.end()
|
||||
|
||||
def reset():
|
||||
'''Reset all statistics to the base state'''
|
||||
|
||||
# call reset stats on all SimObjects
|
||||
root = Root.getInstance()
|
||||
if root:
|
||||
for obj in root.descendants(): obj.resetStats()
|
||||
|
||||
# call any other registered stats reset callbacks
|
||||
for stat in stats_list:
|
||||
stat.reset()
|
||||
|
||||
internal.stats.processResetQueue()
|
||||
|
||||
flags = attrdict({
|
||||
'none' : 0x0000,
|
||||
'init' : 0x0001,
|
||||
'display' : 0x0002,
|
||||
'total' : 0x0010,
|
||||
'pdf' : 0x0020,
|
||||
'cdf' : 0x0040,
|
||||
'dist' : 0x0080,
|
||||
'nozero' : 0x0100,
|
||||
'nonan' : 0x0200,
|
||||
})
|
||||
89
simulators/gem5/src/python/m5/ticks.py
Normal file
89
simulators/gem5/src/python/m5/ticks.py
Normal file
@ -0,0 +1,89 @@
|
||||
# Copyright (c) 2007 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
|
||||
|
||||
tps = 1.0e12 # default to 1 THz (1 Tick == 1 ps)
|
||||
tps_fixed = False # once set to true, can't be changed
|
||||
|
||||
# fix the global frequency and tell C++ about it
|
||||
def fixGlobalFrequency():
|
||||
import internal
|
||||
global tps, tps_fixed
|
||||
if not tps_fixed:
|
||||
tps_fixed = True
|
||||
internal.core.setClockFrequency(int(tps))
|
||||
print "Global frequency set at %d ticks per second" % int(tps)
|
||||
|
||||
def setGlobalFrequency(ticksPerSecond):
|
||||
from m5.util import convert
|
||||
|
||||
global tps, tps_fixed
|
||||
|
||||
if tps_fixed:
|
||||
raise AttributeError, \
|
||||
"Global frequency already fixed at %f ticks/s." % tps
|
||||
|
||||
if isinstance(ticksPerSecond, (int, long)):
|
||||
tps = ticksPerSecond
|
||||
elif isinstance(ticksPerSecond, float):
|
||||
tps = ticksPerSecond
|
||||
elif isinstance(ticksPerSecond, str):
|
||||
tps = round(convert.anyToFrequency(ticksPerSecond))
|
||||
else:
|
||||
raise TypeError, \
|
||||
"wrong type '%s' for ticksPerSecond" % type(ticksPerSecond)
|
||||
|
||||
# how big does a rounding error need to be before we warn about it?
|
||||
frequency_tolerance = 0.001 # 0.1%
|
||||
|
||||
def fromSeconds(value):
|
||||
if not isinstance(value, float):
|
||||
raise TypeError, "can't convert '%s' to type tick" % type(value)
|
||||
|
||||
# once someone needs to convert to seconds, the global frequency
|
||||
# had better be fixed
|
||||
if not tps_fixed:
|
||||
raise AttributeError, \
|
||||
"In order to do conversions, the global frequency must be fixed"
|
||||
|
||||
if value == 0:
|
||||
return 0
|
||||
|
||||
# convert the value from time to ticks
|
||||
value *= tps
|
||||
|
||||
int_value = int(round(value))
|
||||
err = (value - int_value) / value
|
||||
if err > frequency_tolerance:
|
||||
print >>sys.stderr, "Warning: rounding error > tolerance"
|
||||
print >>sys.stderr, " %f rounded to %d" % (value, int_value)
|
||||
return int_value
|
||||
|
||||
__all__ = [ 'setGlobalFrequency', 'fixGlobalFrequency', 'fromSeconds',
|
||||
'frequency_tolerance' ]
|
||||
38
simulators/gem5/src/python/m5/trace.py
Normal file
38
simulators/gem5/src/python/m5/trace.py
Normal file
@ -0,0 +1,38 @@
|
||||
# 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 util
|
||||
|
||||
from internal.trace import output, ignore
|
||||
|
||||
def disable():
|
||||
internal.trace.cvar.enabled = False
|
||||
|
||||
def enable():
|
||||
internal.trace.cvar.enabled = True
|
||||
187
simulators/gem5/src/python/m5/util/__init__.py
Normal file
187
simulators/gem5/src/python/m5/util/__init__.py
Normal file
@ -0,0 +1,187 @@
|
||||
# Copyright (c) 2008-2009 The Hewlett-Packard Development Company
|
||||
# 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 os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import convert
|
||||
import jobfile
|
||||
|
||||
from attrdict import attrdict, multiattrdict, optiondict
|
||||
from code_formatter import code_formatter
|
||||
from multidict import multidict
|
||||
from orderdict import orderdict
|
||||
from smartdict import SmartDict
|
||||
from sorteddict import SortedDict
|
||||
from region import neg_inf, pos_inf, Region, Regions
|
||||
|
||||
# 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(fmt, *args):
|
||||
print >>sys.stderr, 'panic:', fmt % args
|
||||
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(fmt, *args):
|
||||
print >>sys.stderr, 'fatal:', fmt % args
|
||||
sys.exit(1)
|
||||
|
||||
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
|
||||
|
||||
def addToPath(path):
|
||||
"""Prepend given directory to system module search path. We may not
|
||||
need this anymore if we can structure our config library more like a
|
||||
Python package."""
|
||||
|
||||
# if it's a relative path and we know what directory the current
|
||||
# python script is in, make the path relative to that directory.
|
||||
if not os.path.isabs(path) and sys.path[0]:
|
||||
path = os.path.join(sys.path[0], path)
|
||||
path = os.path.realpath(path)
|
||||
# sys.path[0] should always refer to the current script's directory,
|
||||
# so place the new dir right after that.
|
||||
sys.path.insert(1, path)
|
||||
|
||||
# Apply method to object.
|
||||
# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
|
||||
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 compareVersions(v1, v2):
|
||||
"""helper function: compare arrays or strings of version numbers.
|
||||
E.g., compare_version((1,3,25), (1,4,1)')
|
||||
returns -1, 0, 1 if v1 is <, ==, > v2
|
||||
"""
|
||||
def make_version_list(v):
|
||||
if isinstance(v, (list,tuple)):
|
||||
return v
|
||||
elif isinstance(v, str):
|
||||
return map(lambda x: int(re.match('\d+', x).group()), v.split('.'))
|
||||
else:
|
||||
raise TypeError
|
||||
|
||||
v1 = make_version_list(v1)
|
||||
v2 = make_version_list(v2)
|
||||
# Compare corresponding elements of lists
|
||||
for n1,n2 in zip(v1, v2):
|
||||
if n1 < n2: return -1
|
||||
if n1 > n2: return 1
|
||||
# all corresponding values are equal... see if one has extra values
|
||||
if len(v1) < len(v2): return -1
|
||||
if len(v1) > len(v2): return 1
|
||||
return 0
|
||||
|
||||
def crossproduct(items):
|
||||
if len(items) == 1:
|
||||
for i in items[0]:
|
||||
yield (i,)
|
||||
else:
|
||||
for i in items[0]:
|
||||
for j in crossproduct(items[1:]):
|
||||
yield (i,) + j
|
||||
|
||||
def flatten(items):
|
||||
while items:
|
||||
item = items.pop(0)
|
||||
if isinstance(item, (list, tuple)):
|
||||
items[0:0] = item
|
||||
else:
|
||||
yield item
|
||||
|
||||
# force scalars to one-element lists for uniformity
|
||||
def makeList(objOrList):
|
||||
if isinstance(objOrList, list):
|
||||
return objOrList
|
||||
return [objOrList]
|
||||
|
||||
def printList(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
|
||||
|
||||
def readCommand(cmd, **kwargs):
|
||||
"""run the command cmd, read the results and return them
|
||||
this is sorta like `cmd` in shell"""
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
if isinstance(cmd, str):
|
||||
cmd = cmd.split()
|
||||
|
||||
no_exception = 'exception' in kwargs
|
||||
exception = kwargs.pop('exception', None)
|
||||
|
||||
kwargs.setdefault('shell', False)
|
||||
kwargs.setdefault('stdout', PIPE)
|
||||
kwargs.setdefault('stderr', STDOUT)
|
||||
kwargs.setdefault('close_fds', True)
|
||||
try:
|
||||
subp = Popen(cmd, **kwargs)
|
||||
except Exception, e:
|
||||
if no_exception:
|
||||
return exception
|
||||
raise
|
||||
|
||||
return subp.communicate()[0]
|
||||
|
||||
def makeDir(path):
|
||||
"""Make a directory if it doesn't exist. If the path does exist,
|
||||
ensure that it is a directory"""
|
||||
if os.path.exists(path):
|
||||
if not os.path.isdir(path):
|
||||
raise AttributeError, "%s exists but is not directory" % path
|
||||
else:
|
||||
os.mkdir(path)
|
||||
100
simulators/gem5/src/python/m5/util/attrdict.py
Normal file
100
simulators/gem5/src/python/m5/util/attrdict.py
Normal file
@ -0,0 +1,100 @@
|
||||
# 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', '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) or attr.startswith('_'):
|
||||
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)
|
||||
|
||||
def __getstate__(self):
|
||||
return dict(self)
|
||||
|
||||
def __setstate__(self, state):
|
||||
self.update(state)
|
||||
|
||||
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:
|
||||
if attr.startswith('_'):
|
||||
raise
|
||||
|
||||
d = multiattrdict()
|
||||
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:
|
||||
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)
|
||||
|
||||
print
|
||||
print "multiattrdict"
|
||||
x = multiattrdict()
|
||||
x.x.x.x = 9
|
||||
x.y.z = 9
|
||||
print x
|
||||
print x.y
|
||||
print x.y.z
|
||||
print x.z.z
|
||||
315
simulators/gem5/src/python/m5/util/code_formatter.py
Normal file
315
simulators/gem5/src/python/m5/util/code_formatter.py
Normal file
@ -0,0 +1,315 @@
|
||||
# Copyright (c) 2006-2009 Nathan Binkert <nate@binkert.org>
|
||||
# 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.
|
||||
|
||||
import __builtin__
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
|
||||
class lookup(object):
|
||||
def __init__(self, formatter, frame, *args, **kwargs):
|
||||
self.frame = frame
|
||||
self.formatter = formatter
|
||||
self.dict = self.formatter._dict
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.locals = {}
|
||||
|
||||
def __setitem__(self, item, val):
|
||||
self.locals[item] = val
|
||||
|
||||
def __getitem__(self, item):
|
||||
if item in self.locals:
|
||||
return self.locals[item]
|
||||
|
||||
if item in self.kwargs:
|
||||
return self.kwargs[item]
|
||||
|
||||
if item == '__file__':
|
||||
return self.frame.f_code.co_filename
|
||||
|
||||
if item == '__line__':
|
||||
return self.frame.f_lineno
|
||||
|
||||
if self.formatter.locals and item in self.frame.f_locals:
|
||||
return self.frame.f_locals[item]
|
||||
|
||||
if item in self.dict:
|
||||
return self.dict[item]
|
||||
|
||||
if self.formatter.globals and item in self.frame.f_globals:
|
||||
return self.frame.f_globals[item]
|
||||
|
||||
if item in __builtin__.__dict__:
|
||||
return __builtin__.__dict__[item]
|
||||
|
||||
try:
|
||||
item = int(item)
|
||||
return self.args[item]
|
||||
except ValueError:
|
||||
pass
|
||||
raise IndexError, "Could not find '%s'" % item
|
||||
|
||||
class code_formatter_meta(type):
|
||||
pattern = r"""
|
||||
(?:
|
||||
%(delim)s(?P<escaped>%(delim)s) | # escaped delimiter
|
||||
^(?P<indent>[ ]*)%(delim)s(?P<lone>%(ident)s)$ | # lone identifier
|
||||
%(delim)s(?P<ident>%(ident)s) | # identifier
|
||||
%(delim)s%(lb)s(?P<b_ident>%(ident)s)%(rb)s | # braced identifier
|
||||
%(delim)s(?P<pos>%(pos)s) | # positional parameter
|
||||
%(delim)s%(lb)s(?P<b_pos>%(pos)s)%(rb)s | # braced positional
|
||||
%(delim)s%(ldb)s(?P<eval>.*?)%(rdb)s | # double braced expression
|
||||
%(delim)s(?P<invalid>) # ill-formed delimiter exprs
|
||||
)
|
||||
"""
|
||||
def __init__(cls, name, bases, dct):
|
||||
super(code_formatter_meta, cls).__init__(name, bases, dct)
|
||||
if 'pattern' in dct:
|
||||
pat = cls.pattern
|
||||
else:
|
||||
# tuple expansion to ensure strings are proper length
|
||||
lb,rb = cls.braced
|
||||
lb1,lb2,rb2,rb1 = cls.double_braced
|
||||
pat = code_formatter_meta.pattern % {
|
||||
'delim' : re.escape(cls.delim),
|
||||
'ident' : cls.ident,
|
||||
'pos' : cls.pos,
|
||||
'lb' : re.escape(lb),
|
||||
'rb' : re.escape(rb),
|
||||
'ldb' : re.escape(lb1+lb2),
|
||||
'rdb' : re.escape(rb2+rb1),
|
||||
}
|
||||
cls.pattern = re.compile(pat, re.VERBOSE | re.DOTALL | re.MULTILINE)
|
||||
|
||||
class code_formatter(object):
|
||||
__metaclass__ = code_formatter_meta
|
||||
|
||||
delim = r'$'
|
||||
ident = r'[_A-z]\w*'
|
||||
pos = r'[0-9]+'
|
||||
braced = r'{}'
|
||||
double_braced = r'{{}}'
|
||||
|
||||
globals = True
|
||||
locals = True
|
||||
fix_newlines = True
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._data = []
|
||||
self._dict = {}
|
||||
self._indent_level = 0
|
||||
self._indent_spaces = 4
|
||||
self.globals = kwargs.pop('globals', type(self).globals)
|
||||
self.locals = kwargs.pop('locals', type(self).locals)
|
||||
self._fix_newlines = \
|
||||
kwargs.pop('fix_newlines', type(self).fix_newlines)
|
||||
|
||||
if args:
|
||||
self.__call__(args)
|
||||
|
||||
def indent(self, count=1):
|
||||
self._indent_level += self._indent_spaces * count
|
||||
|
||||
def dedent(self, count=1):
|
||||
assert self._indent_level >= (self._indent_spaces * count)
|
||||
self._indent_level -= self._indent_spaces * count
|
||||
|
||||
def fix(self, status):
|
||||
previous = self._fix_newlines
|
||||
self._fix_newlines = status
|
||||
return previous
|
||||
|
||||
def nofix(self):
|
||||
previous = self._fix_newlines
|
||||
self._fix_newlines = False
|
||||
return previous
|
||||
|
||||
def clear():
|
||||
self._data = []
|
||||
|
||||
def write(self, *args):
|
||||
f = file(os.path.join(*args), "w")
|
||||
for data in self._data:
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
def __str__(self):
|
||||
data = string.join(self._data, '')
|
||||
self._data = [ data ]
|
||||
return data
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self._dict[item]
|
||||
|
||||
def __setitem__(self, item, value):
|
||||
self._dict[item] = value
|
||||
|
||||
def __delitem__(self, item):
|
||||
del self._dict[item]
|
||||
|
||||
def __contains__(self, item):
|
||||
return item in self._dict
|
||||
|
||||
def __iadd__(self, data):
|
||||
self.append(data)
|
||||
|
||||
def append(self, data):
|
||||
if isinstance(data, code_formatter):
|
||||
self._data.extend(data._data)
|
||||
else:
|
||||
self._append(str(data))
|
||||
|
||||
def _append(self, data):
|
||||
if not self._fix_newlines:
|
||||
self._data.append(data)
|
||||
return
|
||||
|
||||
initial_newline = not self._data or self._data[-1] == '\n'
|
||||
for line in data.splitlines():
|
||||
if line:
|
||||
if self._indent_level:
|
||||
self._data.append(' ' * self._indent_level)
|
||||
self._data.append(line)
|
||||
|
||||
if line or not initial_newline:
|
||||
self._data.append('\n')
|
||||
|
||||
initial_newline = False
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if not args:
|
||||
self._data.append('\n')
|
||||
return
|
||||
|
||||
format = args[0]
|
||||
args = args[1:]
|
||||
|
||||
frame = inspect.currentframe().f_back
|
||||
|
||||
l = lookup(self, frame, *args, **kwargs)
|
||||
def convert(match):
|
||||
ident = match.group('lone')
|
||||
# check for a lone identifier
|
||||
if ident:
|
||||
indent = match.group('indent') # must be spaces
|
||||
lone = '%s' % (l[ident], )
|
||||
|
||||
def indent_lines(gen):
|
||||
for line in gen:
|
||||
yield indent
|
||||
yield line
|
||||
return ''.join(indent_lines(lone.splitlines(True)))
|
||||
|
||||
# check for an identifier, braced or not
|
||||
ident = match.group('ident') or match.group('b_ident')
|
||||
if ident is not None:
|
||||
return '%s' % (l[ident], )
|
||||
|
||||
# check for a positional parameter, braced or not
|
||||
pos = match.group('pos') or match.group('b_pos')
|
||||
if pos is not None:
|
||||
pos = int(pos)
|
||||
if pos > len(args):
|
||||
raise ValueError \
|
||||
('Positional parameter #%d not found in pattern' % pos,
|
||||
code_formatter.pattern)
|
||||
return '%s' % (args[int(pos)], )
|
||||
|
||||
# check for a double braced expression
|
||||
eval_expr = match.group('eval')
|
||||
if eval_expr is not None:
|
||||
result = eval(eval_expr, {}, l)
|
||||
return '%s' % (result, )
|
||||
|
||||
# check for an escaped delimiter
|
||||
if match.group('escaped') is not None:
|
||||
return '$'
|
||||
|
||||
# At this point, we have to match invalid
|
||||
if match.group('invalid') is None:
|
||||
# didn't match invalid!
|
||||
raise ValueError('Unrecognized named group in pattern',
|
||||
code_formatter.pattern)
|
||||
|
||||
i = match.start('invalid')
|
||||
if i == 0:
|
||||
colno = 1
|
||||
lineno = 1
|
||||
else:
|
||||
lines = format[:i].splitlines(True)
|
||||
colno = i - reduce(lambda x,y: x+y, (len(z) for z in lines))
|
||||
lineno = len(lines)
|
||||
|
||||
raise ValueError('Invalid format string: line %d, col %d' %
|
||||
(lineno, colno))
|
||||
|
||||
d = code_formatter.pattern.sub(convert, format)
|
||||
self._append(d)
|
||||
|
||||
__all__ = [ "code_formatter" ]
|
||||
|
||||
if __name__ == '__main__':
|
||||
from code_formatter import code_formatter
|
||||
f = code_formatter()
|
||||
|
||||
class Foo(dict):
|
||||
def __init__(self, **kwargs):
|
||||
self.update(kwargs)
|
||||
def __getattr__(self, attr):
|
||||
return self[attr]
|
||||
|
||||
x = "this is a test"
|
||||
l = [ [Foo(x=[Foo(y=9)])] ]
|
||||
|
||||
y = code_formatter()
|
||||
y('''
|
||||
{
|
||||
this_is_a_test();
|
||||
}
|
||||
''')
|
||||
f(' $y')
|
||||
f('''$__file__:$__line__
|
||||
{''')
|
||||
f("${{', '.join(str(x) for x in xrange(4))}}")
|
||||
f('${x}')
|
||||
f('$x')
|
||||
f.indent()
|
||||
for i in xrange(5):
|
||||
f('$x')
|
||||
f('$i')
|
||||
f('$0', "zero")
|
||||
f('$1 $0', "zero", "one")
|
||||
f('${0}', "he went")
|
||||
f('${0}asdf', "he went")
|
||||
f.dedent()
|
||||
|
||||
f('''
|
||||
${{l[0][0]["x"][0].y}}
|
||||
}
|
||||
''', 1, 9)
|
||||
|
||||
print f,
|
||||
301
simulators/gem5/src/python/m5/util/convert.py
Normal file
301
simulators/gem5/src/python/m5/util/convert.py
Normal file
@ -0,0 +1,301 @@
|
||||
# Copyright (c) 2005 The Regents of The University of Michigan
|
||||
# Copyright (c) 2010 Advanced Micro Devices, Inc.
|
||||
# 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
|
||||
# Gabe Black
|
||||
|
||||
# metric prefixes
|
||||
exa = 1.0e18
|
||||
peta = 1.0e15
|
||||
tera = 1.0e12
|
||||
giga = 1.0e9
|
||||
mega = 1.0e6
|
||||
kilo = 1.0e3
|
||||
|
||||
milli = 1.0e-3
|
||||
micro = 1.0e-6
|
||||
nano = 1.0e-9
|
||||
pico = 1.0e-12
|
||||
femto = 1.0e-15
|
||||
atto = 1.0e-18
|
||||
|
||||
# power of 2 prefixes
|
||||
kibi = 1024
|
||||
mebi = kibi * 1024
|
||||
gibi = mebi * 1024
|
||||
tebi = gibi * 1024
|
||||
pebi = tebi * 1024
|
||||
exbi = pebi * 1024
|
||||
|
||||
# memory size configuration stuff
|
||||
def toFloat(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
if value.endswith('Ei'):
|
||||
return float(value[:-2]) * exbi
|
||||
elif value.endswith('Pi'):
|
||||
return float(value[:-2]) * pebi
|
||||
elif value.endswith('Ti'):
|
||||
return float(value[:-2]) * tebi
|
||||
elif value.endswith('Gi'):
|
||||
return float(value[:-2]) * gibi
|
||||
elif value.endswith('Mi'):
|
||||
return float(value[:-2]) * mebi
|
||||
elif value.endswith('ki'):
|
||||
return float(value[:-2]) * kibi
|
||||
elif value.endswith('E'):
|
||||
return float(value[:-1]) * exa
|
||||
elif value.endswith('P'):
|
||||
return float(value[:-1]) * peta
|
||||
elif value.endswith('T'):
|
||||
return float(value[:-1]) * tera
|
||||
elif value.endswith('G'):
|
||||
return float(value[:-1]) * giga
|
||||
elif value.endswith('M'):
|
||||
return float(value[:-1]) * mega
|
||||
elif value.endswith('k'):
|
||||
return float(value[:-1]) * kilo
|
||||
elif value.endswith('m'):
|
||||
return float(value[:-1]) * milli
|
||||
elif value.endswith('u'):
|
||||
return float(value[:-1]) * micro
|
||||
elif value.endswith('n'):
|
||||
return float(value[:-1]) * nano
|
||||
elif value.endswith('p'):
|
||||
return float(value[:-1]) * pico
|
||||
elif value.endswith('f'):
|
||||
return float(value[:-1]) * femto
|
||||
else:
|
||||
return float(value)
|
||||
|
||||
def toInteger(value):
|
||||
value = toFloat(value)
|
||||
result = long(value)
|
||||
if value != result:
|
||||
raise ValueError, "cannot convert '%s' to integer" % value
|
||||
|
||||
return result
|
||||
|
||||
_bool_dict = {
|
||||
'true' : True, 't' : True, 'yes' : True, 'y' : True, '1' : True,
|
||||
'false' : False, 'f' : False, 'no' : False, 'n' : False, '0' : False
|
||||
}
|
||||
|
||||
def toBool(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
value = value.lower()
|
||||
result = _bool_dict.get(value, None)
|
||||
if result == None:
|
||||
raise ValueError, "cannot convert '%s' to bool" % value
|
||||
return result
|
||||
|
||||
def toFrequency(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
if value.endswith('THz'):
|
||||
return float(value[:-3]) * tera
|
||||
elif value.endswith('GHz'):
|
||||
return float(value[:-3]) * giga
|
||||
elif value.endswith('MHz'):
|
||||
return float(value[:-3]) * mega
|
||||
elif value.endswith('kHz'):
|
||||
return float(value[:-3]) * kilo
|
||||
elif value.endswith('Hz'):
|
||||
return float(value[:-2])
|
||||
|
||||
raise ValueError, "cannot convert '%s' to frequency" % value
|
||||
|
||||
def toLatency(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
if value.endswith('ps'):
|
||||
return float(value[:-2]) * pico
|
||||
elif value.endswith('ns'):
|
||||
return float(value[:-2]) * nano
|
||||
elif value.endswith('us'):
|
||||
return float(value[:-2]) * micro
|
||||
elif value.endswith('ms'):
|
||||
return float(value[:-2]) * milli
|
||||
elif value.endswith('s'):
|
||||
return float(value[:-1])
|
||||
|
||||
raise ValueError, "cannot convert '%s' to latency" % value
|
||||
|
||||
def anyToLatency(value):
|
||||
"""result is a clock period"""
|
||||
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
try:
|
||||
val = toFrequency(value)
|
||||
if val != 0:
|
||||
val = 1 / val
|
||||
return val
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
val = toLatency(value)
|
||||
return val
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
raise ValueError, "cannot convert '%s' to clock period" % value
|
||||
|
||||
def anyToFrequency(value):
|
||||
"""result is a clock period"""
|
||||
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
try:
|
||||
val = toFrequency(value)
|
||||
return val
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
val = toLatency(value)
|
||||
if val != 0:
|
||||
val = 1 / val
|
||||
return val
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
raise ValueError, "cannot convert '%s' to clock period" % value
|
||||
|
||||
def toNetworkBandwidth(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
if value.endswith('Tbps'):
|
||||
return float(value[:-4]) * tera
|
||||
elif value.endswith('Gbps'):
|
||||
return float(value[:-4]) * giga
|
||||
elif value.endswith('Mbps'):
|
||||
return float(value[:-4]) * mega
|
||||
elif value.endswith('kbps'):
|
||||
return float(value[:-4]) * kilo
|
||||
elif value.endswith('bps'):
|
||||
return float(value[:-3])
|
||||
else:
|
||||
return float(value)
|
||||
|
||||
raise ValueError, "cannot convert '%s' to network bandwidth" % value
|
||||
|
||||
def toMemoryBandwidth(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
if value.endswith('PB/s'):
|
||||
return float(value[:-4]) * pebi
|
||||
elif value.endswith('TB/s'):
|
||||
return float(value[:-4]) * tebi
|
||||
elif value.endswith('GB/s'):
|
||||
return float(value[:-4]) * gibi
|
||||
elif value.endswith('MB/s'):
|
||||
return float(value[:-4]) * mebi
|
||||
elif value.endswith('kB/s'):
|
||||
return float(value[:-4]) * kibi
|
||||
elif value.endswith('B/s'):
|
||||
return float(value[:-3])
|
||||
|
||||
raise ValueError, "cannot convert '%s' to memory bandwidth" % value
|
||||
|
||||
def toMemorySize(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
if value.endswith('PB'):
|
||||
return long(value[:-2]) * pebi
|
||||
elif value.endswith('TB'):
|
||||
return long(value[:-2]) * tebi
|
||||
elif value.endswith('GB'):
|
||||
return long(value[:-2]) * gibi
|
||||
elif value.endswith('MB'):
|
||||
return long(value[:-2]) * mebi
|
||||
elif value.endswith('kB'):
|
||||
return long(value[:-2]) * kibi
|
||||
elif value.endswith('B'):
|
||||
return long(value[:-1])
|
||||
|
||||
raise ValueError, "cannot convert '%s' to memory size" % value
|
||||
|
||||
def toIpAddress(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
bytes = value.split('.')
|
||||
if len(bytes) != 4:
|
||||
raise ValueError, 'invalid ip address %s' % value
|
||||
|
||||
for byte in bytes:
|
||||
if not 0 <= int(byte) <= 0xff:
|
||||
raise ValueError, 'invalid ip address %s' % value
|
||||
|
||||
return (int(bytes[0]) << 24) | (int(bytes[1]) << 16) | \
|
||||
(int(bytes[2]) << 8) | (int(bytes[3]) << 0)
|
||||
|
||||
def toIpNetmask(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
(ip, netmask) = value.split('/')
|
||||
ip = toIpAddress(ip)
|
||||
netmaskParts = netmask.split('.')
|
||||
if len(netmaskParts) == 1:
|
||||
if not 0 <= int(netmask) <= 32:
|
||||
raise ValueError, 'invalid netmask %s' % netmask
|
||||
return (ip, int(netmask))
|
||||
elif len(netmaskParts) == 4:
|
||||
netmaskNum = toIpAddress(netmask)
|
||||
if netmaskNum == 0:
|
||||
return (ip, 0)
|
||||
testVal = 0
|
||||
for i in range(32):
|
||||
testVal |= (1 << (31 - i))
|
||||
if testVal == netmaskNum:
|
||||
return (ip, i + 1)
|
||||
raise ValueError, 'invalid netmask %s' % netmask
|
||||
else:
|
||||
raise ValueError, 'invalid netmask %s' % netmask
|
||||
|
||||
def toIpWithPort(value):
|
||||
if not isinstance(value, str):
|
||||
raise TypeError, "wrong type '%s' should be str" % type(value)
|
||||
|
||||
(ip, port) = value.split(':')
|
||||
ip = toIpAddress(ip)
|
||||
if not 0 <= int(port) <= 0xffff:
|
||||
raise ValueError, 'invalid port %s' % port
|
||||
return (ip, int(port))
|
||||
179
simulators/gem5/src/python/m5/util/dot_writer.py
Normal file
179
simulators/gem5/src/python/m5/util/dot_writer.py
Normal file
@ -0,0 +1,179 @@
|
||||
# Copyright (c) 2012 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# 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: Andreas Hansson
|
||||
# Uri Wiener
|
||||
|
||||
#####################################################################
|
||||
#
|
||||
# System visualization using DOT
|
||||
#
|
||||
# While config.ini and config.json provide an almost complete listing
|
||||
# of a system's components and connectivity, they lack a birds-eye view.
|
||||
# The output generated by do_dot() is a DOT-based figure (pdf) and its
|
||||
# source dot code. Nodes are components, and edges represent
|
||||
# the memory hierarchy: the edges are directed, from a master to a slave.
|
||||
# Initially all nodes are generated, and then all edges are added.
|
||||
# do_dot should be called with the top-most SimObject (namely root
|
||||
# but not necessarily), the output folder and the output dot source
|
||||
# filename. From the given node, both processes (node and edge creation)
|
||||
# is performed recursivly, traversing all children of the given root.
|
||||
#
|
||||
# pydot is required. When missing, no output will be generated.
|
||||
#
|
||||
#####################################################################
|
||||
|
||||
import m5, os, re
|
||||
from m5.SimObject import isRoot, isSimObjectVector
|
||||
try:
|
||||
import pydot
|
||||
except:
|
||||
pydot = False
|
||||
|
||||
# need to create all nodes (components) before creating edges (memory channels)
|
||||
def dot_create_nodes(simNode, callgraph):
|
||||
if isRoot(simNode):
|
||||
label = "root"
|
||||
else:
|
||||
label = simNode._name
|
||||
full_path = re.sub('\.', '_', simNode.path())
|
||||
|
||||
# each component is a sub-graph (cluster)
|
||||
cluster = dot_create_cluster(simNode, full_path, label)
|
||||
|
||||
# create nodes per port
|
||||
for port_name in simNode._ports.keys():
|
||||
port = simNode._port_refs.get(port_name, None)
|
||||
if port != None:
|
||||
full_port_name = full_path + "_" + port_name
|
||||
port_node = dot_create_node(simNode, full_port_name, port_name)
|
||||
cluster.add_node(port_node)
|
||||
|
||||
# recurse to children
|
||||
if simNode._children:
|
||||
for c in simNode._children:
|
||||
child = simNode._children[c]
|
||||
if isSimObjectVector(child):
|
||||
for obj in child:
|
||||
dot_create_nodes(obj, cluster)
|
||||
else:
|
||||
dot_create_nodes(child, cluster)
|
||||
|
||||
callgraph.add_subgraph(cluster)
|
||||
|
||||
# create all edges according to memory hierarchy
|
||||
def dot_create_edges(simNode, callgraph):
|
||||
for port_name in simNode._ports.keys():
|
||||
port = simNode._port_refs.get(port_name, None)
|
||||
if port != None:
|
||||
full_path = re.sub('\.', '_', simNode.path())
|
||||
full_port_name = full_path + "_" + port_name
|
||||
port_node = dot_create_node(simNode, full_port_name, port_name)
|
||||
# create edges
|
||||
if type(port) is m5.params.PortRef:
|
||||
dot_add_edge(simNode, callgraph, full_port_name, port)
|
||||
else:
|
||||
for p in port.elements:
|
||||
dot_add_edge(simNode, callgraph, full_port_name, p)
|
||||
|
||||
# recurse to children
|
||||
if simNode._children:
|
||||
for c in simNode._children:
|
||||
child = simNode._children[c]
|
||||
if isSimObjectVector(child):
|
||||
for obj in child:
|
||||
dot_create_edges(obj, callgraph)
|
||||
else:
|
||||
dot_create_edges(child, callgraph)
|
||||
|
||||
def dot_add_edge(simNode, callgraph, full_port_name, peerPort):
|
||||
if peerPort.role == "MASTER":
|
||||
peer_port_name = re.sub('\.', '_', peerPort.peer.simobj.path() \
|
||||
+ "." + peerPort.peer.name)
|
||||
callgraph.add_edge(pydot.Edge(full_port_name, peer_port_name))
|
||||
|
||||
def dot_create_cluster(simNode, full_path, label):
|
||||
# if you read this, feel free to modify colors / style
|
||||
return pydot.Cluster( \
|
||||
full_path, \
|
||||
shape = "Mrecord", \
|
||||
label = label, \
|
||||
style = "\"rounded, filled\"", \
|
||||
color = "#000000", \
|
||||
fillcolor = dot_gen_color(simNode), \
|
||||
fontname = "Arial", \
|
||||
fontsize = "14", \
|
||||
fontcolor = "#000000" \
|
||||
)
|
||||
|
||||
def dot_create_node(simNode, full_path, label):
|
||||
# if you read this, feel free to modify colors / style.
|
||||
# leafs may have a different style => seperate function
|
||||
return pydot.Node( \
|
||||
full_path, \
|
||||
shape = "Mrecord", \
|
||||
label = label, \
|
||||
style = "\"rounded, filled\"", \
|
||||
color = "#000000", \
|
||||
fillcolor = "#808080", \
|
||||
fontname = "Arial", \
|
||||
fontsize = "14", \
|
||||
fontcolor = "#000000" \
|
||||
)
|
||||
|
||||
# generate color for nodes
|
||||
# currently a simple grayscale. placeholder for aesthetic programmers.
|
||||
def dot_gen_color(simNode):
|
||||
depth = len(simNode.path().split('.'))
|
||||
depth = 256 - depth * 16 * 3
|
||||
return dot_rgb_to_html(simNode, depth, depth, depth)
|
||||
|
||||
def dot_rgb_to_html(simNode, r, g, b):
|
||||
return "#%.2x%.2x%.2x" % (r, g, b)
|
||||
|
||||
def do_dot(root, outdir, dotFilename):
|
||||
if not pydot:
|
||||
return
|
||||
callgraph = pydot.Dot(graph_type='digraph')
|
||||
dot_create_nodes(root, callgraph)
|
||||
dot_create_edges(root, callgraph)
|
||||
dot_filename = os.path.join(outdir, dotFilename)
|
||||
callgraph.write(dot_filename)
|
||||
try:
|
||||
# dot crashes if the figure is extremely wide.
|
||||
# So avoid terminating simulation unnecessarily
|
||||
callgraph.write_pdf(dot_filename + ".pdf")
|
||||
except:
|
||||
print "warning: failed to generate pdf output from %s" % dot_filename
|
||||
139
simulators/gem5/src/python/m5/util/grammar.py
Normal file
139
simulators/gem5/src/python/m5/util/grammar.py
Normal file
@ -0,0 +1,139 @@
|
||||
# Copyright (c) 2006-2011 Nathan Binkert <nate@binkert.org>
|
||||
# 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.
|
||||
|
||||
import os
|
||||
|
||||
import ply.lex
|
||||
import ply.yacc
|
||||
|
||||
class ParseError(Exception):
|
||||
def __init__(self, message, token=None):
|
||||
Exception.__init__(self, message)
|
||||
self.token = token
|
||||
|
||||
class Grammar(object):
|
||||
def setupLexerFactory(self, **kwargs):
|
||||
if 'module' in kwargs:
|
||||
raise AttributeError, "module is an illegal attribute"
|
||||
self.lex_kwargs = kwargs
|
||||
|
||||
def setupParserFactory(self, **kwargs):
|
||||
if 'module' in kwargs:
|
||||
raise AttributeError, "module is an illegal attribute"
|
||||
|
||||
if 'output' in kwargs:
|
||||
dir,tab = os.path.split(output)
|
||||
if not tab.endswith('.py'):
|
||||
raise AttributeError, \
|
||||
'The output file must end with .py'
|
||||
kwargs['outputdir'] = dir
|
||||
kwargs['tabmodule'] = tab[:-3]
|
||||
|
||||
self.yacc_kwargs = kwargs
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr == 'lexers':
|
||||
self.lexers = []
|
||||
return self.lexers
|
||||
|
||||
if attr == 'lex_kwargs':
|
||||
self.setupLexerFactory()
|
||||
return self.lex_kwargs
|
||||
|
||||
if attr == 'yacc_kwargs':
|
||||
self.setupParserFactory()
|
||||
return self.yacc_kwargs
|
||||
|
||||
if attr == 'lex':
|
||||
self.lex = ply.lex.lex(module=self, **self.lex_kwargs)
|
||||
return self.lex
|
||||
|
||||
if attr == 'yacc':
|
||||
self.yacc = ply.yacc.yacc(module=self, **self.yacc_kwargs)
|
||||
return self.yacc
|
||||
|
||||
if attr == 'current_lexer':
|
||||
if not self.lexers:
|
||||
return None
|
||||
return self.lexers[-1][0]
|
||||
|
||||
if attr == 'current_source':
|
||||
if not self.lexers:
|
||||
return '<none>'
|
||||
return self.lexers[-1][1]
|
||||
|
||||
if attr == 'current_line':
|
||||
if not self.lexers:
|
||||
return -1
|
||||
return self.current_lexer.lineno
|
||||
|
||||
raise AttributeError, \
|
||||
"'%s' object has no attribute '%s'" % (type(self), attr)
|
||||
|
||||
def parse_string(self, data, source='<string>', debug=None, tracking=0):
|
||||
if not isinstance(data, basestring):
|
||||
raise AttributeError, \
|
||||
"argument must be a string, was '%s'" % type(f)
|
||||
|
||||
import new
|
||||
lexer = self.lex.clone()
|
||||
lexer.input(data)
|
||||
self.lexers.append((lexer, source))
|
||||
dict = {
|
||||
'productions' : self.yacc.productions,
|
||||
'action' : self.yacc.action,
|
||||
'goto' : self.yacc.goto,
|
||||
'errorfunc' : self.yacc.errorfunc,
|
||||
}
|
||||
parser = new.instance(ply.yacc.LRParser, dict)
|
||||
result = parser.parse(lexer=lexer, debug=debug, tracking=tracking)
|
||||
self.lexers.pop()
|
||||
return result
|
||||
|
||||
def parse_file(self, f, **kwargs):
|
||||
if isinstance(f, basestring):
|
||||
source = f
|
||||
f = file(f, 'r')
|
||||
elif isinstance(f, file):
|
||||
source = f.name
|
||||
else:
|
||||
raise AttributeError, \
|
||||
"argument must be either a string or file, was '%s'" % type(f)
|
||||
|
||||
return self.parse_string(f.read(), source, **kwargs)
|
||||
|
||||
def p_error(self, t):
|
||||
if t:
|
||||
msg = "Syntax error at %s:%d:%d\n>>%s<<" % \
|
||||
(self.current_source, t.lineno, t.lexpos + 1, t.value)
|
||||
else:
|
||||
msg = "Syntax error at end of %s" % (self.current_source, )
|
||||
raise ParseError(msg, t)
|
||||
|
||||
def t_error(self, t):
|
||||
msg = "Illegal character %s @ %d:%d" % \
|
||||
(`t.value[0]`, t.lineno, t.lexpos)
|
||||
raise ParseError(msg, t)
|
||||
472
simulators/gem5/src/python/m5/util/jobfile.py
Normal file
472
simulators/gem5/src/python/m5/util/jobfile.py
Normal file
@ -0,0 +1,472 @@
|
||||
# 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
|
||||
|
||||
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 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, \
|
||||
"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):
|
||||
import m5.util
|
||||
result = m5.util.optiondict()
|
||||
for key in self:
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
import m5.util
|
||||
for options in m5.util.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
|
||||
return data['conf']
|
||||
|
||||
def main(conf=None):
|
||||
usage = 'Usage: %s [-b] [-c] [-v]' % sys.argv[0]
|
||||
if conf is None:
|
||||
usage += ' <jobfile>'
|
||||
|
||||
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()
|
||||
182
simulators/gem5/src/python/m5/util/multidict.py
Normal file
182
simulators/gem5/src/python/m5/util/multidict.py
Normal file
@ -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
|
||||
73
simulators/gem5/src/python/m5/util/orderdict.py
Normal file
73
simulators/gem5/src/python/m5/util/orderdict.py
Normal file
@ -0,0 +1,73 @@
|
||||
# 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' ]
|
||||
|
||||
from UserDict import DictMixin
|
||||
|
||||
class orderdict(dict, DictMixin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
if len(args) > 1:
|
||||
raise TypeError("expected at most one argument, got %d" % \
|
||||
len(args))
|
||||
self._keys = []
|
||||
self.update(*args, **kwargs)
|
||||
|
||||
def __setitem__(self, key, item):
|
||||
if key not in self:
|
||||
self._keys.append(key)
|
||||
super(orderdict, self).__setitem__(key, item)
|
||||
|
||||
def __delitem__(self, key):
|
||||
super(orderdict, self).__delitem__(key)
|
||||
self._keys.remove(key)
|
||||
|
||||
def clear(self):
|
||||
super(orderdict, self).clear()
|
||||
self._keys = []
|
||||
|
||||
def iterkeys(self):
|
||||
for key in self._keys:
|
||||
yield key
|
||||
|
||||
def itervalues(self):
|
||||
for key in self._keys:
|
||||
yield self[key]
|
||||
|
||||
def iteritems(self):
|
||||
for key in self._keys:
|
||||
yield key, self[key]
|
||||
|
||||
def keys(self):
|
||||
return self._keys[:]
|
||||
|
||||
def values(self):
|
||||
return [ self[key] for key in self._keys ]
|
||||
|
||||
def items(self):
|
||||
return [ (self[key],key) for key in self._keys ]
|
||||
279
simulators/gem5/src/python/m5/util/region.py
Normal file
279
simulators/gem5/src/python/m5/util/region.py
Normal file
@ -0,0 +1,279 @@
|
||||
# Copyright (c) 2006 Nathan Binkert <nate@binkert.org>
|
||||
# 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.
|
||||
|
||||
class _neg_inf(object):
|
||||
'''This object always compares less than any other object'''
|
||||
def __repr__(self): return '<neg_inf>'
|
||||
def __lt__(self, other): return type(self) != type(other)
|
||||
def __le__(self, other): return True
|
||||
def __gt__(self, other): return False
|
||||
def __ge__(self, other): return type(self) == type(other)
|
||||
def __eq__(self, other): return type(self) == type(other)
|
||||
def __ne__(self, other): return type(self) != type(other)
|
||||
neg_inf = _neg_inf()
|
||||
|
||||
class _pos_inf(object):
|
||||
'''This object always compares greater than any other object'''
|
||||
def __repr__(self): return '<pos_inf>'
|
||||
def __lt__(self, other): return False
|
||||
def __le__(self, other): return type(self) == type(other)
|
||||
def __gt__(self, other): return type(self) != type(other)
|
||||
def __ge__(self, other): return True
|
||||
def __eq__(self, other): return type(self) == type(other)
|
||||
def __ne__(self, other): return type(self) != type(other)
|
||||
pos_inf = _pos_inf()
|
||||
|
||||
class Region(tuple):
|
||||
'''A region (range) of [start, end).
|
||||
This includes utility functions to compare overlap of regions.'''
|
||||
def __new__(cls, *args):
|
||||
if len(args) == 1:
|
||||
arg = args[0]
|
||||
if isinstance(arg, Region):
|
||||
return arg
|
||||
args = tuple(arg)
|
||||
|
||||
if len(args) != 2:
|
||||
raise AttributeError, \
|
||||
"Only one or two arguments allowed, %d provided" % (alen, )
|
||||
|
||||
return tuple.__new__(cls, args)
|
||||
|
||||
def __repr__(self):
|
||||
return 'Region(%s, %s)' % (self[0], self[1])
|
||||
|
||||
@property
|
||||
def start(self):
|
||||
return self[0]
|
||||
|
||||
@property
|
||||
def end(self):
|
||||
return self[1]
|
||||
|
||||
def __contains__(self, other):
|
||||
'''other is
|
||||
region: True if self and other is fully contained within self.
|
||||
pos: True if other is within the region'''
|
||||
if isinstance(other, tuple):
|
||||
return self[0] <= other[0] and self[1] >= other[1]
|
||||
return self[0] <= other and other < self[1]
|
||||
|
||||
def __eq__(self, other):
|
||||
'''other is
|
||||
region: True if self and other are identical.
|
||||
pos: True if other is within the region'''
|
||||
if isinstance(other, tuple):
|
||||
return self[0] == other[0] and self[1] == other[1]
|
||||
return self[0] <= other and other < self[1]
|
||||
|
||||
# @param self is a region.
|
||||
# @param other is a region.
|
||||
# @return if self and other are not identical.
|
||||
def __ne__(self, other):
|
||||
'''other is
|
||||
region: true if they are not identical
|
||||
pos: True if other is not in the region'''
|
||||
if isinstance(other, tuple):
|
||||
return self[0] != other[0] or self[1] != other[1]
|
||||
return other < self[0] or self[1] <= other
|
||||
|
||||
# @param self is a region.
|
||||
# @param other is a region.
|
||||
# @return if self is less than other and does not overlap self.
|
||||
def __lt__(self, other):
|
||||
"self completely left of other (cannot overlap)"
|
||||
if isinstance(other, tuple):
|
||||
return self[1] <= other[0]
|
||||
return self[1] <= other
|
||||
|
||||
# @param self is a region.
|
||||
# @param other is a region.
|
||||
# @return if self is less than other. self may overlap other,
|
||||
# but not extend beyond the _end of other.
|
||||
def __le__(self, other):
|
||||
"self extends to the left of other (can overlap)"
|
||||
if isinstance(other, tuple):
|
||||
return self[0] <= other[0]
|
||||
return self[0] <= other
|
||||
|
||||
# @param self is a region.
|
||||
# @param other is a region.
|
||||
# @return if self is greater than other and does not overlap other.
|
||||
def __gt__(self, other):
|
||||
"self is completely right of other (cannot overlap)"
|
||||
if isinstance(other, tuple):
|
||||
return self[0] >= other[1]
|
||||
return self[0] > other
|
||||
|
||||
# @param self is a region.
|
||||
# @param other is a region.
|
||||
# @return if self is greater than other. self may overlap other,
|
||||
# but not extend beyond the beginning of other.
|
||||
def __ge__(self, other):
|
||||
"self ex_ends beyond other to the right (can overlap)"
|
||||
if isinstance(other, tuple):
|
||||
return self[1] >= other[1]
|
||||
return self[1] > other
|
||||
|
||||
class Regions(object):
|
||||
'''A set of regions (ranges). Basically a region with holes.
|
||||
Includes utility functions to merge regions and figure out if
|
||||
something is in one of the regions.'''
|
||||
def __init__(self, *args):
|
||||
self.regions = []
|
||||
self.extend(*args)
|
||||
|
||||
def copy(self):
|
||||
copy = Regions()
|
||||
copy.regions.extend(self.regions)
|
||||
return copy
|
||||
|
||||
def append(self, *args):
|
||||
self.regions.append(Region(*args))
|
||||
|
||||
def extend(self, *args):
|
||||
self.regions.extend(Region(a) for a in args)
|
||||
|
||||
def __contains__(self, position):
|
||||
for region in self.regions:
|
||||
if position in region:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def __len__(self):
|
||||
return len(self.regions)
|
||||
|
||||
def __iand__(self, other):
|
||||
A = self.regions
|
||||
B = other.regions
|
||||
R = []
|
||||
|
||||
i = 0
|
||||
j = 0
|
||||
while i < len(self) and j < len(other):
|
||||
a = A[i]
|
||||
b = B[j]
|
||||
if a[1] <= b[0]:
|
||||
# A is completely before B. Skip A
|
||||
i += 1
|
||||
elif a[0] <= b[0]:
|
||||
if a[1] <= b[1]:
|
||||
# A and B overlap with B not left of A and A not right of B
|
||||
R.append(Region(b[0], a[1]))
|
||||
|
||||
# Advance A because nothing is left
|
||||
i += 1
|
||||
|
||||
if a[1] == b[1]:
|
||||
# Advance B too
|
||||
j += 1
|
||||
else:
|
||||
# A and B overlap with B completely within the bounds of A
|
||||
R.append(Region(b[0], b[1]))
|
||||
|
||||
# Advance only B because some of A may still be useful
|
||||
j += 1
|
||||
elif b[1] <= a[0]:
|
||||
# B is completely before A. Skip B.
|
||||
j += 1
|
||||
else:
|
||||
assert b[0] < a[0]
|
||||
if b[1] <= a[1]:
|
||||
# A and B overlap with A not left of B and B not right of A
|
||||
R.append(Region(a[0], b[1]))
|
||||
|
||||
# Advance B because nothing is left
|
||||
j += 1
|
||||
|
||||
if a[1] == b[1]:
|
||||
# Advance A too
|
||||
i += 1
|
||||
else:
|
||||
# A and B overlap with A completely within the bounds of B
|
||||
R.append(Region(a[0], a[1]))
|
||||
|
||||
# Advance only A because some of B may still be useful
|
||||
i += 1
|
||||
|
||||
self.regions = R
|
||||
return self
|
||||
|
||||
def __and__(self, other):
|
||||
result = self.copy()
|
||||
result &= other
|
||||
return result
|
||||
|
||||
def __repr__(self):
|
||||
return 'Regions(%s)' % ([(r[0], r[1]) for r in self.regions], )
|
||||
|
||||
if __name__ == '__main__':
|
||||
x = Regions(*((i, i + 1) for i in xrange(0,30,2)))
|
||||
y = Regions(*((i, i + 4) for i in xrange(0,30,5)))
|
||||
z = Region(6,7)
|
||||
n = Region(9,10)
|
||||
|
||||
def test(left, right):
|
||||
print "%s == %s: %s" % (left, right, left == right)
|
||||
print "%s != %s: %s" % (left, right, left != right)
|
||||
print "%s < %s: %s" % (left, right, left < right)
|
||||
print "%s <= %s: %s" % (left, right, left <= right)
|
||||
print "%s > %s: %s" % (left, right, left > right)
|
||||
print "%s >= %s: %s" % (left, right, left >= right)
|
||||
print
|
||||
|
||||
test(neg_inf, neg_inf)
|
||||
test(neg_inf, pos_inf)
|
||||
test(pos_inf, neg_inf)
|
||||
test(pos_inf, pos_inf)
|
||||
|
||||
test(neg_inf, 0)
|
||||
test(neg_inf, -11111)
|
||||
test(neg_inf, 11111)
|
||||
|
||||
test(0, neg_inf)
|
||||
test(-11111, neg_inf)
|
||||
test(11111, neg_inf)
|
||||
|
||||
test(pos_inf, 0)
|
||||
test(pos_inf, -11111)
|
||||
test(pos_inf, 11111)
|
||||
|
||||
test(0, pos_inf)
|
||||
test(-11111, pos_inf)
|
||||
test(11111, pos_inf)
|
||||
|
||||
print x
|
||||
print y
|
||||
print x & y
|
||||
print z
|
||||
|
||||
print 4 in x
|
||||
print 4 in z
|
||||
print 5 not in x
|
||||
print 6 not in z
|
||||
print z in y
|
||||
print n in y, n not in y
|
||||
155
simulators/gem5/src/python/m5/util/smartdict.py
Normal file
155
simulators/gem5/src/python/m5/util/smartdict.py
Normal file
@ -0,0 +1,155 @@
|
||||
# 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
|
||||
|
||||
# The SmartDict class fixes a couple of issues with using the content
|
||||
# of os.environ or similar dicts of strings as Python variables:
|
||||
#
|
||||
# 1) Undefined variables should return False rather than raising KeyError.
|
||||
#
|
||||
# 2) String values of 'False', '0', etc., should evaluate to False
|
||||
# (not just the empty string).
|
||||
#
|
||||
# #1 is solved by overriding __getitem__, and #2 is solved by using a
|
||||
# proxy class for values and overriding __nonzero__ on the proxy.
|
||||
# Everything else is just to (a) make proxies behave like normal
|
||||
# values otherwise, (b) make sure any dict operation returns a proxy
|
||||
# rather than a normal value, and (c) coerce values written to the
|
||||
# dict to be strings.
|
||||
|
||||
|
||||
from convert import *
|
||||
from attrdict import attrdict
|
||||
|
||||
class Variable(str):
|
||||
"""Intelligent proxy class for SmartDict. Variable will use the
|
||||
various convert functions to attempt to convert values to useable
|
||||
types"""
|
||||
def __int__(self):
|
||||
return toInteger(str(self))
|
||||
def __long__(self):
|
||||
return toLong(str(self))
|
||||
def __float__(self):
|
||||
return toFloat(str(self))
|
||||
def __nonzero__(self):
|
||||
return toBool(str(self))
|
||||
def convert(self, other):
|
||||
t = type(other)
|
||||
if t == bool:
|
||||
return bool(self)
|
||||
if t == int:
|
||||
return int(self)
|
||||
if t == long:
|
||||
return long(self)
|
||||
if t == float:
|
||||
return float(self)
|
||||
return str(self)
|
||||
def __lt__(self, other):
|
||||
return self.convert(other) < other
|
||||
def __le__(self, other):
|
||||
return self.convert(other) <= other
|
||||
def __eq__(self, other):
|
||||
return self.convert(other) == other
|
||||
def __ne__(self, other):
|
||||
return self.convert(other) != other
|
||||
def __gt__(self, other):
|
||||
return self.convert(other) > other
|
||||
def __ge__(self, other):
|
||||
return self.convert(other) >= other
|
||||
|
||||
def __add__(self, other):
|
||||
return self.convert(other) + other
|
||||
def __sub__(self, other):
|
||||
return self.convert(other) - other
|
||||
def __mul__(self, other):
|
||||
return self.convert(other) * other
|
||||
def __div__(self, other):
|
||||
return self.convert(other) / other
|
||||
def __truediv__(self, other):
|
||||
return self.convert(other) / other
|
||||
|
||||
def __radd__(self, other):
|
||||
return other + self.convert(other)
|
||||
def __rsub__(self, other):
|
||||
return other - self.convert(other)
|
||||
def __rmul__(self, other):
|
||||
return other * self.convert(other)
|
||||
def __rdiv__(self, other):
|
||||
return other / self.convert(other)
|
||||
def __rtruediv__(self, other):
|
||||
return other / self.convert(other)
|
||||
|
||||
class UndefinedVariable(object):
|
||||
"""Placeholder class to represent undefined variables. Will
|
||||
generally cause an exception whenever it is used, but evaluates to
|
||||
zero for boolean truth testing such as in an if statement"""
|
||||
def __nonzero__(self):
|
||||
return False
|
||||
|
||||
class SmartDict(attrdict):
|
||||
"""Dictionary class that holds strings, but intelligently converts
|
||||
those strings to other types depending on their usage"""
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""returns a Variable proxy if the values exists in the database and
|
||||
returns an UndefinedVariable otherwise"""
|
||||
|
||||
if key in self:
|
||||
return Variable(dict.get(self, key))
|
||||
else:
|
||||
# Note that this does *not* change the contents of the dict,
|
||||
# so that even after we call env['foo'] we still get a
|
||||
# meaningful answer from "'foo' in env" (which
|
||||
# calls dict.__contains__, which we do not override).
|
||||
return UndefinedVariable()
|
||||
|
||||
def __setitem__(self, key, item):
|
||||
"""intercept the setting of any variable so that we always
|
||||
store strings in the dict"""
|
||||
dict.__setitem__(self, key, str(item))
|
||||
|
||||
def values(self):
|
||||
return [ Variable(v) for v in dict.values(self) ]
|
||||
|
||||
def itervalues(self):
|
||||
for value in dict.itervalues(self):
|
||||
yield Variable(value)
|
||||
|
||||
def items(self):
|
||||
return [ (k, Variable(v)) for k,v in dict.items(self) ]
|
||||
|
||||
def iteritems(self):
|
||||
for key,value in dict.iteritems(self):
|
||||
yield key, Variable(value)
|
||||
|
||||
def get(self, key, default='False'):
|
||||
return Variable(dict.get(self, key, str(default)))
|
||||
|
||||
def setdefault(self, key, default='False'):
|
||||
return Variable(dict.setdefault(self, key, str(default)))
|
||||
|
||||
__all__ = [ 'SmartDict' ]
|
||||
220
simulators/gem5/src/python/m5/util/sorteddict.py
Normal file
220
simulators/gem5/src/python/m5/util/sorteddict.py
Normal file
@ -0,0 +1,220 @@
|
||||
# Copyright (c) 2006-2009 Nathan Binkert <nate@binkert.org>
|
||||
# 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.
|
||||
|
||||
from bisect import bisect_left, bisect_right
|
||||
|
||||
class SortedDict(dict):
|
||||
def _get_sorted(self):
|
||||
return getattr(self, '_sorted', sorted)
|
||||
def _set_sorted(self, val):
|
||||
self._sorted = val
|
||||
self._del_keys()
|
||||
sorted = property(_get_sorted, _set_sorted)
|
||||
|
||||
@property
|
||||
def _keys(self):
|
||||
try:
|
||||
return self._sorted_keys
|
||||
except AttributeError:
|
||||
_sorted_keys = self.sorted(dict.iterkeys(self))
|
||||
self._sorted_keys = _sorted_keys
|
||||
return _sorted_keys
|
||||
|
||||
def _left_eq(self, key):
|
||||
index = self._left_ge(self, key)
|
||||
if self._keys[index] != key:
|
||||
raise KeyError(key)
|
||||
return index
|
||||
|
||||
def _right_eq(self, key):
|
||||
index = self._right_le(self, key)
|
||||
if self._keys[index] != key:
|
||||
raise KeyError(key)
|
||||
return index
|
||||
|
||||
def _right_lt(self, key):
|
||||
index = bisect_left(self._keys, key)
|
||||
if index:
|
||||
return index - 1
|
||||
raise KeyError(key)
|
||||
|
||||
def _right_le(self, key):
|
||||
index = bisect_right(self._keys, key)
|
||||
if index:
|
||||
return index - 1
|
||||
raise KeyError(key)
|
||||
|
||||
def _left_gt(self, key):
|
||||
index = bisect_right(self._keys, key)
|
||||
if index != len(self._keys):
|
||||
return index
|
||||
raise KeyError(key)
|
||||
|
||||
def _left_ge(self, key):
|
||||
index = bisect_left(self._keys, key)
|
||||
if index != len(self._keys):
|
||||
return index
|
||||
raise KeyError(key)
|
||||
|
||||
def _del_keys(self):
|
||||
try:
|
||||
del self._sorted_keys
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return 'SortedDict({%s})' % ', '.join('%r: %r' % item
|
||||
for item in self.iteritems())
|
||||
def __setitem__(self, key, item):
|
||||
dict.__setitem__(self, key, item)
|
||||
self._del_keys()
|
||||
|
||||
def __delitem__(self, key):
|
||||
dict.__delitem__(self, key)
|
||||
self._del_keys()
|
||||
|
||||
def clear(self):
|
||||
self.data.clear()
|
||||
self._del_keys()
|
||||
|
||||
def copy(self):
|
||||
t = type(self)
|
||||
return t(self)
|
||||
|
||||
def keys(self):
|
||||
return self._keys[:]
|
||||
|
||||
def values(self):
|
||||
return list(self.itervalues())
|
||||
|
||||
def items(self):
|
||||
return list(self.iteritems())
|
||||
|
||||
def iterkeys(self):
|
||||
return iter(self._keys)
|
||||
|
||||
def itervalues(self):
|
||||
for k in self._keys:
|
||||
yield self[k]
|
||||
|
||||
def iteritems(self):
|
||||
for k in self._keys:
|
||||
yield k, self[k]
|
||||
|
||||
def keyrange(self, start=None, end=None, inclusive=False):
|
||||
if start is not None:
|
||||
start = self._left_ge(start)
|
||||
|
||||
if end is not None:
|
||||
if inclusive:
|
||||
end = self._right_le(end)
|
||||
else:
|
||||
end = self._right_lt(end)
|
||||
|
||||
return iter(self._keys[start:end+1])
|
||||
|
||||
def valuerange(self, *args, **kwargs):
|
||||
for k in self.keyrange(*args, **kwargs):
|
||||
yield self[k]
|
||||
|
||||
def itemrange(self, *args, **kwargs):
|
||||
for k in self.keyrange(*args, **kwargs):
|
||||
yield k, self[k]
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
dict.update(self, *args, **kwargs)
|
||||
self._del_keys()
|
||||
|
||||
def setdefault(self, key, _failobj=None):
|
||||
try:
|
||||
return self[key]
|
||||
except KeyError:
|
||||
self[key] = _failobj
|
||||
|
||||
def pop(self, key, *args):
|
||||
try:
|
||||
dict.pop(self, key)
|
||||
self._del_keys()
|
||||
except KeyError:
|
||||
if not args:
|
||||
raise
|
||||
return args[0]
|
||||
|
||||
def popitem(self):
|
||||
try:
|
||||
key = self._keys[0]
|
||||
self._del_keys()
|
||||
except IndexError:
|
||||
raise KeyError('popitem(): dictionary is empty')
|
||||
else:
|
||||
return key, dict.pop(self, key)
|
||||
|
||||
@classmethod
|
||||
def fromkeys(cls, seq, value=None):
|
||||
d = cls()
|
||||
for key in seq:
|
||||
d[key] = value
|
||||
return d
|
||||
|
||||
if __name__ == '__main__':
|
||||
def display(d):
|
||||
print d
|
||||
print d.keys()
|
||||
print list(d.iterkeys())
|
||||
print d.values()
|
||||
print list(d.itervalues())
|
||||
print d.items()
|
||||
print list(d.iteritems())
|
||||
|
||||
d = SortedDict(x=24,e=5,j=4,b=2,z=26,d=4)
|
||||
display(d)
|
||||
|
||||
print 'popitem', d.popitem()
|
||||
display(d)
|
||||
|
||||
print 'pop j'
|
||||
d.pop('j')
|
||||
display(d)
|
||||
|
||||
d.setdefault('a', 1)
|
||||
d.setdefault('g', 7)
|
||||
d.setdefault('_')
|
||||
display(d)
|
||||
|
||||
d.update({'b' : 2, 'h' : 8})
|
||||
display(d)
|
||||
|
||||
del d['x']
|
||||
display(d)
|
||||
d['y'] = 26
|
||||
display(d)
|
||||
|
||||
print `d`
|
||||
|
||||
print d.copy()
|
||||
|
||||
for k,v in d.itemrange('d', 'z', inclusive=True):
|
||||
print k,v
|
||||
122
simulators/gem5/src/python/m5/util/terminal.py
Normal file
122
simulators/gem5/src/python/m5/util/terminal.py
Normal file
@ -0,0 +1,122 @@
|
||||
# Copyright (c) 2011 Advanced Micro Devices, Inc.
|
||||
# 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.
|
||||
#
|
||||
# Author: Steve Reinhardt
|
||||
|
||||
import sys
|
||||
|
||||
# Intended usage example:
|
||||
#
|
||||
# if force_colors:
|
||||
# from m5.util.terminal import termcap
|
||||
# elif no_colors:
|
||||
# from m5.util.terminal import no_termcap as termcap
|
||||
# else:
|
||||
# from m5.util.terminal import tty_termcap as termcap
|
||||
# print termcap.Blue + "This could be blue!" + termcap.Normal
|
||||
|
||||
# ANSI color names in index order
|
||||
color_names = "Black Red Green Yellow Blue Magenta Cyan".split()
|
||||
|
||||
# Character attribute capabilities. Note that not all terminals
|
||||
# support all of these capabilities, or support them
|
||||
# differently/meaningfully. For example:
|
||||
#
|
||||
# - In PuTTY (with the default settings), Dim has no effect, Standout
|
||||
# is the same as Reverse, and Blink does not blink but switches to a
|
||||
# gray background.
|
||||
#
|
||||
# Please feel free to add information about other terminals here.
|
||||
#
|
||||
capability_map = {
|
||||
'Bold': 'bold',
|
||||
'Dim': 'dim',
|
||||
'Blink': 'blink',
|
||||
'Underline': 'smul',
|
||||
'Reverse': 'rev',
|
||||
'Standout': 'smso',
|
||||
'Normal': 'sgr0'
|
||||
}
|
||||
|
||||
capability_names = capability_map.keys()
|
||||
|
||||
def null_cap_string(s, *args):
|
||||
return ''
|
||||
|
||||
try:
|
||||
import curses
|
||||
curses.setupterm()
|
||||
def cap_string(s, *args):
|
||||
cap = curses.tigetstr(s)
|
||||
if cap:
|
||||
return curses.tparm(cap, *args)
|
||||
else:
|
||||
return ''
|
||||
except:
|
||||
cap_string = null_cap_string
|
||||
|
||||
class ColorStrings(object):
|
||||
def __init__(self, cap_string):
|
||||
for i, c in enumerate(color_names):
|
||||
setattr(self, c, cap_string('setaf', i))
|
||||
for name, cap in capability_map.iteritems():
|
||||
setattr(self, name, cap_string(cap))
|
||||
|
||||
termcap = ColorStrings(cap_string)
|
||||
no_termcap = ColorStrings(null_cap_string)
|
||||
|
||||
if sys.stdout.isatty():
|
||||
tty_termcap = termcap
|
||||
else:
|
||||
tty_termcap = no_termcap
|
||||
|
||||
def get_termcap(use_colors = None):
|
||||
if use_colors:
|
||||
return termcap
|
||||
elif use_colors is None:
|
||||
# option unspecified; default behavior is to use colors iff isatty
|
||||
return tty_termcap
|
||||
else:
|
||||
return no_termcap
|
||||
|
||||
def test_termcap(obj):
|
||||
for c_name in color_names:
|
||||
c_str = getattr(obj, c_name)
|
||||
print c_str + c_name + obj.Normal
|
||||
for attr_name in capability_names:
|
||||
if attr_name == 'Normal':
|
||||
continue
|
||||
attr_str = getattr(obj, attr_name)
|
||||
print attr_str + c_str + attr_name + " " + c_name + obj.Normal
|
||||
print obj.Bold + obj.Underline + \
|
||||
c_name + "Bold Underline " + c + obj.Normal
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "=== termcap enabled ==="
|
||||
test_termcap(termcap)
|
||||
print termcap.Normal
|
||||
print "=== termcap disabled ==="
|
||||
test_termcap(no_termcap)
|
||||
95
simulators/gem5/src/python/swig/core.i
Normal file
95
simulators/gem5/src/python/swig/core.i
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
%module(package="m5.internal") core
|
||||
|
||||
%{
|
||||
#include "base/misc.hh"
|
||||
#include "base/random.hh"
|
||||
#include "base/socket.hh"
|
||||
#include "base/types.hh"
|
||||
#include "python/swig/pyobject.hh"
|
||||
#include "sim/core.hh"
|
||||
|
||||
extern const char *compileDate;
|
||||
|
||||
#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(); }
|
||||
|
||||
inline void
|
||||
seedRandom(uint64_t seed)
|
||||
{
|
||||
random_mt.init(seed);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%include <std_string.i>
|
||||
%include <stdint.i>
|
||||
|
||||
%include "base/types.hh"
|
||||
|
||||
void setOutputDir(const std::string &dir);
|
||||
void doExitCleanup();
|
||||
void disableAllListeners();
|
||||
void seedRandom(uint64_t seed);
|
||||
|
||||
%immutable compileDate;
|
||||
char *compileDate;
|
||||
const bool flag_DEBUG;
|
||||
const bool flag_NDEBUG;
|
||||
const bool flag_TRACING_ON;
|
||||
|
||||
void setClockFrequency(Tick ticksPerSecond);
|
||||
|
||||
Tick curTick();
|
||||
|
||||
class Checkpoint;
|
||||
|
||||
void serializeAll(const std::string &cpt_dir);
|
||||
Checkpoint *getCheckpoint(const std::string &cpt_dir);
|
||||
void unserializeGlobals(Checkpoint *cp);
|
||||
|
||||
bool want_warn, warn_verbose;
|
||||
bool want_info, info_verbose;
|
||||
bool want_hack, hack_verbose;
|
||||
|
||||
93
simulators/gem5/src/python/swig/debug.i
Normal file
93
simulators/gem5/src/python/swig/debug.i
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||
* Copyright (c) 2010 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
|
||||
*/
|
||||
|
||||
%module(package="m5.internal") debug
|
||||
|
||||
%{
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/debug.hh"
|
||||
#include "base/types.hh"
|
||||
#include "sim/debug.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef map<string, Debug::Flag *> FlagsMap;
|
||||
typedef vector<Debug::Flag *> FlagsVec;
|
||||
|
||||
namespace Debug {
|
||||
extern int allFlagsVersion;
|
||||
FlagsMap &allFlags();
|
||||
}
|
||||
|
||||
inline int
|
||||
getAllFlagsVersion()
|
||||
{
|
||||
return Debug::allFlagsVersion;
|
||||
}
|
||||
|
||||
inline FlagsVec
|
||||
getAllFlags()
|
||||
{
|
||||
FlagsMap &flagsMap = Debug::allFlags();
|
||||
|
||||
FlagsVec flags(flagsMap.size());
|
||||
|
||||
int index = 0;
|
||||
FlagsMap::iterator i = flagsMap.begin();
|
||||
FlagsMap::iterator end = flagsMap.end();
|
||||
for (; i != end; ++i) {
|
||||
assert(index < flags.size());
|
||||
flags[index++] = i->second;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%ignore Debug::SimpleFlag::operator!;
|
||||
|
||||
%include <std_string.i>
|
||||
%include <std_vector.i>
|
||||
%include <stdint.i>
|
||||
|
||||
%include "base/debug.hh"
|
||||
%include "base/types.hh"
|
||||
%include "sim/debug.hh"
|
||||
|
||||
%template(AllFlags) std::vector<Debug::Flag *>;
|
||||
|
||||
int getAllFlagsVersion();
|
||||
std::vector<Debug::Flag *> getAllFlags();
|
||||
105
simulators/gem5/src/python/swig/event.i
Normal file
105
simulators/gem5/src/python/swig/event.i
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
%module(package="m5.internal") event
|
||||
|
||||
%{
|
||||
#include "base/types.hh"
|
||||
#include "python/swig/pyevent.hh"
|
||||
#include "sim/eventq.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "sim/simulate.hh"
|
||||
%}
|
||||
|
||||
#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<PythonEvent *>(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<PythonEvent *>(event);
|
||||
if (pyevent)
|
||||
pyevent->decref();
|
||||
}
|
||||
}
|
||||
|
||||
%ignore EventQueue::schedule;
|
||||
%ignore EventQueue::deschedule;
|
||||
|
||||
%include <std_string.i>
|
||||
%include <stdint.i>
|
||||
|
||||
%import "sim/serialize.hh"
|
||||
|
||||
%include "base/types.hh"
|
||||
%include "sim/eventq.hh"
|
||||
|
||||
// This must follow eventq.hh
|
||||
%include "python/swig/pyevent.hh"
|
||||
|
||||
struct CountedDrainEvent : public Event
|
||||
{
|
||||
void setCount(int _count);
|
||||
};
|
||||
|
||||
// minimal definition of SimExitEvent interface to wrap
|
||||
class SimLoopExitEvent : public Event
|
||||
{
|
||||
public:
|
||||
std::string getCause();
|
||||
int getCode();
|
||||
SimLoopExitEvent(const std::string &_cause, int c, Tick _repeat = 0);
|
||||
};
|
||||
|
||||
%exception simulate {
|
||||
$action
|
||||
if (!result) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
SimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
|
||||
void exitSimLoop(const std::string &message, int exit_code);
|
||||
67
simulators/gem5/src/python/swig/inet.i
Normal file
67
simulators/gem5/src/python/swig/inet.i
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||
* Copyright (c) 2010 Advanced Micro Devices, Inc.
|
||||
* 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
|
||||
* Gabe Black
|
||||
*/
|
||||
|
||||
%{
|
||||
#include "base/inet.hh"
|
||||
%}
|
||||
|
||||
%import <std_string.i>
|
||||
%import <stdint.i>
|
||||
|
||||
namespace Net {
|
||||
struct EthAddr
|
||||
{
|
||||
EthAddr();
|
||||
EthAddr(const uint8_t ea[6]);
|
||||
EthAddr(const std::string &addr);
|
||||
};
|
||||
|
||||
struct IpAddress
|
||||
{
|
||||
IpAddress();
|
||||
IpAddress(const uint32_t __addr);
|
||||
};
|
||||
|
||||
struct IpNetmask : IpAddress
|
||||
{
|
||||
IpNetmask();
|
||||
IpNetmask(const uint32_t __addr, const uint8_t __netmask);
|
||||
};
|
||||
|
||||
struct IpWithPort : IpAddress
|
||||
{
|
||||
IpWithPort();
|
||||
IpWithPort(const uint32_t __addr, const uint16_t __port);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
86
simulators/gem5/src/python/swig/pyevent.cc
Normal file
86
simulators/gem5/src/python/swig/pyevent.cc
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "python/swig/pyevent.hh"
|
||||
#include "sim/async.hh"
|
||||
|
||||
PythonEvent::PythonEvent(PyObject *obj, Priority priority)
|
||||
: Event(priority), object(obj)
|
||||
{
|
||||
if (object == NULL)
|
||||
panic("Passed in invalid object");
|
||||
}
|
||||
|
||||
PythonEvent::~PythonEvent()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PythonEvent::process()
|
||||
{
|
||||
PyObject *args = PyTuple_New(0);
|
||||
PyObject *result = PyObject_Call(object, args, NULL);
|
||||
Py_DECREF(args);
|
||||
|
||||
if (result) {
|
||||
// Nothing to do just decrement the reference count
|
||||
Py_DECREF(result);
|
||||
} else {
|
||||
// Somethign should be done to signal back to the main interpreter
|
||||
// that there's been an exception.
|
||||
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 *
|
||||
createCountedDrain()
|
||||
{
|
||||
return new CountedDrainEvent();
|
||||
}
|
||||
|
||||
void
|
||||
cleanupCountedDrain(Event *counted_drain)
|
||||
{
|
||||
CountedDrainEvent *event =
|
||||
dynamic_cast<CountedDrainEvent *>(counted_drain);
|
||||
if (event == NULL) {
|
||||
fatal("Called cleanupCountedDrain() on an event that was not "
|
||||
"a CountedDrainEvent.");
|
||||
}
|
||||
assert(event->getCount() == 0);
|
||||
delete event;
|
||||
}
|
||||
55
simulators/gem5/src/python/swig/pyevent.hh
Normal file
55
simulators/gem5/src/python/swig/pyevent.hh
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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_PYEVENT_HH__
|
||||
#define __PYTHON_SWIG_PYEVENT_HH__
|
||||
|
||||
#include "sim/eventq.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
|
||||
class PythonEvent : public Event
|
||||
{
|
||||
private:
|
||||
PyObject *object;
|
||||
|
||||
public:
|
||||
PythonEvent(PyObject *obj, Event::Priority priority);
|
||||
~PythonEvent();
|
||||
|
||||
void incref() { Py_INCREF(object); }
|
||||
void decref() { Py_DECREF(object); }
|
||||
|
||||
virtual void process();
|
||||
};
|
||||
|
||||
CountedDrainEvent *createCountedDrain();
|
||||
void cleanupCountedDrain(Event *counted_drain);
|
||||
|
||||
#endif // __PYTHON_SWIG_PYEVENT_HH__
|
||||
162
simulators/gem5/src/python/swig/pyobject.cc
Normal file
162
simulators/gem5/src/python/swig/pyobject.cc
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/inifile.hh"
|
||||
#include "base/output.hh"
|
||||
#include "dev/etherdevice.hh"
|
||||
#include "dev/etherint.hh"
|
||||
#include "dev/etherobject.hh"
|
||||
#include "mem/mem_object.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "sim/full_system.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
EtherInt *
|
||||
lookupEthPort(SimObject *so, const std::string &name, int i)
|
||||
{
|
||||
EtherObject *eo = dynamic_cast<EtherObject *>(so);
|
||||
EtherDevice *ed = dynamic_cast<EtherDevice *>(so);
|
||||
if (eo == NULL && ed == NULL) {
|
||||
warn("error casting SimObject %s", so->name());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EtherInt *p = NULL;
|
||||
if (eo)
|
||||
p = eo->getEthPort(name, i);
|
||||
else
|
||||
p = ed->getEthPort(name, i);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the described MemObject ports. Called from Python via SWIG.
|
||||
* The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports.
|
||||
* SimObject1 is the master, and SimObject2 is the slave
|
||||
*/
|
||||
int
|
||||
connectPorts(SimObject *o1, const std::string &name1, int i1,
|
||||
SimObject *o2, const std::string &name2, int i2)
|
||||
{
|
||||
if (FullSystem) {
|
||||
EtherObject *eo1, *eo2;
|
||||
EtherDevice *ed1, *ed2;
|
||||
eo1 = dynamic_cast<EtherObject*>(o1);
|
||||
ed1 = dynamic_cast<EtherDevice*>(o1);
|
||||
eo2 = dynamic_cast<EtherObject*>(o2);
|
||||
ed2 = dynamic_cast<EtherDevice*>(o2);
|
||||
|
||||
if ((eo1 || ed1) && (eo2 || ed2)) {
|
||||
EtherInt *p1 = lookupEthPort(o1, name1, i1);
|
||||
EtherInt *p2 = lookupEthPort(o2, name2, i2);
|
||||
|
||||
if (p1 != NULL && p2 != NULL) {
|
||||
|
||||
p1->setPeer(p2);
|
||||
p2->setPeer(p1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
MemObject *mo1, *mo2;
|
||||
mo1 = dynamic_cast<MemObject*>(o1);
|
||||
mo2 = dynamic_cast<MemObject*>(o2);
|
||||
|
||||
if(mo1 == NULL || mo2 == NULL) {
|
||||
panic ("Error casting SimObjects %s and %s to MemObject", o1->name(),
|
||||
o2->name());
|
||||
}
|
||||
|
||||
// generic master/slave port connection
|
||||
MasterPort& masterPort = mo1->getMasterPort(name1, i1);
|
||||
SlavePort& slavePort = mo2->getSlavePort(name2, i2);
|
||||
|
||||
masterPort.bind(slavePort);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline IniFile &
|
||||
inifile()
|
||||
{
|
||||
static IniFile inifile;
|
||||
return inifile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a pointer to the Python object that SWIG wraps around a C++
|
||||
* SimObject pointer back to the actual C++ pointer. See main.i.
|
||||
*/
|
||||
extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);
|
||||
|
||||
// Python.h is notoriously not const-correct (for 2.4, anyway)... make
|
||||
// a little define here to reduce the noise and make it easier to
|
||||
// #ifdef away if Python.h gets fixed. Note there are a couple of
|
||||
// these in sim/main.cc as well that are handled without this define.
|
||||
#define PCC(s) const_cast<char *>(s)
|
||||
|
||||
|
||||
SimObject *
|
||||
resolveSimObject(const string &name)
|
||||
{
|
||||
PyObject *module = PyImport_ImportModule(PCC("m5.SimObject"));
|
||||
if (module == NULL)
|
||||
panic("Could not import m5.SimObject");
|
||||
|
||||
PyObject *resolver =
|
||||
PyObject_GetAttrString(module, PCC("resolveSimObject"));
|
||||
if (resolver == NULL) {
|
||||
PyErr_Print();
|
||||
panic("resolveSimObject: failed to find resolveSimObject");
|
||||
}
|
||||
|
||||
PyObject *ptr = PyObject_CallFunction(resolver, PCC("(s)"), name.c_str());
|
||||
if (ptr == NULL) {
|
||||
PyErr_Print();
|
||||
panic("resolveSimObject: failure on call to Python for %s", name);
|
||||
}
|
||||
|
||||
SimObject *obj = convertSwigSimObjectPtr(ptr);
|
||||
if (obj == NULL)
|
||||
panic("resolveSimObject: failure on pointer conversion for %s", name);
|
||||
|
||||
Py_DECREF(module);
|
||||
Py_DECREF(resolver);
|
||||
Py_DECREF(ptr);
|
||||
|
||||
return obj;
|
||||
}
|
||||
63
simulators/gem5/src/python/swig/pyobject.hh
Normal file
63
simulators/gem5/src/python/swig/pyobject.hh
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "base/types.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);
|
||||
SimObject *resolveSimObject(const std::string &name);
|
||||
|
||||
/**
|
||||
* Connect the described MemObject ports. Called from Python via SWIG.
|
||||
*/
|
||||
int connectPorts(SimObject *o1, const std::string &name1, int i1,
|
||||
SimObject *o2, const std::string &name2, int i2);
|
||||
|
||||
|
||||
inline void
|
||||
serializeAll(const std::string &cpt_dir)
|
||||
{
|
||||
Serializable::serializeAll(cpt_dir);
|
||||
}
|
||||
|
||||
inline Checkpoint *
|
||||
getCheckpoint(const std::string &cpt_dir)
|
||||
{
|
||||
return new Checkpoint(cpt_dir);
|
||||
}
|
||||
|
||||
inline void
|
||||
unserializeGlobals(Checkpoint *cp)
|
||||
{
|
||||
Serializable::unserializeGlobals(cp);
|
||||
}
|
||||
55
simulators/gem5/src/python/swig/pyobject.i
Normal file
55
simulators/gem5/src/python/swig/pyobject.i
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
%module(package="m5.internal") pyobject
|
||||
|
||||
%{
|
||||
#include "python/swig/pyobject.hh"
|
||||
%}
|
||||
|
||||
// import these files for SWIG to wrap
|
||||
%include <std_string.i>
|
||||
%include <stdint.i>
|
||||
|
||||
int connectPorts(SimObject *o1, const std::string &name1, int i1,
|
||||
SimObject *o2, const std::string &name2, int i2);
|
||||
|
||||
%wrapper %{
|
||||
// Convert a pointer to the Python object that SWIG wraps around a
|
||||
// C++ SimObject pointer back to the actual C++ pointer.
|
||||
SimObject *
|
||||
convertSwigSimObjectPtr(PyObject *pyObj)
|
||||
{
|
||||
SimObject *so;
|
||||
if (SWIG_ConvertPtr(pyObj, (void **) &so, SWIGTYPE_p_SimObject, 0) == -1)
|
||||
return NULL;
|
||||
return so;
|
||||
}
|
||||
%}
|
||||
45
simulators/gem5/src/python/swig/range.i
Normal file
45
simulators/gem5/src/python/swig/range.i
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
%module(package="m5.internal") range
|
||||
|
||||
%{
|
||||
#include "base/range.hh"
|
||||
#include "base/types.hh"
|
||||
%}
|
||||
|
||||
%include <stdint.i>
|
||||
|
||||
%rename(assign) *::operator=;
|
||||
%include "base/range.hh"
|
||||
%include "base/types.hh"
|
||||
|
||||
%template(AddrRange) Range<Addr>;
|
||||
%template(TickRange) Range<Tick>;
|
||||
162
simulators/gem5/src/python/swig/stats.i
Normal file
162
simulators/gem5/src/python/swig/stats.i
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
%module(package="m5.internal") stats
|
||||
|
||||
%include <std_list.i>
|
||||
%include <std_string.i>
|
||||
%include <std_vector.i>
|
||||
%include <stdint.i>
|
||||
|
||||
%{
|
||||
#include "base/stats/text.hh"
|
||||
#include "base/stats/types.hh"
|
||||
#include "base/callback.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "sim/core.hh"
|
||||
#include "sim/stat_control.hh"
|
||||
|
||||
namespace Stats {
|
||||
template <class T>
|
||||
inline T
|
||||
cast_info(Info *info)
|
||||
{
|
||||
return dynamic_cast<T>(info);
|
||||
}
|
||||
|
||||
inline FlagsType
|
||||
Stats_Info_flags_get(Info *info)
|
||||
{
|
||||
return info->flags;
|
||||
}
|
||||
|
||||
inline void
|
||||
Stats_Info_flags_set(Info *info, FlagsType flags)
|
||||
{
|
||||
info->flags = flags;
|
||||
}
|
||||
|
||||
inline void
|
||||
processResetQueue()
|
||||
{
|
||||
extern CallbackQueue resetQueue;
|
||||
resetQueue.process();
|
||||
}
|
||||
|
||||
inline void
|
||||
processDumpQueue()
|
||||
{
|
||||
extern CallbackQueue dumpQueue;
|
||||
dumpQueue.process();
|
||||
}
|
||||
|
||||
inline char *
|
||||
PCC(const char *string)
|
||||
{
|
||||
return const_cast<char *>(string);
|
||||
}
|
||||
|
||||
void
|
||||
call_module_function(const char *module_name, const char *func_name)
|
||||
{
|
||||
PyObject *module = PyImport_ImportModule(PCC(module_name));
|
||||
if (module == NULL)
|
||||
panic("Could not import %s", module);
|
||||
|
||||
PyObject *result = PyObject_CallMethod(module, PCC(func_name), PCC(""));
|
||||
if (result == NULL) {
|
||||
PyErr_Print();
|
||||
panic("failure on call to function %s", func_name);
|
||||
}
|
||||
|
||||
Py_DECREF(module);
|
||||
Py_DECREF(result);
|
||||
}
|
||||
|
||||
void
|
||||
dump()
|
||||
{
|
||||
call_module_function("m5.stats", "dump");
|
||||
}
|
||||
|
||||
void
|
||||
reset()
|
||||
{
|
||||
call_module_function("m5.stats", "reset");
|
||||
}
|
||||
|
||||
} // namespace Stats
|
||||
%}
|
||||
|
||||
%extend Stats::Info {
|
||||
short flags;
|
||||
}
|
||||
|
||||
%ignore Stats::Info::flags;
|
||||
|
||||
%import "base/stats/types.hh"
|
||||
|
||||
%include "base/stats/info.hh"
|
||||
%include "base/stats/output.hh"
|
||||
|
||||
namespace std {
|
||||
%template(list_info) list<Stats::Info *>;
|
||||
%template(vector_double) vector<double>;
|
||||
%template(vector_string) vector<string>;
|
||||
%template(vector_DistData) vector<Stats::DistData>;
|
||||
}
|
||||
|
||||
namespace Stats {
|
||||
|
||||
template <class T> T cast_info(Info *info);
|
||||
|
||||
%template(dynamic_ScalarInfo) cast_info<ScalarInfo *>;
|
||||
%template(dynamic_VectorInfo) cast_info<VectorInfo *>;
|
||||
%template(dynamic_DistInfo) cast_info<DistInfo *>;
|
||||
%template(dynamic_VectorDistInfo) cast_info<VectorDistInfo *>;
|
||||
%template(dynamic_Vector2dInfo) cast_info<Vector2dInfo *>;
|
||||
%template(dynamic_FormulaInfo) cast_info<FormulaInfo *>;
|
||||
%template(dynamic_SparseHistInfo) cast_info<SparseHistInfo *>;
|
||||
|
||||
void initSimStats();
|
||||
Output *initText(const std::string &filename, bool desc);
|
||||
|
||||
void schedStatEvent(bool dump, bool reset,
|
||||
Tick when = curTick(), Tick repeat = 0);
|
||||
|
||||
void processResetQueue();
|
||||
void processDumpQueue();
|
||||
void enable();
|
||||
bool enabled();
|
||||
|
||||
std::list<Info *> &statsList();
|
||||
|
||||
} // namespace Stats
|
||||
44
simulators/gem5/src/python/swig/time.i
Normal file
44
simulators/gem5/src/python/swig/time.i
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <sys/time.h>
|
||||
%}
|
||||
|
||||
struct tm {
|
||||
int tm_sec; /* seconds after the minute [0-60] */
|
||||
int tm_min; /* minutes after the hour [0-59] */
|
||||
int tm_hour; /* hours since midnight [0-23] */
|
||||
int tm_mday; /* day of the month [1-31] */
|
||||
int tm_mon; /* months since January [0-11] */
|
||||
int tm_year; /* years since 1900 */
|
||||
int tm_wday; /* days since Sunday [0-6] */
|
||||
int tm_yday; /* days since January 1 [0-365] */
|
||||
};
|
||||
54
simulators/gem5/src/python/swig/trace.i
Normal file
54
simulators/gem5/src/python/swig/trace.i
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
%module(package="m5.internal") trace
|
||||
|
||||
%{
|
||||
#include "base/trace.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
inline void
|
||||
output(const char *filename)
|
||||
{
|
||||
Trace::setOutput(filename);
|
||||
}
|
||||
|
||||
inline void
|
||||
ignore(const char *expr)
|
||||
{
|
||||
Trace::ignore.setExpression(expr);
|
||||
}
|
||||
|
||||
using Trace::enabled;
|
||||
%}
|
||||
|
||||
extern void output(const char *string);
|
||||
extern void ignore(const char *expr);
|
||||
extern bool enabled;
|
||||
Reference in New Issue
Block a user