Deleted Added
sdiff udiff text old ( 7527:fe90827a663f ) new ( 7528:6efc3672733b )
full compact
1# Copyright (c) 2004-2006 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

--- 13 unchanged lines hidden (view full) ---

22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Steve Reinhardt
28# Nathan Binkert
29
30import sys
31from types import FunctionType
32
33try:
34 import pydot
35except:
36 pydot = False
37
38import m5
39from m5.util import *
40
41# Have to import params up top since Param is referenced on initial
42# load (when SimObject class references Param to create a class
43# variable, the 'name' param)...
44from m5.params import *
45# There are a few things we need that aren't in params.__all__ since
46# normal users don't need them
47from m5.params import ParamDesc, VectorParamDesc, \
48 isNullPointer, SimObjectVector
49
50from m5.proxy import *
51from m5.proxy import isproxy
52
53#####################################################################
54#
55# M5 Python Configuration Utility
56#

--- 93 unchanged lines hidden (view full) ---

150 # initialize required attributes
151
152 # class-only attributes
153 cls._params = multidict() # param descriptions
154 cls._ports = multidict() # port descriptions
155
156 # class or instance attributes
157 cls._values = multidict() # param values
158 cls._children = multidict() # SimObject children
159 cls._port_refs = multidict() # port ref objects
160 cls._instantiated = False # really instantiated, cloned, or subclassed
161
162 # We don't support multiple inheritance. If you want to, you
163 # must fix multidict to deal with it properly.
164 if len(bases) > 1:
165 raise TypeError, "SimObjects do not support multiple inheritance"
166
167 base = bases[0]
168
169 # Set up general inheritance via multidicts. A subclass will
170 # inherit all its settings from the base class. The only time
171 # the following is not true is when we define the SimObject
172 # class itself (in which case the multidicts have no parent).
173 if isinstance(base, MetaSimObject):
174 cls._base = base
175 cls._params.parent = base._params
176 cls._ports.parent = base._ports
177 cls._values.parent = base._values
178 cls._children.parent = base._children
179 cls._port_refs.parent = base._port_refs
180 # mark base as having been subclassed
181 base._instantiated = True
182 else:
183 cls._base = None
184
185 # default keyword values
186 if 'type' in cls._value_dict:

--- 115 unchanged lines hidden (view full) ---

302 # check for param
303 param = cls._params.get(attr)
304 if param:
305 cls._set_param(attr, value, param)
306 return
307
308 if isSimObjectOrSequence(value):
309 # If RHS is a SimObject, it's an implicit child assignment.
310 cls._children[attr] = coerceSimObjectOrVector(value)
311 return
312
313 # no valid assignment... raise exception
314 raise AttributeError, \
315 "Class %s has no parameter \'%s\'" % (cls.__name__, attr)
316
317 def __getattr__(cls, attr):
318 if cls._values.has_key(attr):
319 return cls._values[attr]
320
321 if cls._children.has_key(attr):
322 return cls._children[attr]
323
324 raise AttributeError, \
325 "object '%s' has no attribute '%s'" % (cls.__name__, attr)
326
327 def __str__(cls):
328 return cls.__name__
329
330 def cxx_decl(cls):
331 code = "#ifndef __PARAMS__%s\n" % cls

--- 129 unchanged lines hidden (view full) ---

461 memo_dict[ancestor] = self
462
463 if not ancestor:
464 ancestor = self.__class__
465 ancestor._instantiated = True
466
467 # initialize required attributes
468 self._parent = None
469 self._name = None
470 self._ccObject = None # pointer to C++ object
471 self._ccParams = None
472 self._instantiated = False # really "cloned"
473
474 # Inherit parameter values from class using multidict so
475 # individual value settings can be overridden but we still
476 # inherit late changes to non-overridden class values.
477 self._values = multidict(ancestor._values)
478 # clone SimObject-valued parameters
479 for key,val in ancestor._values.iteritems():
480 val = tryAsSimObjectOrVector(val)
481 if val is not None:
482 self._values[key] = val(_memo=memo_dict)
483
484 # Clone children specified at class level. No need for a
485 # multidict here since we will be cloning everything.
486 self._children = {}
487 for key,val in ancestor._children.iteritems():
488 self.add_child(key, val(_memo=memo_dict))
489
490 # clone port references. no need to use a multidict here
491 # since we will be creating new references for all ports.
492 self._port_refs = {}
493 for key,val in ancestor._port_refs.iteritems():
494 self._port_refs[key] = val.clone(self, memo_dict)
495 # apply attribute assignments from keyword args, if any
496 for key,val in kwargs.iteritems():
497 setattr(self, key, val)

--- 32 unchanged lines hidden (view full) ---

530
531 def __getattr__(self, attr):
532 if self._ports.has_key(attr):
533 return self._get_port_ref(attr)
534
535 if self._values.has_key(attr):
536 return self._values[attr]
537
538 if self._children.has_key(attr):
539 return self._children[attr]
540
541 # If the attribute exists on the C++ object, transparently
542 # forward the reference there. This is typically used for
543 # SWIG-wrapped methods such as init(), regStats(),
544 # regFormulas(), resetStats(), startup(), drain(), and
545 # resume().
546 if self._ccObject and hasattr(self._ccObject, attr):
547 return getattr(self._ccObject, attr)
548

--- 13 unchanged lines hidden (view full) ---

