server: Use monotonic clock in waitable timers.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
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;
/* convert from absolute into relative time */
NtQuerySystemTime(&now);
/* convert into relative time */
if (basic_info->RemainingTime.QuadPart > 0)
NtQuerySystemTime(&now);
else
{
RtlQueryPerformanceCounter(&now);
basic_info->RemainingTime.QuadPart = -basic_info->RemainingTime.QuadPart;
}
if (now.QuadPart > basic_info->RemainingTime.QuadPart)
basic_info->RemainingTime.QuadPart = 0;
else

View File

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

View File

@ -487,7 +487,7 @@ typedef union
enum apc_type type; /* APC_TIMER */
int __pad;
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 */
} timer;
struct

View File

@ -43,7 +43,7 @@ struct timer
int manual; /* manual reset */
int signaled; /* current signaled state */
unsigned int period; /* timer period in ms */
timeout_t when; /* next expiration */
abstime_t when; /* next expiration */
struct timeout_user *timeout; /* timeout user */
struct thread *thread; /* thread that set the 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 */
{
timer->when += (timeout_t)timer->period * 10000;
timer->timeout = add_timeout_user( timer->when, timer_callback, timer );
if (timer->when > 0) timer->when = -monotonic_time;
timer->when -= (abstime_t)timer->period * 10000;
timer->timeout = add_timeout_user( abstime_to_timeout(timer->when), timer_callback, timer );
}
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 */
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->callback = callback;
timer->arg = arg;
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;
}
static void timer_dump( struct object *obj, int verbose )
{
struct timer *timer = (struct timer *)obj;
timeout_t timeout = abstime_to_timeout( timer->when );
assert( obj->ops == &timer_ops );
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 )