master
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6#include <time.h>
7#include <sys/time.h>
8#include <sys/timeb.h>
9#include <errno.h>
10#include <windows.h>
11
12#define FILETIME_1970 116444736000000000ull /* seconds between 1/1/1601 and 1/1/1970 */
13#define HECTONANOSEC_PER_SEC 10000000ull
14
15int getntptimeofday (struct timespec *, struct timezone *);
16
17int getntptimeofday (struct timespec *tp, struct timezone *z)
18{
19 int res = 0;
20 union {
21 unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
22 FILETIME ft;
23 } _now;
24 TIME_ZONE_INFORMATION TimeZoneInformation;
25 DWORD tzi;
26
27 if (z != NULL)
28 {
29 if ((tzi = GetTimeZoneInformation(&TimeZoneInformation)) != TIME_ZONE_ID_INVALID) {
30 z->tz_minuteswest = TimeZoneInformation.Bias;
31 if (tzi == TIME_ZONE_ID_DAYLIGHT)
32 z->tz_dsttime = 1;
33 else
34 z->tz_dsttime = 0;
35 }
36 else
37 {
38 z->tz_minuteswest = 0;
39 z->tz_dsttime = 0;
40 }
41 }
42
43 if (tp != NULL) {
44 typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME);
45 static GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p /* = 0 */;
46
47 /* Set function pointer during first call */
48 GetSystemTimeAsFileTime_t get_time =
49 __atomic_load_n (&GetSystemTimeAsFileTime_p, __ATOMIC_RELAXED);
50 if (get_time == NULL) {
51 /* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) */
52 get_time = (GetSystemTimeAsFileTime_t)(intptr_t) GetProcAddress (
53 GetModuleHandle ("kernel32.dll"),
54 "GetSystemTimePreciseAsFileTime"); /* <1us precision on Windows 10 */
55 if (get_time == NULL)
56 get_time = GetSystemTimeAsFileTime; /* >15ms precision on Windows 10 */
57 __atomic_store_n (&GetSystemTimeAsFileTime_p, get_time, __ATOMIC_RELAXED);
58 }
59
60 get_time (&_now.ft); /* 100 nano-seconds since 1-1-1601 */
61 _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */
62 tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */
63 tp->tv_nsec = (long) (_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */
64 }
65 return res;
66}
67
68int __cdecl gettimeofday (struct timeval *p, void *z)
69{
70 struct timespec tp;
71
72 if (getntptimeofday (&tp, (struct timezone *) z))
73 return -1;
74 p->tv_sec=tp.tv_sec;
75 p->tv_usec=(tp.tv_nsec/1000);
76 return 0;
77}
78
79int __cdecl mingw_gettimeofday (struct timeval *p, struct timezone *z)
80{
81 struct timespec tp;
82
83 if (getntptimeofday (&tp, z))
84 return -1;
85 p->tv_sec=tp.tv_sec;
86 p->tv_usec=(tp.tv_nsec/1000);
87 return 0;
88}