From patchwork Sat Aug 10 10:06:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Bligh X-Patchwork-Id: 266216 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 AE81E2C008E for ; Sat, 10 Aug 2013 20:45:52 +1000 (EST) Received: from localhost ([::1]:49714 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V86BE-0002OS-I4 for incoming@patchwork.ozlabs.org; Sat, 10 Aug 2013 06:13:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55823) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V864a-0008Rn-2d for qemu-devel@nongnu.org; Sat, 10 Aug 2013 06:07:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V864W-0005B8-M6 for qemu-devel@nongnu.org; Sat, 10 Aug 2013 06:06:59 -0400 Received: from mail.avalus.com ([2001:41c8:10:1dd::10]:41947) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V864W-0005Az-BG for qemu-devel@nongnu.org; Sat, 10 Aug 2013 06:06:56 -0400 Received: by mail.avalus.com (Postfix) with ESMTPSA id A5BE0C561B7; Sat, 10 Aug 2013 11:06:55 +0100 (BST) From: Alex Bligh To: qemu-devel@nongnu.org Date: Sat, 10 Aug 2013 11:06:16 +0100 Message-Id: <1376129195-29872-13-git-send-email-alex@alex.org.uk> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1376129195-29872-1-git-send-email-alex@alex.org.uk> References: <1376129195-29872-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 , Jan Kiszka , liu ping fan , Stefan Hajnoczi , Paolo Bonzini , MORITA Kazutaka , rth@twiddle.net Subject: [Qemu-devel] [RFC] [PATCHv9 12/31] 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 | 27 +++++++++++++++++++++++---- qemu-timer.c | 31 ++++++++++++++++++++++++------- 3 files changed, 53 insertions(+), 12 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 fc0ba57..e70afd2 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); typedef struct QEMUTimer { int64_t expire_time; /* in nanoseconds */ @@ -132,13 +133,16 @@ QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock); /** * timerlist_new: * @type: the clock type to associate with the timerlist + * @cb: the callback to call on notification + * @opaque: the opaque pointer to pass to the callback * * Create a new timerlist associated with the clock of * type @type. * * Returns: a pointer to the QEMUTimerList created */ -QEMUTimerList *timerlist_new(QEMUClockType type); +QEMUTimerList *timerlist_new(QEMUClockType type, + QEMUTimerListNotifyCB *cb, void *opaque); /** * timerlist_free: @@ -219,13 +223,28 @@ QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list); bool timerlist_run_timers(QEMUTimerList *timer_list); /** + * 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 ff5ad50..dec4dfe 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 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; } @@ -386,6 +393,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 */ @@ -507,7 +523,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 +581,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[type] = timerlist_new(type); + tlg[type] = timerlist_new(type, cb, opaque); } }