Skip to content

Commit 19bb7fd

Browse files
committed
MDEV-15694 Windows : use GetSystemTimePreciseAsFileTime if available for high resolution time
Use high accuracy timer on Windows 8.1+ for system versioning,it needs accurate high resoution start query time. Continue to use the inaccurate (but much faster timer function) GetSystemTimeAsFileTime() where accuracy does not matter, e.g in set_timespec_time_nsec(),or my_time()
1 parent 04bac13 commit 19bb7fd

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

include/my_pthread.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
307307

308308
#ifndef set_timespec_nsec
309309
#define set_timespec_nsec(ABSTIME,NSEC) \
310-
set_timespec_time_nsec((ABSTIME), my_hrtime().val*1000 + (NSEC))
310+
set_timespec_time_nsec((ABSTIME), my_hrtime_coarse().val*1000 + (NSEC))
311311
#endif /* !set_timespec_nsec */
312312

313313
/* adapt for two different flavors of struct timespec */

include/my_sys.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,13 @@ extern int my_getncpus(void);
940940
typedef struct {ulonglong val;} my_hrtime_t;
941941
void my_time_init(void);
942942
extern my_hrtime_t my_hrtime(void);
943+
944+
#ifdef _WIN32
945+
extern my_hrtime_t my_hrtime_coarse();
946+
#else
947+
#define my_hrtime_coarse() my_hrtime()
948+
#endif
949+
943950
extern ulonglong my_interval_timer(void);
944951
extern ulonglong my_getcputime(void);
945952

@@ -948,7 +955,7 @@ extern ulonglong my_getcputime(void);
948955
#define hrtime_from_time(X) ((ulonglong)((X)*HRTIME_RESOLUTION))
949956
#define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION)
950957
#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION))
951-
#define my_time(X) hrtime_to_time(my_hrtime())
958+
#define my_time(X) hrtime_to_time(my_hrtime_coarse())
952959

953960
#if STACK_DIRECTION < 0
954961
#define available_stack_size(CUR,END) (long) ((char*)(CUR) - (char*)(END))

mysys/my_getsystime.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818
#include "mysys_priv.h"
1919
#include "my_static.h"
2020

21-
#ifdef __WIN__
21+
#ifdef _WIN32
2222
#define OFFSET_TO_EPOC 116444736000000000LL
2323
static ulonglong query_performance_frequency;
24+
typedef void (WINAPI* get_system_time_as_filetime_t)(LPFILETIME);
25+
static get_system_time_as_filetime_t
26+
my_GetSystemTimePreciseAsFileTime= GetSystemTimeAsFileTime;
2427
#endif
2528
#ifdef HAVE_LINUX_UNISTD_H
2629
#include <linux/unistd.h>
@@ -53,7 +56,7 @@ ulonglong my_interval_timer()
5356
return tp.tv_sec*1000000000ULL+tp.tv_nsec;
5457
#elif defined(HAVE_GETHRTIME)
5558
return gethrtime();
56-
#elif defined(__WIN__)
59+
#elif defined(_WIN32)
5760
LARGE_INTEGER t_cnt;
5861
if (query_performance_frequency)
5962
{
@@ -65,7 +68,7 @@ ulonglong my_interval_timer()
6568
else
6669
{
6770
ulonglong newtime;
68-
GetSystemTimeAsFileTime((FILETIME*)&newtime);
71+
my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
6972
return newtime*100ULL;
7073
}
7174
#else
@@ -82,11 +85,10 @@ ulonglong my_interval_timer()
8285
my_hrtime_t my_hrtime()
8386
{
8487
my_hrtime_t hrtime;
85-
#if defined(__WIN__)
88+
#if defined(_WIN32)
8689
ulonglong newtime;
87-
GetSystemTimeAsFileTime((FILETIME*)&newtime);
88-
newtime -= OFFSET_TO_EPOC;
89-
hrtime.val= newtime/10;
90+
my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
91+
hrtime.val= (newtime - OFFSET_TO_EPOC)/10;
9092
#elif defined(HAVE_CLOCK_GETTIME)
9193
struct timespec tp;
9294
clock_gettime(CLOCK_REALTIME, &tp);
@@ -100,14 +102,39 @@ my_hrtime_t my_hrtime()
100102
return hrtime;
101103
}
102104

105+
#ifdef _WIN32
106+
107+
/*
108+
Low accuracy, "coarse" timer.
109+
Has lower latency than my_hrtime(). Used in situations, where microsecond
110+
precision is not needed, e.g in Windows pthread_cond_timedwait, where POSIX
111+
interface needs nanoseconds, yet the underlying Windows function only
112+
accepts millisecons.
113+
*/
114+
my_hrtime_t my_hrtime_coarse()
115+
{
116+
my_hrtime_t hrtime;
117+
ulonglong t;
118+
GetSystemTimeAsFileTime((FILETIME*)&t);
119+
hrtime.val= (t - OFFSET_TO_EPOC)/10;
120+
return hrtime;
121+
}
122+
123+
#endif
103124

104125
void my_time_init()
105126
{
106-
#ifdef __WIN__
127+
#ifdef _WIN32
107128
compile_time_assert(sizeof(LARGE_INTEGER) ==
108129
sizeof(query_performance_frequency));
109130
if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
110131
query_performance_frequency= 0;
132+
133+
get_system_time_as_filetime_t f= (get_system_time_as_filetime_t)
134+
GetProcAddress(GetModuleHandle("kernel32"),
135+
"GetSystemTimePreciseAsFileTime");
136+
if (f)
137+
my_GetSystemTimePreciseAsFileTime= f;
111138
#endif
112139
}
113140

0 commit comments

Comments
 (0)