1 /** 2 * This file has no copyright assigned and is placed in the Public Domain. 3 * This file is part of the w64 mingw-runtime package. 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5 */ 6 7 #include <errno.h> 8 #include <time.h> 9 #include <windows.h> 10 #include "pthread.h" 11 #include "pthread_time.h" 12 #include "winpthread_internal.h" 13 14 #define POW10_3 1000 15 #define POW10_4 10000 16 #define POW10_6 1000000 17 #define POW10_9 1000000000 18 #define MAX_SLEEP_IN_MS 4294967294UL 19 20 /** 21 * Sleep for the specified time. 22 * @param request The desired amount of time to sleep. 23 * @param remain The remain amount of time to sleep. 24 * @return If the function succeeds, the return value is 0. 25 * If the function fails, the return value is -1, 26 * with errno set to indicate the error. 27 */ nanosleep(const struct timespec * request,struct timespec * remain)28int nanosleep(const struct timespec *request, struct timespec *remain) 29 { 30 unsigned long ms, rc = 0; 31 unsigned __int64 u64, want, real; 32 33 union { 34 unsigned __int64 ns100; 35 FILETIME ft; 36 } _start, _end; 37 38 if (request->tv_sec < 0 || request->tv_nsec < 0 || request->tv_nsec >= POW10_9) { 39 errno = EINVAL; 40 return -1; 41 } 42 43 if (remain != NULL) GetSystemTimeAsFileTime(&_start.ft); 44 45 want = u64 = request->tv_sec * POW10_3 + request->tv_nsec / POW10_6; 46 while (u64 > 0 && rc == 0) { 47 if (u64 >= MAX_SLEEP_IN_MS) ms = MAX_SLEEP_IN_MS; 48 else ms = (unsigned long) u64; 49 50 u64 -= ms; 51 rc = pthread_delay_np_ms(ms); 52 } 53 54 if (rc != 0) { /* WAIT_IO_COMPLETION (192) */ 55 if (remain != NULL) { 56 GetSystemTimeAsFileTime(&_end.ft); 57 real = (_end.ns100 - _start.ns100) / POW10_4; 58 59 if (real >= want) u64 = 0; 60 else u64 = want - real; 61 62 remain->tv_sec = u64 / POW10_3; 63 remain->tv_nsec = (long) (u64 % POW10_3) * POW10_6; 64 } 65 66 errno = EINTR; 67 return -1; 68 } 69 70 return 0; 71 } 72