From patchwork Thu Aug 8 21:42:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Bligh X-Patchwork-Id: 265827 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (unknown [IPv6:2001:4830:134:3::12]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1BC0E2C0089 for ; Fri, 9 Aug 2013 07:49:40 +1000 (EST) Received: from localhost ([::1]:34432 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V7Y5S-0005gq-9U for incoming@patchwork.ozlabs.org; Thu, 08 Aug 2013 17:49:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54694) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V7Xyx-0006OI-2d for qemu-devel@nongnu.org; Thu, 08 Aug 2013 17:42:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V7Xyv-00072A-10 for qemu-devel@nongnu.org; Thu, 08 Aug 2013 17:42:54 -0400 Received: from mail.avalus.com ([2001:41c8:10:1dd::10]:35780) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V7Xyu-00071u-Ms for qemu-devel@nongnu.org; Thu, 08 Aug 2013 17:42:52 -0400 Received: by mail.avalus.com (Postfix) with ESMTPSA id E4D7FC561B5; Thu, 8 Aug 2013 22:42:50 +0100 (BST) From: Alex Bligh To: qemu-devel@nongnu.org Date: Thu, 8 Aug 2013 22:42:08 +0100 Message-Id: <1375998147-24292-12-git-send-email-alex@alex.org.uk> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1375998147-24292-1-git-send-email-alex@alex.org.uk> References: <1375998147-24292-1-git-send-email-alex@alex.org.uk> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:41c8:10:1dd::10 Cc: Kevin Wolf , Anthony Liguori , Alex Bligh , liu ping fan , Stefan Hajnoczi , Paolo Bonzini , MORITA Kazutaka , rth@twiddle.net Subject: [Qemu-devel] [RFC] [PATCHv8 11/30] aio / timers: Add a notify callback to QEMUTimerList X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add a notify pointer to QEMUTimerList so it knows what to notify on a timer change. Signed-off-by: Alex Bligh --- async.c | 7 ++++++- include/qemu/timer.h | 35 ++++++++++++++++++++++++++++++++--- qemu-timer.c | 24 ++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/async.c b/async.c index 99fb5a8..2051921 100644 --- a/async.c +++ b/async.c @@ -234,6 +234,11 @@ void aio_notify(AioContext *ctx) event_notifier_set(&ctx->notifier); } +static void aio_timerlist_notify(void *opaque) +{ + aio_notify(opaque); +} + AioContext *aio_context_new(void) { AioContext *ctx; @@ -245,7 +250,7 @@ AioContext *aio_context_new(void) aio_set_event_notifier(ctx, &ctx->notifier, (EventNotifierHandler *) event_notifier_test_and_clear, NULL); - timerlistgroup_init(ctx->tlg); + timerlistgroup_init(ctx->tlg, aio_timerlist_notify, ctx); return ctx; } diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 3b46f60..07e6d9e 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -54,6 +54,7 @@ typedef struct QEMUClock QEMUClock; typedef struct QEMUTimerList QEMUTimerList; typedef QEMUTimerList *QEMUTimerListGroup[QEMU_CLOCK_MAX]; typedef void QEMUTimerCB(void *opaque); +typedef void QEMUTimerListNotifyCB(void *opaque); extern QEMUTimerListGroup main_loop_tlg; extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX]; @@ -213,13 +214,41 @@ QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list); bool timerlist_run_timers(QEMUTimerList *timer_list); /** + * timerlist_set_notify_cb: + * @timer_list: the timer list to use + * @cb: the callback to call on notification + * @opaque: the opaque pointer to pass to the callback + * + * Set the notify callback for a timer list. The notifier + * callback is called when the clock is reenabled or a timer + * on the list is modified. + */ +void timerlist_set_notify_cb(QEMUTimerList *timer_list, + QEMUTimerListNotifyCB *cb, void *opaque); + +/** + * timerlist_notify: + * @timer_list: the timer list to use + * + * call the notifier callback associated with the timer list. + */ +void timerlist_notify(QEMUTimerList *timer_list); + +/** * timerlistgroup_init: * @tlg: the timer list group + * @cb: the callback to call when a notify is required + * @opaque: the opaque pointer to be passed to the callback. * * Initialise a timer list group. This must already be - * allocated in memory and zeroed. - */ -void timerlistgroup_init(QEMUTimerListGroup tlg); + * allocated in memory and zeroed. The notifier callback is + * called whenever a clock in the timer list group is + * reenabled or whenever a timer associated with any timer + * list is modified. If @cb is specified as null, qemu_notify() + * is used instead. + */ +void timerlistgroup_init(QEMUTimerListGroup tlg, + QEMUTimerListNotifyCB *cb, void *opaque); /** * timerlistgroup_deinit: diff --git a/qemu-timer.c b/qemu-timer.c index e151d24..14cb433 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -73,6 +73,8 @@ struct QEMUTimerList { QEMUClock *clock; QEMUTimer *active_timers; QLIST_ENTRY(QEMUTimerList) list; + QEMUTimerListNotifyCB *notify_cb; + void *notify_opaque; }; struct QEMUTimer { @@ -394,6 +396,22 @@ QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock) return clock->main_loop_timerlist; } +void timerlist_set_notify_cb(QEMUTimerList *timer_list, + QEMUTimerListNotifyCB *cb, void *opaque) +{ + timer_list->notify_cb = cb; + timer_list->notify_opaque = opaque; +} + +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 */ @@ -518,7 +536,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); } } } @@ -576,11 +594,13 @@ 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[type] = timerlist_new(type); + timerlist_set_notify_cb(tlg[type], cb, opaque); } }