sim: Reuse the same limit_event in simulate()
authorCurtis Dunham <Curtis.Dunham@arm.com>
Mon, 23 Mar 2015 10:57:36 +0000 (06:57 -0400)
committerCurtis Dunham <Curtis.Dunham@arm.com>
Mon, 23 Mar 2015 10:57:36 +0000 (06:57 -0400)
This patch accomplishes two things:
1. Makes simulate()'s GlobalSimLoopExitEvent a singleton reused
   across calls. This is slightly more efficient than recreating
   it every time.
2. Gives callers to simulate() (especially other simulators) a
   foolproof way of knowing that the simulation period ended
   successfully by hitting the limit event. They can call
   getLimitEvent() and compare it to the return
   value of simulate().

This change was motivated by an ongoing effort to integrate gem5
and SST, with SST as the master sim and gem5 as the slave sim.

src/sim/sim_events.hh
src/sim/simulate.cc
src/sim/simulate.hh

index 5be2609fd02449b5bdbd328dcc11abcbf22b5dde..4d001f8f0178444124511a4ae00e0eb08ced39b2 100644 (file)
@@ -71,6 +71,11 @@ class GlobalSimLoopExitEvent : public GlobalEvent
     void process();     // process event
 
     virtual const char *description() const;
+
+    virtual ~GlobalSimLoopExitEvent() {
+        // simulate()'s singleton GlobalSimLoopExitEvent is always scheduled
+        deschedule();
+    }
 };
 
 class LocalSimLoopExitEvent : public Event
index 7d88dc11d3941e6e44e1360fe3e434f63322a69b..14dd00fc1f6a67c4ad09853c3fddd4cb2aeee0b7 100644 (file)
@@ -71,6 +71,14 @@ thread_loop(EventQueue *queue)
     }
 }
 
+GlobalEvent*
+getLimitEvent(void) {
+    static GlobalSimLoopExitEvent
+           simulate_limit_event(mainEventQueue[0]->getCurTick(),
+                                "simulate() limit reached", 0);
+    return &simulate_limit_event;
+}
+
 /** Simulate for num_cycles additional cycles.  If num_cycles is -1
  * (the default), do not limit simulation; some other event must
  * terminate the loop.  Exported to Python via SWIG.
@@ -105,8 +113,7 @@ simulate(Tick num_cycles)
     else // counter would roll over or be set to MaxTick anyhow
         num_cycles = MaxTick;
 
-    GlobalEvent *limit_event = new GlobalSimLoopExitEvent(num_cycles,
-                                "simulate() limit reached", 0, 0);
+    getLimitEvent()->reschedule(num_cycles);
 
     GlobalSyncEvent *quantum_event = NULL;
     if (numMainEventQueues > 1) {
@@ -137,13 +144,6 @@ simulate(Tick num_cycles)
         dynamic_cast<GlobalSimLoopExitEvent *>(global_event);
     assert(global_exit_event != NULL);
 
-    // if we didn't hit limit_event, delete it.
-    if (global_exit_event != limit_event) {
-        assert(limit_event->scheduled());
-        limit_event->deschedule();
-        delete limit_event;
-    }
-
     //! Delete the simulation quantum event.
     if (quantum_event != NULL) {
         quantum_event->deschedule();
index 5e51c76b66f59ddb67718c74744c1286c84a9d10..18be7ea825e9626495f31b7609dbf6d1183a86f2 100644 (file)
@@ -33,3 +33,4 @@
 #include "sim/sim_events.hh"
 
 GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
+GlobalEvent* getLimitEvent();