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:
parent
af89b53cef
commit
6d2d3595c0
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
Loading…
Reference in New Issue