sim: move iterating over SimObjects into Python.
authorSteve Reinhardt <steve.reinhardt@amd.com>
Tue, 17 Aug 2010 12:08:50 +0000 (05:08 -0700)
committerSteve Reinhardt <steve.reinhardt@amd.com>
Tue, 17 Aug 2010 12:08:50 +0000 (05:08 -0700)
src/python/m5/SimObject.py
src/python/m5/core.py
src/python/m5/simulate.py
src/python/m5/stats.py
src/python/swig/core.i
src/python/swig/pyobject.hh
src/python/swig/sim_object.i
src/sim/sim_object.cc
src/sim/sim_object.hh

index 69f79ed615a63847897cd6d3665d0b532544e5ec..a3905949a011208ca7c1cff814f2b9e962a7baef 100644 (file)
@@ -530,7 +530,8 @@ class SimObject(object):
         # If the attribute exists on the C++ object, transparently
         # forward the reference there.  This is typically used for
         # SWIG-wrapped methods such as init(), regStats(),
-        # regFormulas(), resetStats(), and startup().
+        # regFormulas(), resetStats(), startup(), drain(), and
+        # resume().
         if self._ccObject and hasattr(self._ccObject, attr):
             return getattr(self._ccObject, attr)
 
@@ -660,7 +661,7 @@ class SimObject(object):
     def unproxy(self, base):
         return self
 
-    def unproxy_all(self):
+    def unproxyParams(self):
         for param in self._params.iterkeys():
             value = self._values.get(param)
             if value != None and isproxy(value):
@@ -681,12 +682,6 @@ class SimObject(object):
             if port != None:
                 port.unproxy(self)
 
-        # Unproxy children in sorted order for determinism also.
-        child_names = self._children.keys()
-        child_names.sort()
-        for child in child_names:
-            self._children[child].unproxy_all()
-
     def print_ini(self, ini_file):
         print >>ini_file, '[' + self.path() + ']'       # .ini section header
 
@@ -717,9 +712,6 @@ class SimObject(object):
 
         print >>ini_file        # blank line between objects
 
-        for child in child_names:
-            self._children[child].print_ini(ini_file)
-
     def getCCParams(self):
         if self._ccParams:
             return self._ccParams
@@ -774,39 +766,25 @@ class SimObject(object):
                   % self.path()
         return self._ccObject
 
-    # Call C++ to create C++ object corresponding to this object and
-    # (recursively) all its children
+    def descendants(self):
+        yield self
+        for child in self._children.itervalues():
+            for obj in child.descendants():
+                yield obj
+
+    # Call C++ to create C++ object corresponding to this object
     def createCCObject(self):
         self.getCCParams()
         self.getCCObject() # force creation
-        for child in self._children.itervalues():
-            child.createCCObject()
 
     def getValue(self):
         return self.getCCObject()
 
     # Create C++ port connections corresponding to the connections in
-    # _port_refs (& recursively for all children)
+    # _port_refs
     def connectPorts(self):
         for portRef in self._port_refs.itervalues():
             portRef.ccConnect()
-        for child in self._children.itervalues():
-            child.connectPorts()
-
-    def startDrain(self, drain_event, recursive):
-        count = 0
-        if isinstance(self, SimObject):
-            count += self._ccObject.drain(drain_event)
-        if recursive:
-            for child in self._children.itervalues():
-                count += child.startDrain(drain_event, True)
-        return count
-
-    def resume(self):
-        if isinstance(self, SimObject):
-            self._ccObject.resume()
-        for child in self._children.itervalues():
-            child.resume()
 
     def getMemoryMode(self):
         if not isinstance(self, m5.objects.System):
@@ -820,8 +798,6 @@ class SimObject(object):
             # setMemoryMode directly from self._ccObject results in calling
             # SimObject::setMemoryMode, not the System::setMemoryMode
             self._ccObject.setMemoryMode(mode)
-        for child in self._children.itervalues():
-            child.changeTiming(mode)
 
     def takeOverFrom(self, old_cpu):
         self._ccObject.takeOverFrom(old_cpu._ccObject)
index 1d7985be62b5e16526dec1b4df5e3aa6ea01aff2..8fa3d6faca514e6b2860a256925f8a94b1313a3e 100644 (file)
 # Authors: Nathan Binkert
 
 import internal
