]> git.proxmox.com Git - qemu.git/commitdiff
aio / timers: Add QEMUTimerListGroup and helper functions
authorAlex Bligh <alex@alex.org.uk>
Wed, 21 Aug 2013 15:02:48 +0000 (16:02 +0100)
committerStefan Hajnoczi <stefanha@redhat.com>
Thu, 22 Aug 2013 17:10:27 +0000 (19:10 +0200)
Add QEMUTimerListGroup and helper functions, to represent
a QEMUTimerList associated with each clock. Add a default
QEMUTimerListGroup representing the default timer lists
which are not associated with any other object (e.g.
an AioContext as added by future patches).

Signed-off-by: Alex Bligh <alex@alex.org.uk>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
include/qemu/timer.h
include/qemu/typedefs.h
qemu-timer.c

index d4b643f20e058c2eff0e4c7b55ab78d762fb4b5e..6f1ec76a577d85668c454e6d971b4bfcc99bbc4e 100644 (file)
@@ -53,6 +53,11 @@ typedef enum {
 
 typedef struct QEMUClock QEMUClock;
 typedef struct QEMUTimerList QEMUTimerList;
+
+struct QEMUTimerListGroup {
+    QEMUTimerList *tl[QEMU_CLOCK_MAX];
+};
+
 typedef void QEMUTimerCB(void *opaque);
 
 struct QEMUTimer {
@@ -64,6 +69,7 @@ struct QEMUTimer {
     int scale;
 };
 
+extern QEMUTimerListGroup main_loop_tlg;
 extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
 
 /**
@@ -217,6 +223,49 @@ QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list);
  */
 bool timerlist_run_timers(QEMUTimerList *timer_list);
 
+/**
+ * timerlistgroup_init:
+ * @tlg: the timer list group
+ *
+ * Initialise a timer list group. This must already be
+ * allocated in memory and zeroed.
+ */
+void timerlistgroup_init(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_deinit:
+ * @tlg: the timer list group
+ *
+ * Deinitialise a timer list group. This must already be
+ * initialised. Note the memory is not freed.
+ */
+void timerlistgroup_deinit(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_run_timers:
+ * @tlg: the timer list group
+ *
+ * Run the timers associated with a timer list group.
+ * This will run timers on multiple clocks.
+ *
+ * Returns: true if any timer callback ran
+ */
+bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_deadline_ns
+ * @tlg: the timer list group
+ *
+ * Determine the deadline of the soonest timer to
+ * expire associated with any timer list linked to
+ * the timer list group. Only clocks suitable for
+ * deadline calculation are included.
+ *
+ * Returns: the deadline in nanoseconds or -1 if no
+ * timers are to expire.
+ */
+int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg);
+
 /**
  * qemu_timeout_ns_to_ms:
  * @ns: nanosecond timeout value
index cae94ff57e672f1ca55ff9d8e491c41bb47b80df..320554005957549825ff6ab020ddd548381efb55 100644 (file)
@@ -4,6 +4,7 @@
 /* A load of opaque types so that device init declarations don't have to
    pull in all the real definitions.  */
 typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUTimerListGroup QEMUTimerListGroup;
 typedef struct QEMUFile QEMUFile;
 typedef struct QEMUBH QEMUBH;
 
index b045184c048a7273903724ca5afc2f008164bbed..c5e456e0b14687e250f1350a27547b9d02c2f407 100644 (file)
@@ -59,6 +59,7 @@ struct QEMUClock {
     bool enabled;
 };
 
+QEMUTimerListGroup main_loop_tlg;
 QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
 
 /* A QEMUTimerList is a list of timers attached to a clock. More
@@ -564,6 +565,46 @@ bool qemu_run_timers(QEMUClock *clock)
     return timerlist_run_timers(clock->main_loop_timerlist);
 }
 
+void timerlistgroup_init(QEMUTimerListGroup *tlg)
+{
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        tlg->tl[type] = timerlist_new(type);
+    }
+}
+
+void timerlistgroup_deinit(QEMUTimerListGroup *tlg)
+{
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        timerlist_free(tlg->tl[type]);
+    }
+}
+
+bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg)
+{
+    QEMUClockType type;
+    bool progress = false;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        progress |= timerlist_run_timers(tlg->tl[type]);
+    }
+    return progress;
+}
+
+int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
+{
+    int64_t deadline = -1;
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        if (qemu_clock_use_for_deadline(tlg->tl[type]->clock)) {
+            deadline = qemu_soonest_timeout(deadline,
+                                            timerlist_deadline_ns(
+                                                tlg->tl[type]));
+        }
+    }
+    return deadline;
+}
+
 int64_t qemu_get_clock_ns(QEMUClock *clock)
 {
     int64_t now, last;
@@ -605,6 +646,7 @@ void init_clocks(void)
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
         if (!qemu_clocks[type]) {
             qemu_clocks[type] = qemu_clock_new(type);
+            main_loop_tlg.tl[type] = qemu_clocks[type]->main_loop_timerlist;
         }
     }