sim: Reuse the same limit_event in simulate()

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.
This commit is contained in:
Curtis Dunham 2015-03-23 06:57:36 -04:00
parent 45286d9b64
commit 564482c782
3 changed files with 15 additions and 9 deletions

View 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

View 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();

View file

@ -33,3 +33,4 @@
#include "sim/sim_events.hh"
GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
GlobalEvent* getLimitEvent();