-from internal.core import initAll, regAllStats
 
 def setOutputDir(dir):
     internal.core.setOutputDir(dir)
-
-def initAll():
-    internal.core.initAll()
-
-def regAllStats():
-    internal.core.regAllStats()
-
index 2db5c6952865a8abf1b1a87f5e41544f261b8065..54c6a0a2dfbff957d64e4ac24ab543120548535a 100644 (file)
@@ -55,25 +55,29 @@ def instantiate():
     # we need to fix the global frequency
     ticks.fixGlobalFrequency()
 
-    root.unproxy_all()
+    # 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')
-        root.print_ini(ini_file)
+        # 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()
 
     # Initialize the global statistics
     stats.initSimStats()
 
     # Create the C++ sim objects and connect ports
-    root.createCCObject()
-    root.connectPorts()
+    for obj in root.descendants(): obj.createCCObject()
+    for obj in root.descendants(): obj.connectPorts()
 
     # Do a second pass to finish initializing the sim objects
-    core.initAll()
+    for obj in root.descendants(): obj.init()
 
     # Do a third pass to initialize statistics
-    core.regAllStats()
+    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()
@@ -97,7 +101,8 @@ def simulate(*args, **kwargs):
     global need_resume, need_startup
 
     if need_startup:
-        internal.core.startupAll()
+        root = objects.Root.getInstance()
+        for obj in root.descendants(): obj.startup()
         need_startup = False
 
     for root in need_resume:
@@ -129,10 +134,10 @@ def doDrain(root):
 def drain(root):
     all_drained = False
     drain_event = internal.event.createCountedDrain()
-    unready_objects = root.startDrain(drain_event, True)
+    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_objects > 0:
-        drain_event.setCount(unready_objects)
+    if unready_objs > 0:
+        drain_event.setCount(unready_objs)
         simulate()
     else:
         all_drained = True
@@ -140,7 +145,7 @@ def drain(root):
     return all_drained
 
 def resume(root):
-    root.resume()
+    for obj in root.descendants(): obj.resume()
 
 def checkpoint(dir):
     root = objects.Root.getInstance()
@@ -165,7 +170,8 @@ def changeToAtomic(system):
     if system.getMemoryMode() != objects.params.atomic:
         doDrain(system)
         print "Changing memory mode to atomic"
-        system.changeTiming(objects.params.atomic)
+        for obj in system.descendants():
+            obj.changeTiming(objects.params.atomic)
 
 def changeToTiming(system):
     if not isinstance(system, (objects.Root, objects.System)):
@@ -175,7 +181,8 @@ def changeToTiming(system):
     if system.getMemoryMode() != objects.params.timing:
         doDrain(system)
         print "Changing memory mode to timing"
-        system.changeTiming(objects.params.timing)
+        for obj in system.descendants():
+            obj.changeTiming(objects.params.timing)
 
 def switchCpus(cpuList):
     print "switching cpus"
index 40a49b001607ab33763cf65d9a0bcc6da5cdccfc..76729d5ee42a5b9c772df02320a52dda15bd6cb0 100644 (file)
@@ -29,6 +29,7 @@
 import internal
 
 from internal.stats import StatEvent as event
+from objects import Root
 
 def initText(filename, desc=True):
     internal.stats.initText(filename, desc)
@@ -56,4 +57,8 @@ def dump():
     internal.stats.dump()
 
 def reset():
+    # call reset stats on all SimObjects
+    root = Root.getInstance()
+    for obj in root.descendants(): obj.resetStats()
+    # call any other registered stats reset callbacks
     internal.stats.reset()
index f7a075f74e5960bf3e3ce7a480a5e18e9ecacbb1..81085dd06426eb5c23f55705855acf9a6e574b8f 100644 (file)
@@ -78,10 +78,6 @@ Tick curTick;
 void serializeAll(const std::string &cpt_dir);
 void unserializeAll(const std::string &cpt_dir);
 
-void initAll();
-void regAllStats();
-void startupAll();
-
 bool want_warn, warn_verbose;
 bool want_info, info_verbose;
 bool want_hack, hack_verbose;
index 01f0fd95ec1abd01458b2f85072e73f6afc11033..a27080d08210691e78da2b9e7572114d51cc79d2 100644 (file)
@@ -45,17 +45,6 @@ SimObject *resolveSimObject(const std::string &name);
 int connectPorts(SimObject *o1, const std::string &name1, int i1,
     SimObject *o2, const std::string &name2, int i2);
 
