This source file includes following definitions.
- nanosleep
- nanosleep
- nanosleep
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #include <time.h>
25
26 #include "intprops.h"
27
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <sys/select.h>
31 #include <signal.h>
32
33 #include <errno.h>
34
35 #include <unistd.h>
36
37
38 enum { BILLION = 1000 * 1000 * 1000 };
39
40 #if HAVE_BUG_BIG_NANOSLEEP
41
42 int
43 nanosleep (const struct timespec *requested_delay,
44 struct timespec *remaining_delay)
45 # undef nanosleep
46 {
47
48
49
50
51
52
53 if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)
54 {
55 errno = EINVAL;
56 return -1;
57 }
58
59 {
60
61 static_assert (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60);
62 const time_t limit = 24 * 24 * 60 * 60;
63 time_t seconds = requested_delay->tv_sec;
64 struct timespec intermediate;
65 intermediate.tv_nsec = requested_delay->tv_nsec;
66
67 while (limit < seconds)
68 {
69 int result;
70 intermediate.tv_sec = limit;
71 result = nanosleep (&intermediate, remaining_delay);
72 seconds -= limit;
73 if (result)
74 {
75 if (remaining_delay)
76 remaining_delay->tv_sec += seconds;
77 return result;
78 }
79 intermediate.tv_nsec = 0;
80 }
81 intermediate.tv_sec = seconds;
82 return nanosleep (&intermediate, remaining_delay);
83 }
84 }
85
86 #elif defined _WIN32 && ! defined __CYGWIN__
87
88
89 # define WIN32_LEAN_AND_MEAN
90 # include <windows.h>
91
92
93
94
95
96
97
98 int
99 nanosleep (const struct timespec *requested_delay,
100 struct timespec *remaining_delay)
101 {
102 static bool initialized;
103
104
105 static double ticks_per_nanosecond;
106
107 if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)
108 {
109 errno = EINVAL;
110 return -1;
111 }
112
113
114
115 if (requested_delay->tv_sec == 0)
116 {
117 if (!initialized)
118 {
119
120 LARGE_INTEGER ticks_per_second;
121
122 if (QueryPerformanceFrequency (&ticks_per_second))
123 ticks_per_nanosecond =
124 (double) ticks_per_second.QuadPart / 1000000000.0;
125
126 initialized = true;
127 }
128 if (ticks_per_nanosecond)
129 {
130
131
132
133
134
135
136 int sleep_millis = (int) requested_delay->tv_nsec / 1000000 - 10;
137
138 LONGLONG wait_ticks = requested_delay->tv_nsec * ticks_per_nanosecond;
139
140 LARGE_INTEGER counter_before;
141 if (QueryPerformanceCounter (&counter_before))
142 {
143
144
145
146
147 LONGLONG wait_until = counter_before.QuadPart + wait_ticks;
148
149 if (sleep_millis > 0)
150 Sleep (sleep_millis);
151
152 for (;;)
153 {
154 LARGE_INTEGER counter_after;
155 if (!QueryPerformanceCounter (&counter_after))
156
157
158 break;
159 if (counter_after.QuadPart >= wait_until)
160
161 break;
162 }
163 goto done;
164 }
165 }
166 }
167
168 Sleep (requested_delay->tv_sec * 1000 + requested_delay->tv_nsec / 1000000);
169
170 done:
171
172 if (remaining_delay != NULL)
173 {
174 remaining_delay->tv_sec = 0;
175 remaining_delay->tv_nsec = 0;
176 }
177 return 0;
178 }
179
180 #else
181
182
183
184
185
186
187
188 int
189 nanosleep (const struct timespec *requested_delay,
190 struct timespec *remaining_delay)
191 {
192 return pselect (0, NULL, NULL, NULL, requested_delay, NULL);
193 }
194 #endif