* Steve Reinhardt
*/
+#include "sim/simulate.hh"
+
#include <mutex>
#include <thread>
#include "sim/eventq_impl.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
-#include "sim/simulate.hh"
#include "sim/stat_control.hh"
//! Mutex for handling async events.
}
}
+GlobalSimLoopExitEvent *simulate_limit_event = nullptr;
+
/** 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.
+ * terminate the loop. Exported to Python.
* @return The SimLoopExitEvent that caused the loop to exit.
*/
GlobalSimLoopExitEvent *
}
threads_initialized = true;
+ simulate_limit_event =
+ new GlobalSimLoopExitEvent(mainEventQueue[0]->getCurTick(),
+ "simulate() limit reached", 0);
}
inform("Entering event queue @ %d. Starting simulation...\n", curTick());
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);
+ simulate_limit_event->reschedule(num_cycles);
GlobalSyncEvent *quantum_event = NULL;
if (numMainEventQueues > 1) {
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();
assert(curTick() <= eventq->nextTick() &&
"event scheduled in the past");
- Event *exit_event = eventq->serviceOne();
- if (exit_event != NULL) {
- return exit_event;
- }
-
if (async_event && testAndClearAsyncEvent()) {
- async_event = false;
+ // Take the event queue lock in case any of the service
+ // routines want to schedule new events.
+ std::lock_guard<EventQueue> lock(*eventq);
if (async_statdump || async_statreset) {
Stats::schedStatEvent(async_statdump, async_statreset);
async_statdump = false;
async_statreset = false;
}
- if (async_exit) {
- async_exit = false;
- exitSimLoop("user interrupt received");
- }
-
if (async_io) {
async_io = false;
pollQueue.service();
}
+ if (async_exit) {
+ async_exit = false;
+ exitSimLoop("user interrupt received");
+ }
+
if (async_exception) {
async_exception = false;
return NULL;
}
}
+
+ Event *exit_event = eventq->serviceOne();
+ if (exit_event != NULL) {
+ return exit_event;
+ }
}
// not reached... only exit is return on SimLoopExitEvent