diff -r dc26d1d5e4a5 -r 889cd4396022 configs/common/Simulation.py --- a/configs/common/Simulation.py Wed Oct 24 17:36:45 2012 -0400 +++ b/configs/common/Simulation.py Wed Oct 24 17:55:04 2012 -0400 @@ -242,7 +242,7 @@ return exit_cause print "draining the system" - m5.doDrain(testsys) + m5.drain(testsys) m5.switchCpus(repeat_switch_cpu_list) m5.resume(testsys) @@ -469,7 +469,7 @@ print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys.switch_cpus_1[0].max_insts_any_thread) - m5.doDrain(testsys) + m5.drain(testsys) m5.switchCpus(switch_cpu_list1) m5.resume(testsys) diff -r dc26d1d5e4a5 -r 889cd4396022 src/python/m5/simulate.py --- a/src/python/m5/simulate.py Wed Oct 24 17:36:45 2012 -0400 +++ b/src/python/m5/simulate.py Wed Oct 24 17:55:04 2012 -0400 @@ -157,28 +157,29 @@ # 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) +# Drain the system in preparation of a checkpoint or memory mode +# switch. +def drain(root): + # Try 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(): + all_drained = False + dm = internal.drain.createDrainManager() + unready_objs = sum(obj.drain(dm) for obj in root.descendants()) + # If we've got some objects that can't drain immediately, then simulate + if unready_objs > 0: + dm.setCount(unready_objs) + simulate() + else: + all_drained = True + internal.drain.cleanupDrainManager(dm) + return all_drained + + all_drained = _drain() 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 - dm = internal.drain.createDrainManager() - unready_objs = sum(obj.drain(dm) for obj in root.descendants()) - # If we've got some objects that can't drain immediately, then simulate - if unready_objs > 0: - dm.setCount(unready_objs) - simulate() - else: - all_drained = True - internal.drain.cleanupDrainManager(dm) - return all_drained + all_drained = _drain() def resume(root): for obj in root.descendants(): obj.drainResume() @@ -187,7 +188,7 @@ root = objects.Root.getInstance() if not isinstance(root, objects.Root): raise TypeError, "Checkpoint must be called on a root object." - doDrain(root) + drain(root) print "Writing checkpoint" internal.core.serializeAll(dir) resume(root) @@ -197,7 +198,7 @@ raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \ (type(system), objects.Root, objects.System) if system.getMemoryMode() != mode: - doDrain(system) + drain(system) system.setMemoryMode(mode) else: print "System already in target mode. Memory mode unchanged."