qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v2 2/5] monitor: introduce MonitorQAPIEventDelay cal


From: marcandre . lureau
Subject: [Qemu-devel] [PATCH v2 2/5] monitor: introduce MonitorQAPIEventDelay callback
Date: Thu, 17 Sep 2015 18:08:47 +0200

From: Marc-André Lureau <address@hidden>

Move the delay handling in a seperate function that can be changed for
different throttling implementations, as will be done in following commits.

Signed-off-by: Marc-André Lureau <address@hidden>
---
 monitor.c    | 85 +++++++++++++++++++++++++++++++++++++++---------------------
 trace-events |  3 ++-
 2 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/monitor.c b/monitor.c
index 2d2e030..e78ecc2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -183,6 +183,8 @@ typedef struct {
 
 typedef struct MonitorQAPIEventState MonitorQAPIEventState;
 
+typedef bool (*MonitorQAPIEventDelay)(MonitorQAPIEventState *evstate,
+                                      QDict *data);
 /*
  * To prevent flooding clients, events can be throttled. The
  * throttling is calculated globally, rather than per-Monitor
@@ -190,6 +192,7 @@ typedef struct MonitorQAPIEventState MonitorQAPIEventState;
  */
 struct MonitorQAPIEventState {
     int64_t rate;       /* Minimum time (in ns) between two events */
+    MonitorQAPIEventDelay delay;
     void *delay_data;   /* data for the throttle handler */
 };
 
@@ -463,50 +466,70 @@ static void monitor_qapi_event_emit(QAPIEvent event, 
QObject *data)
 }
 
 /*
- * Queue a new event for emission to Monitor instances,
- * applying any rate limiting if required.
+ * A simple delay handler, that will delay all events according to the
+ * evstate->rate limit.
+ *
+ * Return 'false' if the event is not delayed and can be emitted now.
  */
-static void
-monitor_qapi_event_queue(QAPIEvent event, QDict *data, Error **errp)
+static bool
+monitor_qapi_event_delay(MonitorQAPIEventState *evstate, QDict *data)
 {
-    MonitorQAPIEventState *evstate;
-    MonitorQAPIEventPending *p;
-    assert(event < QAPI_EVENT_MAX);
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+    MonitorQAPIEventPending *p = evstate->delay_data;
+    int64_t delta = now - p->last;
 
-    evstate = &monitor_qapi_event_state[event];
-    p = evstate->delay_data;
-    trace_monitor_protocol_event_queue(event,
+    trace_monitor_protocol_event_delay(p->event,
                                        data,
                                        evstate->rate,
                                        p->last,
                                        now);
 
     /* Rate limit of 0 indicates no throttling */
-    qemu_mutex_lock(&monitor_lock);
     if (!evstate->rate) {
-        monitor_qapi_event_emit(event, QOBJECT(data));
-    } else {
-        int64_t delta = now - p->last;
-        if (evstate->delay_data ||
-            delta < evstate->rate) {
-            /* If there's an existing event pending, replace
-             * it with the new event, otherwise schedule a
-             * timer for delayed emission
-             */
-            if (evstate->delay_data) {
-                qobject_decref(evstate->delay_data);
-            } else {
-                int64_t then = p->last + evstate->rate;
-                timer_mod_ns(p->timer, then);
-            }
-            evstate->delay_data = QOBJECT(data);
-            qobject_incref(evstate->delay_data);
+        p->last = now;
+        return false;
+    }
+
+    if (p->data || delta < evstate->rate) {
+        /* If there's an existing event pending, replace
+         * it with the new event, otherwise schedule a
+         * timer for delayed emission
+         */
+        if (p->data) {
+            qobject_decref(p->data);
         } else {
-            monitor_qapi_event_emit(event, QOBJECT(data));
-            p->last = now;
+            int64_t then = p->last + evstate->rate;
+            timer_mod_ns(p->timer, then);
         }
+        p->data = QOBJECT(data);
+        qobject_incref(p->data);
+        return true;
     }
+
+    p->last = now;
+    return false;
+}
+
+/*
+ * Queue a new event for emission to Monitor instances,
+ * applying any rate limiting if required.
+ */
+static void
+monitor_qapi_event_queue(QAPIEvent event, QDict *data, Error **errp)
+{
+    MonitorQAPIEventState *evstate;
+    assert(event < QAPI_EVENT_MAX);
+
+    evstate = &monitor_qapi_event_state[event];
+    trace_monitor_protocol_event_queue(event, data);
+
+    qemu_mutex_lock(&monitor_lock);
+
+    if (!evstate->delay ||
+        !evstate->delay(evstate, data)) {
+        monitor_qapi_event_emit(event, QOBJECT(data));
+    }
+
     qemu_mutex_unlock(&monitor_lock);
 }
 
@@ -566,6 +589,8 @@ monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
     trace_monitor_protocol_event_throttle(event, rate);
     assert(rate * SCALE_MS <= INT64_MAX);
     evstate->rate = rate * SCALE_MS;
+
+    evstate->delay = monitor_qapi_event_delay;
     evstate->delay_data = monitor_qapi_event_pending_new(event);
 }
 
diff --git a/trace-events b/trace-events
index 88a2f14..20eb8bf 100644
--- a/trace-events
+++ b/trace-events
@@ -1035,7 +1035,8 @@ handle_qmp_command(void *mon, const char *cmd_name) "mon 
%p cmd_name \"%s\""
 monitor_protocol_emitter(void *mon) "mon %p"
 monitor_protocol_event_handler(uint32_t event, void *data, uint64_t last, 
uint64_t now) "event=%d data=%p last=%" PRId64 " now=%" PRId64
 monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
-monitor_protocol_event_queue(uint32_t event, void *data, uint64_t rate, 
uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 
" now=%" PRId64
+monitor_protocol_event_delay(uint32_t event, void *data, uint64_t rate, 
uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 
" now=%" PRId64
+monitor_protocol_event_queue(uint32_t event, void *data) "event=%d data=%p"
 monitor_protocol_event_throttle(uint32_t event, uint64_t rate) "event=%d 
rate=%" PRId64
 
 # hw/net/opencores_eth.c
-- 
2.4.3




reply via email to

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