server: Use monotonic clock in waitable timers.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2020-04-06 17:21:15 +02:00 committed by Alexandre Julliard
parent af89b53cef
commit 6d2d3595c0
4 changed files with 19 additions and 10 deletions

View File

@ -1025,8 +1025,15 @@ NTSTATUS WINAPI NtQueryTimer(
} }
SERVER_END_REQ; SERVER_END_REQ;
/* convert from absolute into relative time */ /* convert into relative time */
if (basic_info->RemainingTime.QuadPart > 0)
NtQuerySystemTime(&now); NtQuerySystemTime(&now);
else
{
RtlQueryPerformanceCounter(&now);
basic_info->RemainingTime.QuadPart = -basic_info->RemainingTime.QuadPart;
}
if (now.QuadPart > basic_info->RemainingTime.QuadPart) if (now.QuadPart > basic_info->RemainingTime.QuadPart)
basic_info->RemainingTime.QuadPart = 0; basic_info->RemainingTime.QuadPart = 0;
else else

View File

@ -471,7 +471,7 @@ typedef union
enum apc_type type; enum apc_type type;
int __pad; int __pad;
client_ptr_t func; client_ptr_t func;
timeout_t time; abstime_t time;
client_ptr_t arg; client_ptr_t arg;
} timer; } timer;
struct struct

View File

@ -487,7 +487,7 @@ typedef union
enum apc_type type; /* APC_TIMER */ enum apc_type type; /* APC_TIMER */
int __pad; int __pad;
client_ptr_t func; /* void (__stdcall *func)(void*, unsigned int, unsigned int); */ client_ptr_t func; /* void (__stdcall *func)(void*, unsigned int, unsigned int); */
timeout_t time; /* absolute time of expiration */ abstime_t time; /* time of expiration */
client_ptr_t arg; /* user argument */ client_ptr_t arg; /* user argument */
} timer; } timer;
struct struct

View File

@ -43,7 +43,7 @@ struct timer
int manual; /* manual reset */ int manual; /* manual reset */
int signaled; /* current signaled state */ int signaled; /* current signaled state */
unsigned int period; /* timer period in ms */ unsigned int period; /* timer period in ms */
timeout_t when; /* next expiration */ abstime_t when; /* next expiration */
struct timeout_user *timeout; /* timeout user */ struct timeout_user *timeout; /* timeout user */
struct thread *thread; /* thread that set the APC function */ struct thread *thread; /* thread that set the APC function */
client_ptr_t callback; /* callback APC function */ client_ptr_t callback; /* callback APC function */
@ -132,8 +132,9 @@ static void timer_callback( void *private )
if (timer->period) /* schedule the next expiration */ if (timer->period) /* schedule the next expiration */
{ {
timer->when += (timeout_t)timer->period * 10000; if (timer->when > 0) timer->when = -monotonic_time;
timer->timeout = add_timeout_user( timer->when, timer_callback, timer ); timer->when -= (abstime_t)timer->period * 10000;
timer->timeout = add_timeout_user( abstime_to_timeout(timer->when), timer_callback, timer );
} }
else timer->timeout = NULL; else timer->timeout = NULL;
@ -171,21 +172,22 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
period = 0; /* period doesn't make any sense for a manual timer */ period = 0; /* period doesn't make any sense for a manual timer */
timer->signaled = 0; timer->signaled = 0;
} }
timer->when = (expire <= 0) ? current_time - expire : max( expire, current_time ); timer->when = (expire <= 0) ? expire - monotonic_time : max( expire, current_time );
timer->period = period; timer->period = period;
timer->callback = callback; timer->callback = callback;
timer->arg = arg; timer->arg = arg;
if (callback) timer->thread = (struct thread *)grab_object( current ); if (callback) timer->thread = (struct thread *)grab_object( current );
timer->timeout = add_timeout_user( timer->when, timer_callback, timer ); timer->timeout = add_timeout_user( expire, timer_callback, timer );
return signaled; return signaled;
} }
static void timer_dump( struct object *obj, int verbose ) static void timer_dump( struct object *obj, int verbose )
{ {
struct timer *timer = (struct timer *)obj; struct timer *timer = (struct timer *)obj;
timeout_t timeout = abstime_to_timeout( timer->when );
assert( obj->ops == &timer_ops ); assert( obj->ops == &timer_ops );
fprintf( stderr, "Timer manual=%d when=%s period=%u\n", fprintf( stderr, "Timer manual=%d when=%s period=%u\n",
timer->manual, get_timeout_str(timer->when), timer->period ); timer->manual, get_timeout_str(timeout), timer->period );
} }
static struct object_type *timer_get_type( struct object *obj ) static struct object_type *timer_get_type( struct object *obj )