Commit 19bb7fdc authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

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()
parent 04bac13b
...@@ -307,7 +307,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex); ...@@ -307,7 +307,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#ifndef set_timespec_nsec #ifndef set_timespec_nsec
#define set_timespec_nsec(ABSTIME,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 */ #endif /* !set_timespec_nsec */
/* adapt for two different flavors of struct timespec */ /* adapt for two different flavors of struct timespec */
......
...@@ -940,6 +940,13 @@ extern int my_getncpus(void); ...@@ -940,6 +940,13 @@ extern int my_getncpus(void);
typedef struct {ulonglong val;} my_hrtime_t; typedef struct {ulonglong val;} my_hrtime_t;
void my_time_init(void); void my_time_init(void);
extern my_hrtime_t my_hrtime(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_interval_timer(void);
extern ulonglong my_getcputime(void); extern ulonglong my_getcputime(void);
...@@ -948,7 +955,7 @@ 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_from_time(X) ((ulonglong)((X)*HRTIME_RESOLUTION))
#define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION) #define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION)
#define hrtime_sec_part(X) ((ulong)((X).val % 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 #if STACK_DIRECTION < 0
#define available_stack_size(CUR,END) (long) ((char*)(CUR) - (char*)(END)) #define available_stack_size(CUR,END) (long) ((char*)(CUR) - (char*)(END))
......
...@@ -18,9 +18,12 @@ ...@@ -18,9 +18,12 @@
#include "mysys_priv.h" #include "mysys_priv.h"
#include "my_static.h" #include "my_static.h"
#ifdef __WIN__ #ifdef _WIN32
#define OFFSET_TO_EPOC 116444736000000000LL #define OFFSET_TO_EPOC 116444736000000000LL
static ulonglong query_performance_frequency; 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 #endif
#ifdef HAVE_LINUX_UNISTD_H #ifdef HAVE_LINUX_UNISTD_H
#include <linux/unistd.h> #include <linux/unistd.h>
...@@ -53,7 +56,7 @@ ulonglong my_interval_timer() ...@@ -53,7 +56,7 @@ ulonglong my_interval_timer()
return tp.tv_sec*1000000000ULL+tp.tv_nsec; return tp.tv_sec*1000000000ULL+tp.tv_nsec;
#elif defined(HAVE_GETHRTIME) #elif defined(HAVE_GETHRTIME)
return gethrtime(); return gethrtime();
#elif defined(__WIN__) #elif defined(_WIN32)
LARGE_INTEGER t_cnt; LARGE_INTEGER t_cnt;
if (query_performance_frequency) if (query_performance_frequency)
{ {
...@@ -65,7 +68,7 @@ ulonglong my_interval_timer() ...@@ -65,7 +68,7 @@ ulonglong my_interval_timer()
else else
{ {
ulonglong newtime; ulonglong newtime;
GetSystemTimeAsFileTime((FILETIME*)&newtime); my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
return newtime*100ULL; return newtime*100ULL;
} }
#else #else
...@@ -82,11 +85,10 @@ ulonglong my_interval_timer() ...@@ -82,11 +85,10 @@ ulonglong my_interval_timer()
my_hrtime_t my_hrtime() my_hrtime_t my_hrtime()
{ {
my_hrtime_t hrtime; my_hrtime_t hrtime;
#if defined(__WIN__) #if defined(_WIN32)
ulonglong newtime; ulonglong newtime;
GetSystemTimeAsFileTime((FILETIME*)&newtime); my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
newtime -= OFFSET_TO_EPOC; hrtime.val= (newtime - OFFSET_TO_EPOC)/10;
hrtime.val= newtime/10;
#elif defined(HAVE_CLOCK_GETTIME) #elif defined(HAVE_CLOCK_GETTIME)
struct timespec tp; struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp); clock_gettime(CLOCK_REALTIME, &tp);
...@@ -100,14 +102,39 @@ my_hrtime_t my_hrtime() ...@@ -100,14 +102,39 @@ my_hrtime_t my_hrtime()
return 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() void my_time_init()
{ {
#ifdef __WIN__ #ifdef _WIN32
compile_time_assert(sizeof(LARGE_INTEGER) == compile_time_assert(sizeof(LARGE_INTEGER) ==
sizeof(query_performance_frequency)); sizeof(query_performance_frequency));
if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0) if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
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 #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment