summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2018-03-27 20:10:17 +0000
committerVladislav Vaintroub <wlad@mariadb.com>2018-04-01 14:38:45 +0000
commit19bb7fdcd6e68aca6e41a2e30ffb3c2ad1d14cb6 (patch)
treecc8f0d33ed82129834ca9c75af1841f3d31d7841
parent04bac13b30df18e90a72b9454ac36bc264792974 (diff)
downloadmariadb-git-19bb7fdcd6e68aca6e41a2e30ffb3c2ad1d14cb6.tar.gz
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()
-rw-r--r--include/my_pthread.h2
-rw-r--r--include/my_sys.h9
-rw-r--r--mysys/my_getsystime.c43
3 files changed, 44 insertions, 10 deletions
diff --git a/include/my_pthread.h b/include/my_pthread.h
index d51951f3904..4b8f9bf3f0f 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -307,7 +307,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#ifndef set_timespec_nsec
#define set_timespec_nsec(ABSTIME,NSEC) \
- set_timespec_time_nsec((ABSTIME), my_hrtime().val*1000 + (NSEC))
+ set_timespec_time_nsec((ABSTIME), my_hrtime_coarse().val*1000 + (NSEC))
#endif /* !set_timespec_nsec */
/* adapt for two different flavors of struct timespec */
diff --git a/include/my_sys.h b/include/my_sys.h
index 61ca6085ba7..8c81926b61c 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -940,6 +940,13 @@ extern int my_getncpus(void);
typedef struct {ulonglong val;} my_hrtime_t;
void my_time_init(void);
extern my_hrtime_t my_hrtime(void);
+
+#ifdef _WIN32
+extern my_hrtime_t my_hrtime_coarse();
+#else
+#define my_hrtime_coarse() my_hrtime()
+#endif
+
extern ulonglong my_interval_timer(void);
extern ulonglong my_getcputime(void);
@@ -948,7 +955,7 @@ extern ulonglong my_getcputime(void);
#define hrtime_from_time(X) ((ulonglong)((X)*HRTIME_RESOLUTION))
#define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION)
#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION))
-#define my_time(X) hrtime_to_time(my_hrtime())
+#define my_time(X) hrtime_to_time(my_hrtime_coarse())
#if STACK_DIRECTION < 0
#define available_stack_size(CUR,END) (long) ((char*)(CUR) - (char*)(END))
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 1cedeb21d6e..cd9525e5ff7 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -18,9 +18,12 @@
#include "mysys_priv.h"
#include "my_static.h"
-#ifdef __WIN__
+#ifdef _WIN32
#define OFFSET_TO_EPOC 116444736000000000LL
static ulonglong query_performance_frequency;
+typedef void (WINAPI* get_system_time_as_filetime_t)(LPFILETIME);
+static get_system_time_as_filetime_t
+ my_GetSystemTimePreciseAsFileTime= GetSystemTimeAsFileTime;
#endif
#ifdef HAVE_LINUX_UNISTD_H
#include <linux/unistd.h>
@@ -53,7 +56,7 @@ ulonglong my_interval_timer()
return tp.tv_sec*1000000000ULL+tp.tv_nsec;
#elif defined(HAVE_GETHRTIME)
return gethrtime();
-#elif defined(__WIN__)
+#elif defined(_WIN32)
LARGE_INTEGER t_cnt;
if (query_performance_frequency)
{
@@ -65,7 +68,7 @@ ulonglong my_interval_timer()
else
{
ulonglong newtime;
- GetSystemTimeAsFileTime((FILETIME*)&newtime);
+ my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
return newtime*100ULL;
}
#else
@@ -82,11 +85,10 @@ ulonglong my_interval_timer()
my_hrtime_t my_hrtime()
{
my_hrtime_t hrtime;
-#if defined(__WIN__)
+#if defined(_WIN32)
ulonglong newtime;
- GetSystemTimeAsFileTime((FILETIME*)&newtime);
- newtime -= OFFSET_TO_EPOC;
- hrtime.val= newtime/10;
+ my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
+ hrtime.val= (newtime - OFFSET_TO_EPOC)/10;
#elif defined(HAVE_CLOCK_GETTIME)
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
@@ -100,14 +102,39 @@ my_hrtime_t my_hrtime()
return hrtime;
}
+#ifdef _WIN32
+
+/*
+ Low accuracy, "coarse" timer.
+ Has lower latency than my_hrtime(). Used in situations, where microsecond
+ precision is not needed, e.g in Windows pthread_cond_timedwait, where POSIX
+ interface needs nanoseconds, yet the underlying Windows function only
+ accepts millisecons.
+*/
+my_hrtime_t my_hrtime_coarse()
+{
+ my_hrtime_t hrtime;
+ ulonglong t;
+ GetSystemTimeAsFileTime((FILETIME*)&t);
+ hrtime.val= (t - OFFSET_TO_EPOC)/10;
+ return hrtime;
+}
+
+#endif
void my_time_init()
{
-#ifdef __WIN__
+#ifdef _WIN32
compile_time_assert(sizeof(LARGE_INTEGER) ==
sizeof(query_performance_frequency));
if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
query_performance_frequency= 0;
+
+ get_system_time_as_filetime_t f= (get_system_time_as_filetime_t)
+ GetProcAddress(GetModuleHandle("kernel32"),
+ "GetSystemTimePreciseAsFileTime");
+ if (f)
+ my_GetSystemTimePreciseAsFileTime= f;
#endif
}