From: Piotr Caban Subject: [PATCH 3/6 v2] server: Use monotonic clock for SetTimer timeouts. Message-Id: <9b2dcc5a-6224-0221-fa12-78581564e0a7@codeweavers.com> Date: Mon, 6 Apr 2020 17:21:07 +0200 Signed-off-by: Piotr Caban --- server/file.h | 6 ++++++ server/queue.c | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/server/file.h b/server/file.h index 4f130e2cf7..7395814dad 100644 --- a/server/file.h +++ b/server/file.h @@ -140,6 +140,12 @@ static inline abstime_t timeout_to_abstime( timeout_t timeout ) return timeout > 0 ? timeout : timeout - monotonic_time; } +static inline timeout_t abstime_to_timeout( abstime_t abstime ) +{ + if (abstime > 0) return abstime; + return -abstime < monotonic_time ? 0 : abstime + monotonic_time; +} + extern void set_current_time( void ); extern struct timeout_user *add_timeout_user( timeout_t when, timeout_callback func, void *private ); extern void remove_timeout_user( struct timeout_user *user ); diff --git a/server/queue.c b/server/queue.c index b5e17be18f..84ee0f9a4e 100644 --- a/server/queue.c +++ b/server/queue.c @@ -89,7 +89,7 @@ struct message struct timer { struct list entry; /* entry in timer list */ - timeout_t when; /* next expiration */ + abstime_t when; /* next expiration */ unsigned int rate; /* timer rate in ms */ user_handle_t win; /* window handle */ unsigned int msg; /* message to post */ @@ -1154,7 +1154,7 @@ static void set_next_timer( struct msg_queue *queue ) if ((ptr = list_head( &queue->pending_timers ))) { struct timer *timer = LIST_ENTRY( ptr, struct timer, entry ); - queue->timeout = add_timeout_user( timer->when, timer_callback, queue ); + queue->timeout = add_timeout_user( abstime_to_timeout(timer->when), timer_callback, queue ); } /* set/clear QS_TIMER bit */ if (list_empty( &queue->expired_timers )) @@ -1206,7 +1206,7 @@ static void link_timer( struct msg_queue *queue, struct timer *timer ) for (ptr = queue->pending_timers.next; ptr != &queue->pending_timers; ptr = ptr->next) { struct timer *t = LIST_ENTRY( ptr, struct timer, entry ); - if (t->when >= timer->when) break; + if (t->when <= timer->when) break; } list_add_before( ptr, &timer->entry ); } @@ -1223,7 +1223,7 @@ static void free_timer( struct msg_queue *queue, struct timer *timer ) static void restart_timer( struct msg_queue *queue, struct timer *timer ) { list_remove( &timer->entry ); - while (timer->when <= current_time) timer->when += (timeout_t)timer->rate * 10000; + while (-timer->when <= monotonic_time) timer->when -= (timeout_t)timer->rate * 10000; link_timer( queue, timer ); set_next_timer( queue ); } @@ -1255,7 +1255,7 @@ static struct timer *set_timer( struct msg_queue *queue, unsigned int rate ) if (timer) { timer->rate = max( rate, 1 ); - timer->when = current_time + (timeout_t)timer->rate * 10000; + timer->when = -monotonic_time - (timeout_t)timer->rate * 10000; link_timer( queue, timer ); /* check if we replaced the next timer */ if (list_head( &queue->pending_timers ) == &timer->entry) set_next_timer( queue );