The timer must be rearmed if a new timeout is added at the start of
the timeout list (or the new timeout will be expired too late.) 
However, as the rearming always happens after servicing expired
timers, do not rearm in that case.

Also, move the setting of the dirty flag outside conditional in
host_alarm_handler(), to make sure it is always done. This broke kvm.


Cheers,
Anders.

diff --git a/vl.c b/vl.c
index 129166d..a7d9021 100644
--- a/vl.c
+++ b/vl.c
@@ -822,7 +822,7 @@ struct qemu_alarm_timer {
 };
 
 #define ALARM_FLAG_DYNTICKS  0x1
-#define ALARM_FLAG_MODIFIED  0x2
+#define ALARM_FLAG_EXPIRED   0x2
 
 static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
 {
@@ -834,11 +834,6 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
     if (!alarm_has_dynticks(t))
         return;
 
-    if (!(t->flags & ALARM_FLAG_MODIFIED))
-        return;
-
-    t->flags &= ~(ALARM_FLAG_MODIFIED);
-
     t->rearm(t);
 }
 
@@ -1001,8 +996,6 @@ void qemu_del_timer(QEMUTimer *ts)
 {
     QEMUTimer **pt, *t;
 
-    alarm_timer->flags |= ALARM_FLAG_MODIFIED;
-
     /* NOTE: this code must be signal safe because
        qemu_timer_expired() can be called from a signal. */
     pt = &active_timers[ts->clock->type];
@@ -1041,6 +1034,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)
@@ -1193,8 +1192,9 @@ static void host_alarm_handler(int host_signum)
 #endif
         CPUState *env = next_cpu;
 
+        alarm_timer->flags |= ALARM_FLAG_EXPIRED;
+
         if (env) {
-            alarm_timer->flags |= ALARM_FLAG_MODIFIED;
             /* stop the currently executing cpu because a timer occured */
             cpu_interrupt(env, CPU_INTERRUPT_EXIT);
 #ifdef USE_KQEMU
@@ -7396,7 +7396,10 @@ void main_loop_wait(int timeout)
     qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
                     qemu_get_clock(rt_clock));
 
-    qemu_rearm_alarm_timer(alarm_timer);
+    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.  */

Reply via email to