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