Piotr Caban : server: Use monotonic clock in waitable timers.
Alexandre Julliard
julliard at winehq.org
Thu Apr 9 16:04:47 CDT 2020
Module: wine
Branch: master
Commit: 6d2d3595c0ea08d915df5fef506fe3679ffa8051
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6d2d3595c0ea08d915df5fef506fe3679ffa8051
Author: Piotr Caban <piotr at codeweavers.com>
Date: Mon Apr 6 17:21:15 2020 +0200
server: Use monotonic clock in waitable timers.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/sync.c | 11 +++++++++--
include/wine/server_protocol.h | 2 +-
server/protocol.def | 2 +-
server/timer.c | 14 ++++++++------
4 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 2b5b6ce44a..4a7b461627 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -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
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index fa0b7ff406..cb3a073886 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -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
diff --git a/server/protocol.def b/server/protocol.def
index e12e6fbdbf..cc23ee84db 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -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
diff --git a/server/timer.c b/server/timer.c
index 9cca85569f..c1269e0ff0 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -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 )
More information about the wine-cvs
mailing list