This patch significantly increases the precision of gettimeofday() on Windows 8 or later. It is then similar to Cygwin or Linux.

It also affects C++11 std::chrono:*_clock as _GLIBCXX_USE_GETTIMEOFDAY is defined but not _GLIBCXX_USE_CLOCK_*.

A similar change (or a call to getntptimeofday()) would possibly also make sense for clock_gettime(CLOCK_REALTIME,...).

Drawback: GetSystemTimePreciseAsFileTime() is slower than the legacy function. But it is still reasonably fast. Average time per call on an old machine with i7-2600K:
GetSystemTimePreciseAsFileTime(): 23ns
GetSystemTimeAsFileTime(): <3ns

--
Regards,
Christian

From f3366a524643067b7adb0d535c38bb106bda42e2 Mon Sep 17 00:00:00 2001
From: Christian Franke <christian.fra...@t-online.de>
Date: Thu, 22 Apr 2021 13:47:30 +0200
Subject: [PATCH] crt: Increase precision of gettimeofday() if possible.

Use GetSystemTimePreciseAsFileTime() if available.

Signed-off-by: Christian Franke <christian.fra...@t-online.de>
---
 mingw-w64-crt/misc/gettimeofday.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/mingw-w64-crt/misc/gettimeofday.c 
b/mingw-w64-crt/misc/gettimeofday.c
index 50ffcfc7..8e016f9c 100644
--- a/mingw-w64-crt/misc/gettimeofday.c
+++ b/mingw-w64-crt/misc/gettimeofday.c
@@ -41,8 +41,23 @@ int getntptimeofday (struct timespec *tp, struct timezone *z)
     }
 
   if (tp != NULL) {
-    GetSystemTimeAsFileTime (&_now.ft);         /* 100-nanoseconds since 
1-1-1601 */
-    /* The actual accuracy on XP seems to be 125,000 nanoseconds = 125 
microseconds = 0.125 milliseconds */
+    typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME);
+    static volatile GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p = NULL;
+
+    /* Set function pointer during first call */
+    GetSystemTimeAsFileTime_t get_time = GetSystemTimeAsFileTime_p;
+    if (get_time == NULL) {
+      /* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or 
later) */
+      get_time = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
+        "GetSystemTimePreciseAsFileTime"); /* <1us precision on Windows 10 */
+      if (get_time == NULL)
+        get_time = GetSystemTimeAsFileTime; /* >15ms precision on Windows 10 */
+      /* First thread wins */
+      InterlockedCompareExchangePointer ((void * volatile *) 
&GetSystemTimeAsFileTime_p,
+        get_time, NULL);
+    }
+
+    get_time (&_now.ft);       /* 100 nano-seconds since 1-1-1601 */
     _now.ns100 -= FILETIME_1970;       /* 100 nano-seconds since 1-1-1970 */
     tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC;    /* seconds since 
1-1-1970 */
     tp->tv_nsec = (long) (_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* 
nanoseconds */
-- 
2.31.1

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to