Alexandre Julliard : kernel32: Use the user shared data to implement GetTickCount().

Alexandre Julliard julliard at winehq.org
Thu May 21 15:41:20 CDT 2020


Module: wine
Branch: master
Commit: cd215bb49bc240cdce5415c80264f8daa557636a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=cd215bb49bc240cdce5415c80264f8daa557636a

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu May 21 17:07:02 2020 +0200

kernel32: Use the user shared data to implement GetTickCount().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/time.c    | 62 ++++++++++++-------------------------------------
 dlls/ntdll/tests/time.c |  2 --
 2 files changed, 15 insertions(+), 49 deletions(-)

diff --git a/dlls/kernel32/time.c b/dlls/kernel32/time.c
index 47da788bee..5d27fc7ac3 100644
--- a/dlls/kernel32/time.c
+++ b/dlls/kernel32/time.c
@@ -38,9 +38,6 @@
 #elif defined(HAVE_MACHINE_LIMITS_H)
 #include <machine/limits.h>
 #endif
-#ifdef __APPLE__
-# include <mach/mach_time.h>
-#endif
 
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
@@ -49,49 +46,21 @@
 #include "winbase.h"
 #include "winreg.h"
 #include "winternl.h"
+#include "ddk/wdm.h"
 #include "kernel_private.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(time);
 
+static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000;
+
 static inline void longlong_to_filetime( LONGLONG t, FILETIME *ft )
 {
     ft->dwLowDateTime = (DWORD)t;
     ft->dwHighDateTime = (DWORD)(t >> 32);
 }
 
-#define TICKSPERSEC        10000000
-#define TICKSPERMSEC       10000
-
-/* return a monotonic time counter, in Win32 ticks */
-static inline ULONGLONG monotonic_counter(void)
-{
-    LARGE_INTEGER counter;
-
-#ifdef __APPLE__
-    static mach_timebase_info_data_t timebase;
-
-    if (!timebase.denom) mach_timebase_info( &timebase );
-#ifdef HAVE_MACH_CONTINUOUS_TIME
-    if (&mach_continuous_time != NULL)
-        return mach_continuous_time() * timebase.numer / timebase.denom / 100;
-#endif
-    return mach_absolute_time() * timebase.numer / timebase.denom / 100;
-#elif defined(HAVE_CLOCK_GETTIME)
-    struct timespec ts;
-#ifdef CLOCK_MONOTONIC_RAW
-    if (!clock_gettime( CLOCK_MONOTONIC_RAW, &ts ))
-        return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
-#endif
-    if (!clock_gettime( CLOCK_MONOTONIC, &ts ))
-        return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
-#endif
-
-    NtQueryPerformanceCounter( &counter, NULL );
-    return counter.QuadPart;
-}
-
 
 /***********************************************************************
  *           GetSystemTimeAdjustment     (KERNEL32.@)
@@ -394,24 +363,23 @@ BOOL WINAPI GetSystemTimes(LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFIL
  */
 ULONGLONG WINAPI DECLSPEC_HOTPATCH GetTickCount64(void)
 {
-    return monotonic_counter() / TICKSPERMSEC;
+    ULONG high, low;
+
+    do
+    {
+        high = user_shared_data->u.TickCount.High1Time;
+        low = user_shared_data->u.TickCount.LowPart;
+    }
+    while (high != user_shared_data->u.TickCount.High2Time);
+    /* note: we ignore TickCountMultiplier */
+    return (ULONGLONG)high << 32 | low;
 }
 
 /***********************************************************************
  *           GetTickCount       (KERNEL32.@)
- *
- * Get the number of milliseconds the system has been running.
- *
- * PARAMS
- *  None.
- *
- * RETURNS
- *  The current tick count.
- *
- * NOTES
- *  The value returned will wrap around every 2^32 milliseconds.
  */
 DWORD WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
 {
-    return monotonic_counter() / TICKSPERMSEC;
+    /* note: we ignore TickCountMultiplier */
+    return user_shared_data->u.TickCount.LowPart;
 }
diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c
index 1628af8df2..99bddd4fec 100644
--- a/dlls/ntdll/tests/time.c
+++ b/dlls/ntdll/tests/time.c
@@ -185,8 +185,6 @@ static void test_user_shared_data_time(void)
         t3 = GetTickCount();
     } while(t3 < t1 && i++ < 1); /* allow for wrap, but only once */
 
-    /* FIXME: not always in order, but should be close */
-    todo_wine_if(t1 > t2 && t1 - t2 < 50)
     ok(t1 <= t2, "USD TickCount / GetTickCount are out of order: %s %s\n",
        wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
     ok(t2 <= t3, "USD TickCount / GetTickCount are out of order: %s %s\n",




More information about the wine-cvs mailing list