提交 add40e97 编写于 作者: P Paolo Bonzini

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: NAlex Bligh <alex@alex.org.uk>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 0f809e5f
...@@ -544,6 +544,19 @@ void timer_del(QEMUTimer *ts); ...@@ -544,6 +544,19 @@ void timer_del(QEMUTimer *ts);
*/ */
void timer_mod_ns(QEMUTimer *ts, int64_t expire_time); 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: * timer_mod:
* @ts: the timer * @ts: the timer
...@@ -557,6 +570,19 @@ void timer_mod_ns(QEMUTimer *ts, int64_t expire_time); ...@@ -557,6 +570,19 @@ void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
*/ */
void timer_mod(QEMUTimer *ts, int64_t expire_timer); 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: * timer_pending:
* @ts: the timer * @ts: the timer
......
...@@ -410,11 +410,40 @@ void timer_mod_ns(QEMUTimer *ts, int64_t expire_time) ...@@ -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) void timer_mod(QEMUTimer *ts, int64_t expire_time)
{ {
timer_mod_ns(ts, expire_time * ts->scale); 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) bool timer_pending(QEMUTimer *ts)
{ {
return ts->expire_time >= 0; return ts->expire_time >= 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册