blob: 0e1c61b911894375332e3abc71d5220a2e61357e [file]
/**
* 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);
}