timer: add timer_mod_anticipate and timer_mod_anticipate_ns
These let a user anticipate the deadline of a timer, atomically with other sites that call the function. This helps avoiding complicated lock hierarchies. Reviewed-by: Alex Bligh <alex@alex.org.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
0f809e5fbe
commit
add40e9777
@ -544,6 +544,19 @@ void timer_del(QEMUTimer *ts);
|
||||
*/
|
||||
void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
|
||||
|
||||
/**
|
||||
* timer_mod_anticipate_ns:
|
||||
* @ts: the timer
|
||||
* @expire_time: the expiry time in nanoseconds
|
||||
*
|
||||
* Modify a timer to expire at @expire_time or the current time,
|
||||
* whichever comes earlier.
|
||||
*
|
||||
* This function is thread-safe but the timer and its timer list must not be
|
||||
* freed while this function is running.
|
||||
*/
|
||||
void timer_mod_anticipate_ns(QEMUTimer *ts, int64_t expire_time);
|
||||
|
||||
/**
|
||||
* timer_mod:
|
||||
* @ts: the timer
|
||||
@ -557,6 +570,19 @@ void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
|
||||
*/
|
||||
void timer_mod(QEMUTimer *ts, int64_t expire_timer);
|
||||
|
||||
/**
|
||||
* timer_mod_anticipate:
|
||||
* @ts: the timer
|
||||
* @expire_time: the expiry time in nanoseconds
|
||||
*
|
||||
* Modify a timer to expire at @expire_time or the current time, whichever
|
||||
* comes earlier, taking into account the scale associated with the timer.
|
||||
*
|
||||
* This function is thread-safe but the timer and its timer list must not be
|
||||
* freed while this function is running.
|
||||
*/
|
||||
void timer_mod_anticipate(QEMUTimer *ts, int64_t expire_time);
|
||||
|
||||
/**
|
||||
* timer_pending:
|
||||
* @ts: the timer
|
||||
|
29
qemu-timer.c
29
qemu-timer.c
@ -410,11 +410,40 @@ void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
|
||||
}
|
||||
}
|
||||
|
||||
/* modify the current timer so that it will be fired when current_time
|
||||
>= expire_time or the current deadline, whichever comes earlier.
|
||||
The corresponding callback will be called. */
|
||||
void timer_mod_anticipate_ns(QEMUTimer *ts, int64_t expire_time)
|
||||
{
|
||||
QEMUTimerList *timer_list = ts->timer_list;
|
||||
bool rearm;
|
||||
|
||||
qemu_mutex_lock(&timer_list->active_timers_lock);
|
||||
if (ts->expire_time == -1 || ts->expire_time > expire_time) {
|
||||
if (ts->expire_time != -1) {
|
||||
timer_del_locked(timer_list, ts);
|
||||
}
|
||||
rearm = timer_mod_ns_locked(timer_list, ts, expire_time);
|
||||
} else {
|
||||
rearm = false;
|
||||
}
|
||||
qemu_mutex_unlock(&timer_list->active_timers_lock);
|
||||
|
||||
if (rearm) {
|
||||
timerlist_rearm(timer_list);
|
||||
}
|
||||
}
|
||||
|
||||
void timer_mod(QEMUTimer *ts, int64_t expire_time)
|
||||
{
|
||||
timer_mod_ns(ts, expire_time * ts->scale);
|
||||
}
|
||||
|
||||
void timer_mod_anticipate(QEMUTimer *ts, int64_t expire_time)
|
||||
{
|
||||
timer_mod_anticipate_ns(ts, expire_time * ts->scale);
|
||||
}
|
||||
|
||||
bool timer_pending(QEMUTimer *ts)
|
||||
{
|
||||
return ts->expire_time >= 0;
|
||||
|
Loading…
Reference in New Issue
Block a user