-inline void
-initAll()
-{
-    SimObject::initAll();
-}
-
-inline void
-regAllStats()
-{
-    SimObject::regAllStats();
-}
 
 inline void
 serializeAll(const std::string &cpt_dir)
@@ -68,9 +57,3 @@ unserializeAll(const std::string &cpt_dir)
 {
     Serializable::unserializeAll(cpt_dir);
 }
-
-inline void
-startupAll()
-{
-    SimObject::startupAll();
-}
index c98e44ec25b07b4588ca1220c71a8a83cc511f74..8cd8e8beb74361832a43ec6c00e427426a0ddc1d 100644 (file)
@@ -50,6 +50,12 @@ class SimObject {
       Drained
     };
 
+    void init();
+    void regStats();
+    void regFormulas();
+    void resetStats();
+    void startup();
+
     unsigned int drain(Event *drain_event);
     void resume();
     void switchOut();
index 0b18ff437b57c9e846bf53be13441be3d7922c73..157bf1395305801c6d3f6fd374c3614880fa79f8 100644 (file)
@@ -96,76 +96,6 @@ SimObject::resetStats()
 {
 }
 
-//
-// static function:
-//   call regStats() on all SimObjects and then regFormulas() on all
-//   SimObjects.
-//
-struct SimObjectResetCB : public Callback
-{
-    virtual void process() { SimObject::resetAllStats(); }
-};
-
-namespace {
-    static SimObjectResetCB StatResetCB;
-}
-
-void
-SimObject::regAllStats()
-{
-    SimObjectList::iterator i;
-    SimObjectList::iterator end = simObjectList.end();
-
-    /**
-     * @todo change cprintfs to DPRINTFs
-     */
-    for (i = simObjectList.begin(); i != end; ++i) {
-#ifdef STAT_DEBUG
-        cprintf("registering stats for %s\n", (*i)->name());
-#endif
-        (*i)->regStats();
-    }
-
-    for (i = simObjectList.begin(); i != end; ++i) {
-#ifdef STAT_DEBUG
-        cprintf("registering formulas for %s\n", (*i)->name());
-#endif
-        (*i)->regFormulas();
-    }
-
-    Stats::registerResetCallback(&StatResetCB);
-}
-
-//
-// static function: call init() on all SimObjects.
-//
-void
-SimObject::initAll()
-{
-    SimObjectList::iterator i = simObjectList.begin();
-    SimObjectList::iterator end = simObjectList.end();
-
-    for (; i != end; ++i) {
-        SimObject *obj = *i;
-        obj->init();
-    }
-}
-
-//
-// static function: call resetStats() on all SimObjects.
-//
-void
-SimObject::resetAllStats()
-{
-    SimObjectList::iterator i = simObjectList.begin();
-    SimObjectList::iterator end = simObjectList.end();
-
-    for (; i != end; ++i) {
-        SimObject *obj = *i;
-        obj->resetStats();
-    }
-}
-
 //
 // static function: serialize all SimObjects.
 //
@@ -201,18 +131,6 @@ SimObject::unserializeAll(Checkpoint *cp)
 }
 
 
-void
-SimObject::startupAll()
-{
-    SimObjectList::iterator i = simObjectList.begin();
-    SimObjectList::iterator end = simObjectList.end();
-
-    while (i != end) {
-        (*i)->startup();
-        ++i;
-    }
-}
-
 
 #ifdef DEBUG
 //
index 2bea97301d62a2b14b3fa005a76e7dfc09218294..1b22c5825c45db804c54782aefbcfba22b4b1218 100644 (file)
@@ -94,7 +94,6 @@ class SimObject : public EventManager, public Serializable
     // initialization pass of all objects.
     // Gets invoked after construction, before unserialize.
     virtual void init();
-    static void initAll();
 
     // register statistics for this object
     virtual void regStats();
@@ -104,13 +103,6 @@ class SimObject : public EventManager, public Serializable
     // final initialization before simulation
     // all state is unserialized so 
     virtual void startup();
-    static void startupAll();
-
-    // static: call reg_stats on all SimObjects
-    static void regAllStats();
-
-    // static: call resetStats on all SimObjects
-    static void resetAllStats();
 
     // static: call nameOut() & serialize() on all SimObjects
     static void serializeAll(std::ostream &);