mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
109 lines
2.8 KiB
C
Vendored
109 lines
2.8 KiB
C
Vendored
/**
|
|
* This file has no copyright assigned and is placed in the Public Domain.
|
|
* This file is part of the w64 mingw-runtime package.
|
|
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
|
|
#define WINPTHREAD_NANOSLEEP_DECL WINPTHREAD_API
|
|
|
|
/* public header files */
|
|
#include "pthread.h"
|
|
#include "pthread_time.h"
|
|
/* internal header files */
|
|
#include "thread.h"
|
|
|
|
#define POW10_3 1000
|
|
#define POW10_4 10000
|
|
#define POW10_6 1000000
|
|
#define POW10_9 1000000000
|
|
#define MAX_SLEEP_IN_MS 4294967294UL
|
|
|
|
/**
|
|
* Sleep for the specified time.
|
|
* @param request The desired amount of time to sleep.
|
|
* @param remain The remain amount of time to sleep.
|
|
* @return If the function succeeds, the return value is 0.
|
|
* If the function fails, the return value is -1,
|
|
* with errno set to indicate the error.
|
|
*/
|
|
static int __nanosleep(const struct _timespec64 *request, struct _timespec64 *remain)
|
|
{
|
|
unsigned long ms, rc = 0;
|
|
unsigned __int64 u64, want, real;
|
|
|
|
union {
|
|
unsigned __int64 ns100;
|
|
FILETIME ft;
|
|
} _start, _end;
|
|
|
|
if (request->tv_sec < 0 || request->tv_nsec < 0 || request->tv_nsec >= POW10_9) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
if (remain != NULL) GetSystemTimeAsFileTime(&_start.ft);
|
|
|
|
want = u64 = request->tv_sec * POW10_3 + request->tv_nsec / POW10_6;
|
|
while (u64 > 0 && rc == 0) {
|
|
if (u64 >= MAX_SLEEP_IN_MS) ms = MAX_SLEEP_IN_MS;
|
|
else ms = (unsigned long) u64;
|
|
|
|
u64 -= ms;
|
|
rc = _pthread_delay_np_ms(ms);
|
|
}
|
|
|
|
if (rc != 0) { /* WAIT_IO_COMPLETION (192) */
|
|
if (remain != NULL) {
|
|
GetSystemTimeAsFileTime(&_end.ft);
|
|
real = (_end.ns100 - _start.ns100) / POW10_4;
|
|
|
|
if (real >= want) u64 = 0;
|
|
else u64 = want - real;
|
|
|
|
remain->tv_sec = u64 / POW10_3;
|
|
remain->tv_nsec = (long) (u64 % POW10_3) * POW10_6;
|
|
}
|
|
|
|
errno = EINTR;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int nanosleep64(const struct _timespec64 *request, struct _timespec64 *remain)
|
|
{
|
|
return __nanosleep (request, remain);
|
|
}
|
|
|
|
int nanosleep32(const struct _timespec32 *request, struct _timespec32 *remain)
|
|
{
|
|
struct _timespec64 request64 = {
|
|
.tv_sec = request->tv_sec,
|
|
.tv_nsec = request->tv_nsec
|
|
};
|
|
struct _timespec64 remain64 = {0};
|
|
|
|
if (__nanosleep (&request64, &remain64) == -1)
|
|
return -1;
|
|
|
|
assert (remain64.tv_sec <= INT_MAX);
|
|
|
|
if (remain != NULL) {
|
|
remain->tv_sec = (__time32_t)remain64.tv_sec;
|
|
remain->tv_nsec = remain64.tv_nsec;
|
|
}
|
|
|
|
return 0;
|
|
}
|