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