summaryrefslogtreecommitdiff
path: root/src/sim/simulate.cc
diff options
context:
space:
mode:
authorCurtis Dunham <Curtis.Dunham@arm.com>2014-12-19 15:32:34 -0600
committerCurtis Dunham <Curtis.Dunham@arm.com>2014-12-19 15:32:34 -0600
commitb89fd576633f63b14b8e5eb24de377e4918c363d (patch)
tree1ffcf6c6b299460668dc14af07af2d4c30e94bbd /src/sim/simulate.cc
parent20111ba9171378bbf3bfd2f4628d7e8a0e9cbd3b (diff)
downloadgem5-b89fd576633f63b14b8e5eb24de377e4918c363d.tar.xz
sim: prioritize async events; prevent starvation
If a time quantum event is the only one in the queue, async events (Ctrl-C, I/O, etc.) will never be processed. So process them first.
Diffstat (limited to 'src/sim/simulate.cc')
-rw-r--r--src/sim/simulate.cc21
1 files changed, 10 insertions, 11 deletions
diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc
index 426c3e662..7d88dc11d 100644
--- a/src/sim/simulate.cc
+++ b/src/sim/simulate.cc
@@ -192,37 +192,36 @@ doSimLoop(EventQueue *eventq)
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()) {
// Take the event queue lock in case any of the service
// routines want to schedule new events.
std::lock_guard<EventQueue> lock(*eventq);
- async_event = false;
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