]> git.proxmox.com Git - qemu.git/blobdiff - qemu-timer.c
aio / timers: On timer modification, qemu_notify or aio_notify
[qemu.git] / qemu-timer.c
index c5e456e0b14687e250f1350a27547b9d02c2f407..746ba8b7e1f952d8622a0de8fdff3241400ea811 100644 (file)
@@ -73,6 +73,8 @@ struct QEMUTimerList {
     QEMUClock *clock;
     QEMUTimer *active_timers;
     QLIST_ENTRY(QEMUTimerList) list;
+    QEMUTimerListNotifyCB *notify_cb;
+    void *notify_opaque;
 };
 
 struct qemu_alarm_timer {
@@ -243,7 +245,9 @@ next:
     }
 }
 
-static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock)
+static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock,
+                                               QEMUTimerListNotifyCB *cb,
+                                               void *opaque)
 {
     QEMUTimerList *timer_list;
 
@@ -257,13 +261,16 @@ static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock)
 
     timer_list = g_malloc0(sizeof(QEMUTimerList));
     timer_list->clock = clock;
+    timer_list->notify_cb = cb;
+    timer_list->notify_opaque = opaque;
     QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
     return timer_list;
 }
 
-QEMUTimerList *timerlist_new(QEMUClockType type)
+QEMUTimerList *timerlist_new(QEMUClockType type,
+                             QEMUTimerListNotifyCB *cb, void *opaque)
 {
-    return timerlist_new_from_clock(qemu_clock_ptr(type));
+    return timerlist_new_from_clock(qemu_clock_ptr(type), cb, opaque);
 }
 
 void timerlist_free(QEMUTimerList *timer_list)
@@ -288,7 +295,7 @@ static QEMUClock *qemu_clock_new(QEMUClockType type)
     clock->last = INT64_MIN;
     QLIST_INIT(&clock->timerlists);
     notifier_list_init(&clock->reset_notifiers);
-    clock->main_loop_timerlist = timerlist_new_from_clock(clock);
+    clock->main_loop_timerlist = timerlist_new_from_clock(clock, NULL, NULL);
     return clock;
 }
 
@@ -297,11 +304,20 @@ bool qemu_clock_use_for_deadline(QEMUClock *clock)
     return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL));
 }
 
+void qemu_clock_notify(QEMUClock *clock)
+{
+    QEMUTimerList *timer_list;
+    QLIST_FOREACH(timer_list, &clock->timerlists, list) {
+        timerlist_notify(timer_list);
+    }
+}
+
 void qemu_clock_enable(QEMUClock *clock, bool enabled)
 {
     bool old = clock->enabled;
     clock->enabled = enabled;
     if (enabled && !old) {
+        qemu_clock_notify(clock);
         qemu_rearm_alarm_timer(alarm_timer);
     }
 }
@@ -386,6 +402,15 @@ QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock)
     return clock->main_loop_timerlist;
 }
 
+void timerlist_notify(QEMUTimerList *timer_list)
+{
+    if (timer_list->notify_cb) {
+        timer_list->notify_cb(timer_list->notify_opaque);
+    } else {
+        qemu_notify_event();
+    }
+}
+
 /* Transition function to convert a nanosecond timeout to ms
  * This is used where a system does not support ppoll
  */
@@ -506,9 +531,7 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
         }
         /* Interrupt execution to force deadline recalculation.  */
         qemu_clock_warp(ts->timer_list->clock);
-        if (use_icount) {
-            qemu_notify_event();
-        }
+        timerlist_notify(ts->timer_list);
     }
 }
 
@@ -565,11 +588,12 @@ bool qemu_run_timers(QEMUClock *clock)
     return timerlist_run_timers(clock->main_loop_timerlist);
 }
 
-void timerlistgroup_init(QEMUTimerListGroup *tlg)
+void timerlistgroup_init(QEMUTimerListGroup *tlg,
+                         QEMUTimerListNotifyCB *cb, void *opaque)
 {
     QEMUClockType type;
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
-        tlg->tl[type] = timerlist_new(type);
+        tlg->tl[type] = timerlist_new(type, cb, opaque);
     }
 }