27#if _WIN32 && !defined(__MINGW32__)
40#define FILETIME_EPOCH ((LONGLONG)(369 * 365 + 89) * 24 * 60 * 60)
42#ifdef _USE_32BIT_TIME_T
44#define TIME_T_MIN LONG_MIN
46#define TIME_T_MAX LONG_MAX
49#define TIME_T_MIN _I64_MIN
51#define TIME_T_MAX _I64_MAX
55clock_getres(clockid_t clock_id,
struct timespec *res)
57 if (clock_id == CLOCK_MONOTONIC) {
59 LARGE_INTEGER liFrequency;
60 QueryPerformanceFrequency(&liFrequency);
61 LONGLONG pf = liFrequency.QuadPart;
64 *res = (
struct timespec){ 0,
65 (long)((1000000000l + pf / 2) / pf) };
72 case CLOCK_PROCESS_CPUTIME_ID:
73 case CLOCK_THREAD_CPUTIME_ID:
break;
74 default: errno = EINVAL;
return -1;
77 DWORD dwTimeAdjustment;
78 DWORD dwTimeIncrement;
79 BOOL bTimeAdjustmentDisabled;
81 if (!GetSystemTimeAdjustment(&dwTimeAdjustment, &dwTimeIncrement,
82 &bTimeAdjustmentDisabled))
87 *res = (
struct timespec){ 0, dwTimeIncrement * 100 };
93clock_gettime(clockid_t clock_id,
struct timespec *tp)
95 if (clock_id == CLOCK_MONOTONIC) {
97 LARGE_INTEGER liFrequency;
98 QueryPerformanceFrequency(&liFrequency);
99 LONGLONG pf = liFrequency.QuadPart;
100 LARGE_INTEGER liPerformanceCount;
101 QueryPerformanceCounter(&liPerformanceCount);
102 LONGLONG pc = liPerformanceCount.QuadPart;
103 if (pc / pf > TIME_T_MAX) {
109 tp->tv_sec = pc / pf;
110 tp->tv_nsec = (long)(((pc % pf) * (1000000000l + pf / 2))
119 case CLOCK_REALTIME: {
120 FILETIME SystemTimeAsFileTime;
121#if defined(NTDDI_WIN8) && NTDDI_VERSION >= NTDDI_WIN8
122 GetSystemTimePreciseAsFileTime(&SystemTimeAsFileTime);
124 GetSystemTimeAsFileTime(&SystemTimeAsFileTime);
126 ULARGE_INTEGER st = {
127 .LowPart = SystemTimeAsFileTime.dwLowDateTime,
128 .HighPart = SystemTimeAsFileTime.dwHighDateTime
130 ft = st.QuadPart - (ULONGLONG)FILETIME_EPOCH * 10000000ul;
133 case CLOCK_PROCESS_CPUTIME_ID: {
134 FILETIME CreationTime, ExitTime, KernelTime, UserTime;
136 if (!GetProcessTimes(GetCurrentProcess(), &CreationTime,
137 &ExitTime, &KernelTime, &UserTime))
142 ULARGE_INTEGER kt = { .LowPart = KernelTime.dwLowDateTime,
143 .HighPart = KernelTime.dwHighDateTime };
144 ULARGE_INTEGER ut = { .LowPart = UserTime.dwLowDateTime,
145 .HighPart = UserTime.dwHighDateTime };
146 if (kt.QuadPart + ut.QuadPart > _I64_MAX) {
150 ft = kt.QuadPart + ut.QuadPart;
153 case CLOCK_THREAD_CPUTIME_ID: {
154 FILETIME CreationTime, ExitTime, KernelTime, UserTime;
156 if (!GetProcessTimes(GetCurrentThread(), &CreationTime,
157 &ExitTime, &KernelTime, &UserTime))
162 ULARGE_INTEGER kt = { .LowPart = KernelTime.dwLowDateTime,
163 .HighPart = KernelTime.dwHighDateTime };
164 ULARGE_INTEGER ut = { .LowPart = UserTime.dwLowDateTime,
165 .HighPart = UserTime.dwHighDateTime };
166 if (kt.QuadPart + ut.QuadPart > _I64_MAX) {
170 ft = kt.QuadPart + ut.QuadPart;
173 default: errno = EINVAL;
return -1;
176 LONGLONG sec = ft / 10000000l;
177 if (sec < TIME_T_MIN || sec > TIME_T_MAX) {
184 tp->tv_nsec = (ft % 10000000l) * 100;
191clock_nanosleep(clockid_t clock_id,
int flags,
const struct timespec *rqtp,
192 struct timespec *rmtp)
196 case CLOCK_MONOTONIC:
break;
197 case CLOCK_PROCESS_CPUTIME_ID:
return ENOTSUP;
198 case CLOCK_THREAD_CPUTIME_ID:
199 default:
return EINVAL;
202 if (rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000l)
207 struct timespec now = { 0, 0 };
208 if (clock_gettime(clock_id, &now) == -1) {
215 struct timespec tp = *rqtp;
216 if (!(flags & TIMER_ABSTIME)) {
217 if (tp.tv_sec < 0 || (!tp.tv_sec && !tp.tv_nsec))
219 if (now.tv_sec > TIME_T_MAX - tp.tv_sec)
221 tp.tv_sec += now.tv_sec;
222 tp.tv_nsec += now.tv_nsec;
223 if (tp.tv_nsec >= 1000000000l) {
224 if (tp.tv_sec == TIME_T_MAX)
227 tp.tv_nsec -= 1000000000l;
232 while (now.tv_sec < tp.tv_sec || (now.tv_sec == tp.tv_sec
233 && now.tv_nsec < tp.tv_nsec)) {
237 LONGLONG llMilliseconds =
238 (LONGLONG)(tp.tv_sec - now.tv_sec) * 1000
239 + (tp.tv_nsec - now.tv_nsec + 999999l)
241 DWORD dwMilliseconds = llMilliseconds <= MAX_SLEEP_MS
242 ? (DWORD)llMilliseconds
244 DWORD dwResult = SleepEx(dwMilliseconds, TRUE);
245 if (clock_gettime(clock_id, &now) == -1) {
253 if (!(flags & TIMER_ABSTIME) && rmtp) {
254 rmtp->tv_sec = tp.tv_sec - now.tv_sec;
255 rmtp->tv_nsec = tp.tv_nsec - now.tv_nsec;
256 if (rmtp->tv_nsec < 0) {
258 rmtp->tv_nsec += 1000000000l;
269clock_settime(clockid_t clock_id,
const struct timespec *tp)
271 if (clock_id != CLOCK_REALTIME) {
276 if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000l) {
281 if (tp->tv_sec + FILETIME_EPOCH < 0) {
285 ULARGE_INTEGER li = { .QuadPart = tp->tv_sec + FILETIME_EPOCH };
286 if (li.QuadPart > _UI64_MAX / 10000000ul) {
290 li.QuadPart *= 10000000ul;
291 if (li.QuadPart > _UI64_MAX - tp->tv_nsec / 100) {
295 li.QuadPart += tp->tv_nsec / 100;
297 FILETIME ft = { li.LowPart, li.HighPart };
299 if (!FileTimeToSystemTime(&ft, &st)) {
303 if (!SetSystemTime(&st)) {
This header file is part of the C11 and POSIX compatibility library; it includes <time....
This is the internal header file of the C11 and POSIX compatibility library.