aboutsummaryrefslogtreecommitdiff
path: root/qemu-timer.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-10-03 15:11:43 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2013-10-17 17:31:00 +0200
commitadd40e9777de139fb317ca6b1fb0dc142601cfcd (patch)
treebec5acdd2592edaa95f52afd6ec2526e7f390c49 /qemu-timer.c
parent0f809e5fbebb36788aea3523be7f93c04f2c7f8c (diff)
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>
Diffstat (limited to 'qemu-timer.c')
-rw-r--r--qemu-timer.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/qemu-timer.c b/qemu-timer.c
index 0305ad5313..e15ce477cc 100644
--- a/qemu-timer.c
+++ b/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;