diff --git a/qemu/vl.c b/qemu/vl.c index 28c5df4..000df7e 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -850,6 +850,7 @@ struct qemu_alarm_timer { }; #define ALARM_FLAG_DYNTICKS 0x1 +#define ALARM_FLAG_EXPIRED 0x2 static inline int alarm_has_dynticks(struct qemu_alarm_timer *t) { @@ -1061,6 +1062,12 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) ts->expire_time = expire_time; ts->next = *pt; *pt = ts; + + /* Rearm if necessary */ + if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0 + && pt == &active_timers[ts->clock->type]) { + qemu_rearm_alarm_timer(alarm_timer); + } } int qemu_timer_pending(QEMUTimer *ts) @@ -1095,7 +1102,6 @@ static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time) /* run the callback (the timer list can be modified) */ ts->cb(ts->opaque); } - qemu_rearm_alarm_timer(alarm_timer); } int64_t qemu_get_clock(QEMUClock *clock) @@ -1215,6 +1221,8 @@ static void host_alarm_handler(int host_signum) #endif CPUState *env = next_cpu; + alarm_timer->flags |= ALARM_FLAG_EXPIRED; + if (env) { /* stop the currently executing cpu because a timer occured */ cpu_interrupt(env, CPU_INTERRUPT_EXIT); @@ -7726,6 +7734,11 @@ void main_loop_wait(int timeout) qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], qemu_get_clock(rt_clock)); + if (alarm_timer->flags & ALARM_FLAG_EXPIRED) { + alarm_timer->flags &= ~(ALARM_FLAG_EXPIRED); + qemu_rearm_alarm_timer(alarm_timer); + } + /* Check bottom-halves last in case any of the earlier events triggered them. */ qemu_bh_poll();