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