| /** |
| * This file has no copyright assigned and is placed in the Public Domain. |
| * This file is part of the mingw-w64 runtime package. |
| * No warranty is given; refer to the file DISCLAIMER.PD within this package. |
| */ |
| #include <time.h> |
| #include <sys/time.h> |
| #include <windows.h> |
| |
| #define FILETIME_1970 116444736000000000ull /* seconds between 1/1/1601 and 1/1/1970 */ |
| #define HECTONANOSEC_PER_SEC 10000000ull |
| |
| int __cdecl mingw_gettimeofday(struct timeval* __restrict__ _Tv, struct timezone* __restrict__ _Tz) |
| { |
| union { |
| unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ |
| FILETIME ft; |
| } _now; |
| TIME_ZONE_INFORMATION TimeZoneInformation; |
| DWORD tzi; |
| |
| if (_Tz != NULL) |
| { |
| if ((tzi = GetTimeZoneInformation(&TimeZoneInformation)) != TIME_ZONE_ID_INVALID) { |
| _Tz->tz_minuteswest = TimeZoneInformation.Bias; |
| if (tzi == TIME_ZONE_ID_DAYLIGHT) |
| _Tz->tz_dsttime = 1; |
| else |
| _Tz->tz_dsttime = 0; |
| } |
| else |
| { |
| _Tz->tz_minuteswest = 0; |
| _Tz->tz_dsttime = 0; |
| } |
| } |
| |
| if (_Tv != NULL) { |
| typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME); |
| static GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p /* = 0 */; |
| |
| /* Set function pointer during first call */ |
| GetSystemTimeAsFileTime_t get_time = |
| __atomic_load_n (&GetSystemTimeAsFileTime_p, __ATOMIC_RELAXED); |
| if (get_time == NULL) { |
| /* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) */ |
| 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); |
| } |
| |
| get_time (&_now.ft); /* 100 nano-seconds since 1-1-1601 */ |
| _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */ |
| _Tv->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */ |
| _Tv->tv_usec = (long) (_now.ns100 % HECTONANOSEC_PER_SEC) / 10; /* 100ns -> 1us */ |
| } |
| return 0; |
| } |
| |
| int __cdecl gettimeofday(struct timeval* __restrict__ _Tv, void* __restrict__ _Tz) |
| { |
| return mingw_gettimeofday(_Tv, (struct timezone*)_Tz); |
| } |