mirror of https://gitee.com/openkylin/qemu.git
aio / timers: Add a notify callback to QEMUTimerList
Add a notify pointer to QEMUTimerList so it knows what to notify on a timer change. Signed-off-by: Alex Bligh <alex@alex.org.uk> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
dae21b98b9
commit
d5541d8680
7
async.c
7
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);
|
||||
timerlistgroup_init(&ctx->tlg);
|
||||
timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ struct QEMUTimerListGroup {
|
|||
};
|
||||
|
||||
typedef void QEMUTimerCB(void *opaque);
|
||||
typedef void QEMUTimerListNotifyCB(void *opaque);
|
||||
|
||||
struct QEMUTimer {
|
||||
int64_t expire_time; /* in nanoseconds */
|
||||
|
@ -137,13 +138,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:
|
||||
|
@ -223,14 +227,29 @@ 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.
|
||||
* 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);
|
||||
void timerlistgroup_init(QEMUTimerListGroup *tlg,
|
||||
QEMUTimerListNotifyCB *cb, void *opaque);
|
||||
|
||||
/**
|
||||
* timerlistgroup_deinit:
|
||||
|
|
31
qemu-timer.c
31
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->tl[type] = timerlist_new(type);
|
||||
tlg->tl[type] = timerlist_new(type, cb, opaque);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue