This patch makes the precision of CLOCK_REALTIME consistent with new 'gettimeofday()' and provides the old behavior as CLOCK_REALTIME_COARSE.

CLOCK_REALTIME_COARSE is not part of POSIX, but available in Linux since 2009 and in Cygwin since 2018.

--
Best regards,
Christian Franke

From 778f7b3d94eaa748914187e4408ea9deac6d1b90 Mon Sep 17 00:00:00 2001
From: Christian Franke <[email protected]>
Date: Wed, 5 May 2021 18:56:20 +0200
Subject: [PATCH] winpthreads: Increase precision of CLOCK_REALTIME, add
 CLOCK_REALTIME_COARSE.

Use GetSystemTimePreciseAsFileTime() for CLOCK_REALTIME if available.
Always use GetSystemTimeAsFileTime() for CLOCK_REALTIME_COARSE.

Signed-off-by: Christian Franke <[email protected]>
---
 .../winpthreads/include/pthread_time.h        |  4 ++
 mingw-w64-libraries/winpthreads/src/clock.c   | 44 ++++++++++++++++++-
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/mingw-w64-libraries/winpthreads/include/pthread_time.h 
b/mingw-w64-libraries/winpthreads/include/pthread_time.h
index 7a7538c3..7818b114 100644
--- a/mingw-w64-libraries/winpthreads/include/pthread_time.h
+++ b/mingw-w64-libraries/winpthreads/include/pthread_time.h
@@ -70,6 +70,10 @@ typedef int clockid_t;
 #define CLOCK_THREAD_CPUTIME_ID     3
 #endif
 
+#ifndef CLOCK_REALTIME_COARSE
+#define CLOCK_REALTIME_COARSE       4
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/mingw-w64-libraries/winpthreads/src/clock.c 
b/mingw-w64-libraries/winpthreads/src/clock.c
index 5ad710b2..ba983c90 100644
--- a/mingw-w64-libraries/winpthreads/src/clock.c
+++ b/mingw-w64-libraries/winpthreads/src/clock.c
@@ -31,6 +31,30 @@ static WINPTHREADS_INLINE int lc_set_errno(int result)
     return 0;
 }
 
+typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME);
+static GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p /* = 0 */;
+
+static GetSystemTimeAsFileTime_t try_load_GetSystemPreciseTimeAsFileTime()
+{
+    /* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) 
*/
+    GetSystemTimeAsFileTime_t get_time = 
(GetSystemTimeAsFileTime_t)(intptr_t)GetProcAddress(
+        GetModuleHandle ("kernel32.dll"),
+        "GetSystemTimePreciseAsFileTime"); /* <1us precision on Windows 10 */
+    if (get_time == NULL)
+        get_time = GetSystemTimeAsFileTime; /* >15ms precision on Windows 10 */
+    __atomic_store_n(&GetSystemTimeAsFileTime_p, get_time, __ATOMIC_RELAXED);
+    return get_time;
+}
+
+static WINPTHREADS_INLINE GetSystemTimeAsFileTime_t 
load_GetSystemTimeBestAsFileTime()
+{
+    GetSystemTimeAsFileTime_t get_time =
+        __atomic_load_n(&GetSystemTimeAsFileTime_p, __ATOMIC_RELAXED);
+    if (get_time == NULL)
+        get_time = try_load_GetSystemPreciseTimeAsFileTime();
+    return get_time;
+}
+
 /**
  * Get the resolution of the specified clock clock_id and
  * stores it in the struct timespec pointed to by res.
@@ -52,7 +76,13 @@ static WINPTHREADS_INLINE int lc_set_errno(int result)
  */
 int clock_getres(clockid_t clock_id, struct timespec *res)
 {
-    switch(clock_id) {
+    clockid_t id = clock_id;
+
+    if (id == CLOCK_REALTIME && load_GetSystemTimeBestAsFileTime() == 
GetSystemTimeAsFileTime)
+        id = CLOCK_REALTIME_COARSE; /* GetSystemTimePreciseAsFileTime() not 
available */
+
+    switch(id) {
+    case CLOCK_REALTIME:
     case CLOCK_MONOTONIC:
         {
             LARGE_INTEGER pf;
@@ -68,7 +98,7 @@ int clock_getres(clockid_t clock_id, struct timespec *res)
             return 0;
         }
 
-    case CLOCK_REALTIME:
+    case CLOCK_REALTIME_COARSE:
     case CLOCK_PROCESS_CPUTIME_ID:
     case CLOCK_THREAD_CPUTIME_ID:
         {
@@ -117,6 +147,16 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
 
     switch(clock_id) {
     case CLOCK_REALTIME:
+        {
+            load_GetSystemTimeBestAsFileTime()(&ct.ft);
+            t = ct.u64 - DELTA_EPOCH_IN_100NS;
+            tp->tv_sec = t / POW10_7;
+            tp->tv_nsec = ((int) (t % POW10_7)) * 100;
+
+            return 0;
+        }
+
+    case CLOCK_REALTIME_COARSE:
         {
             GetSystemTimeAsFileTime(&ct.ft);
             t = ct.u64 - DELTA_EPOCH_IN_100NS;
-- 
2.31.1

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to