qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 11/19] use a bottom half to run timers


From: Paolo Bonzini
Subject: [Qemu-devel] [PATCH 11/19] use a bottom half to run timers
Date: Mon, 21 Dec 2009 09:09:22 +0100

Make the timer subsystem register its own bottom half instead of
placing the bottom half code in the heart of the main loop.  To
test if an alarm timer is pending, just check if the bottom half is
scheduled.

Signed-off-by: Paolo Bonzini <address@hidden>
---
 vl.c |   68 ++++++++++++++++++++++++++++++++++++-----------------------------
 1 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/vl.c b/vl.c
index 78807f5..289aadc 100644
--- a/vl.c
+++ b/vl.c
@@ -573,10 +573,17 @@ struct qemu_alarm_timer {
     void (*rearm)(struct qemu_alarm_timer *t);
     void *priv;
 
+    QEMUBH *bh;
     char expired;
-    char pending;
 };
 
+static struct qemu_alarm_timer *alarm_timer;
+
+static inline int qemu_alarm_pending(void)
+{
+    return qemu_bh_scheduled(alarm_timer->bh);
+}
+
 static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
 {
     return !!t->rearm;
@@ -593,8 +600,6 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer 
*t)
 /* TODO: MIN_TIMER_REARM_US should be optimized */
 #define MIN_TIMER_REARM_US 250
 
-static struct qemu_alarm_timer *alarm_timer;
-
 #ifdef _WIN32
 
 struct qemu_alarm_win32 {
@@ -874,7 +879,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
 
     /* Rearm if necessary  */
     if (pt == &active_timers[ts->clock->type]) {
-        if (!alarm_timer->pending) {
+        if (!qemu_alarm_pending()) {
             qemu_rearm_alarm_timer(alarm_timer);
         }
         /* Interrupt execution to force deadline recalculation.  */
@@ -1001,6 +1006,31 @@ static const VMStateDescription vmstate_timers = {
 
 static void qemu_event_increment(void);
 
+static void qemu_timer_bh(void *opaque)
+{
+    struct qemu_alarm_timer *t = opaque;
+
+    /* rearm timer, if not periodic */
+    if (t->expired) {
+        t->expired = 0;
+        qemu_rearm_alarm_timer(t);
+    }
+
+    /* vm time timers */
+    if (vm_running) {
+        if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
+            qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
+                            qemu_get_clock(vm_clock));
+    }
+
+    /* real time timers */
+    qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
+                    qemu_get_clock(rt_clock));
+
+    qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
+                    qemu_get_clock(host_clock));
+}
+
 #ifdef _WIN32
 static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
                                         DWORD_PTR dwUser, DWORD_PTR dw1,
@@ -1059,8 +1089,7 @@ static void host_alarm_handler(int host_signum)
             cpu_exit(next_cpu);
         }
 #endif
-        t->pending = 1;
-        qemu_notify_event();
+        qemu_bh_schedule(t->bh);
     }
 }
 
@@ -1446,7 +1475,8 @@ static int init_timer_alarm(void)
     }
 
     /* first event is at time 0 */
-    t->pending = 1;
+    t->bh = qemu_bh_new(qemu_timer_bh, t);
+    qemu_bh_schedule(t->bh);
     alarm_timer = t;
     qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t);
 
@@ -3811,28 +3841,6 @@ void main_loop_wait(int timeout)
 
     slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
 
-    /* rearm timer, if not periodic */
-    if (alarm_timer->expired) {
-        alarm_timer->expired = 0;
-        qemu_rearm_alarm_timer(alarm_timer);
-    }
-
-    alarm_timer->pending = 0;
-
-    /* vm time timers */
-    if (vm_running) {
-        if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
-            qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
-                            qemu_get_clock(vm_clock));
-    }
-
-    /* real time timers */
-    qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
-                    qemu_get_clock(rt_clock));
-
-    qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
-                    qemu_get_clock(host_clock));
-
     /* Check bottom-halves last in case any of the earlier events triggered
        them.  */
     qemu_bh_poll();
@@ -3888,7 +3896,7 @@ static void tcg_cpu_exec(void)
 
         if (!vm_running)
             break;
-        if (alarm_timer->pending)
+        if (qemu_alarm_pending())
             break;
         if (cpu_can_run(env))
             ret = qemu_cpu_exec(env);
-- 
1.6.5.2






reply via email to

[Prev in Thread] Current Thread [Next in Thread]