Il 08/08/2013 23:42, Alex Bligh ha scritto: > Add a notify pointer to QEMUTimerList so it knows what to notify > on a timer change.
If we do the "two AioContexts" trick, this can simply be a back-pointer to the AioContext. Paolo > Signed-off-by: Alex Bligh <a...@alex.org.uk> > --- > 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); > } > } > >