562 self._get_port_ref(attr).connect(value)
563 return
564
565 if isSimObjectOrSequence(value) and self._instantiated:
566 raise RuntimeError, \
567 "cannot set SimObject parameter '%s' after\n" \
568 " instance been cloned %s" % (attr, `self`)
569
570 param = self._params.get(attr)
571 if param:
572 try:
573 value = param.convert(value)
574 except Exception, e:
575 msg = "%s\nError setting param %s.%s to %s\n" % \
576 (e, self.__class__.__name__, attr, value)
577 e.args = (msg, )
578 raise
579 self._values[attr] = value
580 return
581
582 # if RHS is a SimObject, it's an implicit child assignment
583 if isSimObjectOrSequence(value):
584 self.add_child(attr, value)
585 return
586
587 # no valid assignment... raise exception
588 raise AttributeError, "Class %s has no parameter %s" \
589 % (self.__class__.__name__, attr)
590
591
592 # this hack allows tacking a '[0]' onto parameters that may or may
593 # not be vectors, and always getting the first element (e.g. cpus)
594 def __getitem__(self, key):
595 if key == 0:
596 return self
597 raise TypeError, "Non-zero index '%s' to SimObject" % key
598
599 # Also implemented by SimObjectVector
600 def clear_parent(self, old_parent):
601 assert self._parent is old_parent
602 self._parent = None
603
604 # Also implemented by SimObjectVector
605 def set_parent(self, parent, name):
606 self._parent = parent
607 self._name = name
608
609 # Also implemented by SimObjectVector
610 def get_name(self):
611 return self._name
612
613 # use this rather than directly accessing _parent for symmetry
614 # with SimObjectVector
615 def get_parent(self):
616 return self._parent
617
618 # clear out child with given name
619 def clear_child(self, name):
620 child = self._children[name]
621 child.clear_parent(self)
622 del self._children[name]
623
624 # Add a new child to this object.
625 def add_child(self, name, child):
626 child = coerceSimObjectOrVector(child)
627 if child.get_parent():
628 raise RuntimeError, \
629 "add_child('%s'): child '%s' already has parent '%s'" % \
630 (name, child._name, child._parent)
631 if self._children.has_key(name):
632 clear_child(name)
633 child.set_parent(self, name)
634 self._children[name] = child
635
636 # Take SimObject-valued parameters that haven't been explicitly
637 # assigned as children and make them children of the object that
638 # they were assigned to as a parameter value. This guarantees
639 # that when we instantiate all the parameter objects we're still
640 # inside the configuration hierarchy.
641 def adoptOrphanParams(self):
642 for key,val in self._values.iteritems():
643 if not isSimObjectVector(val) and isSimObjectSequence(val):
644 # need to convert raw SimObject sequences to
645 # SimObjectVector class so we can call get_parent()
646 val = SimObjectVector(val)
647 self._values[key] = val
648 if isSimObjectOrVector(val) and not val.get_parent():
649 self.add_child(key, val)
650
651 def path(self):
652 if not self._parent:
653 return '(orphan)'
654 ppath = self._parent.path()
655 if ppath == 'root':
656 return self._name
657 return ppath + "." + self._name
658

--- 55 unchanged lines hidden (view full) ---

714 instanceDict[self.path()] = self
715
716 if hasattr(self, 'type'):
717 print >>ini_file, 'type=%s' % self.type
718
719 child_names = self._children.keys()
720 child_names.sort()
721 if len(child_names):
722 print >>ini_file, 'children=%s' % \
723 ' '.join(self._children[n].get_name() for n in child_names)
724
725 param_names = self._params.keys()
726 param_names.sort()
727 for param in param_names:
728 value = self._values.get(param)
729 if value != None:
730 print >>ini_file, '%s=%s' % (param,
731 self._values[param].ini_str())

--- 146 unchanged lines hidden (view full) ---

878 return obj.getCCObject()
879
880def isSimObject(value):
881 return isinstance(value, SimObject)
882
883def isSimObjectClass(value):
884 return issubclass(value, SimObject)
885
886def isSimObjectVector(value):
887 return isinstance(value, SimObjectVector)
888
889def isSimObjectSequence(value):
890 if not isinstance(value, (list, tuple)) or len(value) == 0:
891 return False
892
893 for val in value:
894 if not isNullPointer(val) and not isSimObject(val):
895 return False
896
897 return True
898
899def isSimObjectOrSequence(value):
900 return isSimObject(value) or isSimObjectSequence(value)
901
902def isRoot(obj):
903 from m5.objects import Root
904 return obj and obj is Root.getInstance()
905
906def isSimObjectOrVector(value):
907 return isSimObject(value) or isSimObjectVector(value)
908
909def tryAsSimObjectOrVector(value):
910 if isSimObjectOrVector(value):
911 return value
912 if isSimObjectSequence(value):
913 return SimObjectVector(value)
914 return None
915
916def coerceSimObjectOrVector(value):
917 value = tryAsSimObjectOrVector(value)
918 if value is None:
919 raise TypeError, "SimObject or SimObjectVector expected"
920 return value
921
922baseClasses = allClasses.copy()
923baseInstances = instanceDict.copy()
924
925def clear():
926 global allClasses, instanceDict
927
928 allClasses = baseClasses.copy()
929 instanceDict = baseInstances.copy()
930
931# __all__ defines the list of symbols that get exported when
932# 'from config import *' is invoked. Try to keep this reasonably
933# short to avoid polluting other namespaces.
934__all__ = [ 'SimObject' ]