Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/nanosleep.c @ 17334:bb52d9cece01
unsetenv etc.: port to Solaris 11 + GNU Emacs
* lib/canonicalize-lgpl.c, lib/getaddrinfo.c, lib/getdelim.c:
* lib/glob.c, lib/random_r.c, lib/setenv.c, lib/tsearch.c:
* lib/unsetenv.c (_GL_ARG_NONNULL): Define before including <config.h>.
GNU Emacs's <config.h> includes <stdlib.h> (which is not a great
idea but is too painful to fix right now), and without this gnulib
change <stdlib.h> was defining _GL_ARG_NONNULL incorrectly when
compiling unsetenv.c on Solaris 11. Fix the problem for
unsetenv.c, and fix other similar occurrences.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Mon, 11 Feb 2013 14:58:56 -0800 |
parents | e542fd46ad6f |
children | 344018b6e5d7 |
rev | line source |
---|---|
2052 | 1 /* Provide a replacement for the POSIX nanosleep function. |
6795
9dc5bb3f3359
* lib/nanosleep.c [HAVE_SYS_SELECT_H]: Include <sys/select.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
2 |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16242
diff
changeset
|
3 Copyright (C) 1999-2000, 2002, 2004-2013 Free Software Foundation, Inc. |
2052 | 4 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8146
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
2052 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8146
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8146
diff
changeset
|
8 (at your option) any later version. |
2052 | 9 |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8146
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
2052 | 17 |
13144
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
18 /* written by Jim Meyering |
16242
59c686e5b2df
Talk about "native Windows API", not "Woe32".
Bruno Haible <bruno@clisp.org>
parents:
16214
diff
changeset
|
19 and Bruno Haible for the native Windows part */ |
2052 | 20 |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
7298
diff
changeset
|
21 #include <config.h> |
2270 | 22 |
8146
b31580167c2b
New module 'time', so that apps can include <time.h> as per
Paul Eggert <eggert@cs.ucla.edu>
parents:
7897
diff
changeset
|
23 #include <time.h> |
2270 | 24 |
12327
9e07d6d6ed00
nanosleep: work around cygwin bug
Eric Blake <ebb9@byu.net>
parents:
11110
diff
changeset
|
25 #include "intprops.h" |
10230
54813304edd2
Use sigaction module rather than signal().
Eric Blake <ebb9@byu.net>
parents:
10227
diff
changeset
|
26 #include "sig-handler.h" |
12327
9e07d6d6ed00
nanosleep: work around cygwin bug
Eric Blake <ebb9@byu.net>
parents:
11110
diff
changeset
|
27 #include "verify.h" |
7897
b7a83a69ac23
* MODULES.html.sh (Support for systems lacking POSIX:2001): New
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
28 |
5159 | 29 #include <stdbool.h> |
2053 | 30 #include <stdio.h> |
7298
6948138d9f3a
* nanosleep.c: Include <sys/types.h> before sys/select.h, to avoid
Jim Meyering <jim@meyering.net>
parents:
7237
diff
changeset
|
31 #include <sys/types.h> |
10227 | 32 #include <sys/select.h> |
2053 | 33 #include <signal.h> |
2052 | 34 |
7897
b7a83a69ac23
* MODULES.html.sh (Support for systems lacking POSIX:2001): New
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
35 #include <sys/time.h> |
2057 | 36 #include <errno.h> |
37 | |
6275 | 38 #include <unistd.h> |
2056 | 39 |
8146
b31580167c2b
New module 'time', so that apps can include <time.h> as per
Paul Eggert <eggert@cs.ucla.edu>
parents:
7897
diff
changeset
|
40 |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
41 enum { BILLION = 1000 * 1000 * 1000 }; |
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
42 |
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
43 #if HAVE_BUG_BIG_NANOSLEEP |
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
44 |
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
45 int |
13134
080377ada58c
nanosleep: Fix C++ test error on mingw.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
46 nanosleep (const struct timespec *requested_delay, |
080377ada58c
nanosleep: Fix C++ test error on mingw.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
47 struct timespec *remaining_delay) |
14379
2330aac2ae54
maint: adjust cpp indentation to reflect nesting depth
Jim Meyering <meyering@redhat.com>
parents:
14079
diff
changeset
|
48 # undef nanosleep |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
49 { |
13852
299859ce1b75
sleep, nanosleep: Work around Linux 2.6.9 nanosleep bug.
Bruno Haible <bruno@clisp.org>
parents:
13782
diff
changeset
|
50 /* nanosleep mishandles large sleeps due to internal overflow problems. |
299859ce1b75
sleep, nanosleep: Work around Linux 2.6.9 nanosleep bug.
Bruno Haible <bruno@clisp.org>
parents:
13782
diff
changeset
|
51 The worst known case of this is Linux 2.6.9 with glibc 2.3.4, which |
299859ce1b75
sleep, nanosleep: Work around Linux 2.6.9 nanosleep bug.
Bruno Haible <bruno@clisp.org>
parents:
13782
diff
changeset
|
52 can't sleep more than 24.85 days (2^31 milliseconds). Similarly, |
299859ce1b75
sleep, nanosleep: Work around Linux 2.6.9 nanosleep bug.
Bruno Haible <bruno@clisp.org>
parents:
13782
diff
changeset
|
53 cygwin 1.5.x, which can't sleep more than 49.7 days (2^32 milliseconds). |
299859ce1b75
sleep, nanosleep: Work around Linux 2.6.9 nanosleep bug.
Bruno Haible <bruno@clisp.org>
parents:
13782
diff
changeset
|
54 Solve this by breaking the sleep up into smaller chunks. */ |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
55 |
13782
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
56 if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) |
12327
9e07d6d6ed00
nanosleep: work around cygwin bug
Eric Blake <ebb9@byu.net>
parents:
11110
diff
changeset
|
57 { |
13782
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
58 errno = EINVAL; |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
59 return -1; |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
60 } |
13782
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
61 |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
62 { |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
63 /* Verify that time_t is large enough. */ |
13852
299859ce1b75
sleep, nanosleep: Work around Linux 2.6.9 nanosleep bug.
Bruno Haible <bruno@clisp.org>
parents:
13782
diff
changeset
|
64 verify (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60); |
299859ce1b75
sleep, nanosleep: Work around Linux 2.6.9 nanosleep bug.
Bruno Haible <bruno@clisp.org>
parents:
13782
diff
changeset
|
65 const time_t limit = 24 * 24 * 60 * 60; |
13782
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
66 time_t seconds = requested_delay->tv_sec; |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
67 struct timespec intermediate; |
15323
b4b10d174a9d
nanosleep: simplify carrying
Paul Eggert <eggert@cs.ucla.edu>
parents:
14379
diff
changeset
|
68 intermediate.tv_nsec = requested_delay->tv_nsec; |
13782
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
69 |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
70 while (limit < seconds) |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
71 { |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
72 int result; |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
73 intermediate.tv_sec = limit; |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
74 result = nanosleep (&intermediate, remaining_delay); |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
75 seconds -= limit; |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
76 if (result) |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
77 { |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
78 if (remaining_delay) |
15323
b4b10d174a9d
nanosleep: simplify carrying
Paul Eggert <eggert@cs.ucla.edu>
parents:
14379
diff
changeset
|
79 remaining_delay->tv_sec += seconds; |
13782
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
80 return result; |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
81 } |
15323
b4b10d174a9d
nanosleep: simplify carrying
Paul Eggert <eggert@cs.ucla.edu>
parents:
14379
diff
changeset
|
82 intermediate.tv_nsec = 0; |
13782
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
83 } |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
84 intermediate.tv_sec = seconds; |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
85 return nanosleep (&intermediate, remaining_delay); |
3a4a1b81c846
nanosleep: Make replacement POSIX compliant.
Bruno Haible <bruno@clisp.org>
parents:
13144
diff
changeset
|
86 } |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
87 } |
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
88 |
13144
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
89 #elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
90 /* Native Windows platforms. */ |
13144
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
91 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
92 # define WIN32_LEAN_AND_MEAN |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
93 # include <windows.h> |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
94 |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
95 /* The Windows API function Sleep() has a resolution of about 15 ms and takes |
13144
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
96 at least 5 ms to execute. We use this function for longer time periods. |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
97 Additionally, we use busy-looping over short time periods, to get a |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
98 resolution of about 0.01 ms. In order to measure such short timespans, |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
99 we use the QueryPerformanceCounter() function. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
100 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
101 int |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
102 nanosleep (const struct timespec *requested_delay, |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
103 struct timespec *remaining_delay) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
104 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
105 static bool initialized; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
106 /* Number of performance counter increments per nanosecond, |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
107 or zero if it could not be determined. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
108 static double ticks_per_nanosecond; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
109 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
110 if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
111 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
112 errno = EINVAL; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
113 return -1; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
114 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
115 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
116 /* For requested delays of one second or more, 15ms resolution is |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
117 sufficient. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
118 if (requested_delay->tv_sec == 0) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
119 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
120 if (!initialized) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
121 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
122 /* Initialize ticks_per_nanosecond. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
123 LARGE_INTEGER ticks_per_second; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
124 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
125 if (QueryPerformanceFrequency (&ticks_per_second)) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
126 ticks_per_nanosecond = |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
127 (double) ticks_per_second.QuadPart / 1000000000.0; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
128 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
129 initialized = true; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
130 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
131 if (ticks_per_nanosecond) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
132 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
133 /* QueryPerformanceFrequency worked. We can use |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
134 QueryPerformanceCounter. Use a combination of Sleep and |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
135 busy-looping. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
136 /* Number of milliseconds to pass to the Sleep function. |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
137 Since Sleep can take up to 8 ms less or 8 ms more than requested |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
138 (or maybe more if the system is loaded), we subtract 10 ms. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
139 int sleep_millis = (int) requested_delay->tv_nsec / 1000000 - 10; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
140 /* Determine how many ticks to delay. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
141 LONGLONG wait_ticks = requested_delay->tv_nsec * ticks_per_nanosecond; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
142 /* Start. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
143 LARGE_INTEGER counter_before; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
144 if (QueryPerformanceCounter (&counter_before)) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
145 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
146 /* Wait until the performance counter has reached this value. |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
147 We don't need to worry about overflow, because the performance |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
148 counter is reset at reboot, and with a frequency of 3.6E6 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
149 ticks per second 63 bits suffice for over 80000 years. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
150 LONGLONG wait_until = counter_before.QuadPart + wait_ticks; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
151 /* Use Sleep for the longest part. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
152 if (sleep_millis > 0) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
153 Sleep (sleep_millis); |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
154 /* Busy-loop for the rest. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
155 for (;;) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
156 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
157 LARGE_INTEGER counter_after; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
158 if (!QueryPerformanceCounter (&counter_after)) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
159 /* QueryPerformanceCounter failed, but succeeded earlier. |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
160 Should not happen. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
161 break; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
162 if (counter_after.QuadPart >= wait_until) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
163 /* The requested time has elapsed. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
164 break; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
165 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
166 goto done; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
167 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
168 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
169 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
170 /* Implementation for long delays and as fallback. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
171 Sleep (requested_delay->tv_sec * 1000 + requested_delay->tv_nsec / 1000000); |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
172 |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
173 done: |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
174 /* Sleep is not interruptible. So there is no remaining delay. */ |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
175 if (remaining_delay != NULL) |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
176 { |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
177 remaining_delay->tv_sec = 0; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
178 remaining_delay->tv_nsec = 0; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
179 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
180 return 0; |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
181 } |
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
182 |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
183 #else |
13144
ded40bf5dced
Implement nanosleep for native Windows.
Bruno Haible <bruno@clisp.org>
parents:
13134
diff
changeset
|
184 /* Unix platforms lacking nanosleep. */ |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
185 |
2687
34703e371994
(SIGCONT): Define if not already defined.
Jim Meyering <jim@meyering.net>
parents:
2341
diff
changeset
|
186 /* Some systems (MSDOS) don't have SIGCONT. |
34703e371994
(SIGCONT): Define if not already defined.
Jim Meyering <jim@meyering.net>
parents:
2341
diff
changeset
|
187 Using SIGTERM here turns the signal-handling code below |
34703e371994
(SIGCONT): Define if not already defined.
Jim Meyering <jim@meyering.net>
parents:
2341
diff
changeset
|
188 into a no-op on such systems. */ |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
189 # ifndef SIGCONT |
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
190 # define SIGCONT SIGTERM |
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
191 # endif |
2687
34703e371994
(SIGCONT): Define if not already defined.
Jim Meyering <jim@meyering.net>
parents:
2341
diff
changeset
|
192 |
5060
4e59cddb690f
nanosleep merge from coreutils
Paul Eggert <eggert@cs.ucla.edu>
parents:
3767
diff
changeset
|
193 static sig_atomic_t volatile suspended; |
2052 | 194 |
2053 | 195 /* Handle SIGCONT. */ |
196 | |
197 static void | |
198 sighandler (int sig) | |
199 { | |
200 suspended = 1; | |
201 } | |
202 | |
6795
9dc5bb3f3359
* lib/nanosleep.c [HAVE_SYS_SELECT_H]: Include <sys/select.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
203 /* Suspend execution for at least *TS_DELAY seconds. */ |
2052 | 204 |
205 static void | |
2056 | 206 my_usleep (const struct timespec *ts_delay) |
2052 | 207 { |
208 struct timeval tv_delay; | |
209 tv_delay.tv_sec = ts_delay->tv_sec; | |
5060
4e59cddb690f
nanosleep merge from coreutils
Paul Eggert <eggert@cs.ucla.edu>
parents:
3767
diff
changeset
|
210 tv_delay.tv_usec = (ts_delay->tv_nsec + 999) / 1000; |
4e59cddb690f
nanosleep merge from coreutils
Paul Eggert <eggert@cs.ucla.edu>
parents:
3767
diff
changeset
|
211 if (tv_delay.tv_usec == 1000000) |
4e59cddb690f
nanosleep merge from coreutils
Paul Eggert <eggert@cs.ucla.edu>
parents:
3767
diff
changeset
|
212 { |
15324
04f6eb9c0c53
nanosleep: fix integer overflow problem
Paul Eggert <eggert@cs.ucla.edu>
parents:
15323
diff
changeset
|
213 if (tv_delay.tv_sec == TYPE_MAXIMUM (time_t)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
214 tv_delay.tv_usec = 1000000 - 1; /* close enough */ |
6795
9dc5bb3f3359
* lib/nanosleep.c [HAVE_SYS_SELECT_H]: Include <sys/select.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
215 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
216 { |
15324
04f6eb9c0c53
nanosleep: fix integer overflow problem
Paul Eggert <eggert@cs.ucla.edu>
parents:
15323
diff
changeset
|
217 tv_delay.tv_sec++; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
218 tv_delay.tv_usec = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
219 } |
5060
4e59cddb690f
nanosleep merge from coreutils
Paul Eggert <eggert@cs.ucla.edu>
parents:
3767
diff
changeset
|
220 } |
5813 | 221 select (0, NULL, NULL, NULL, &tv_delay); |
2052 | 222 } |
223 | |
6795
9dc5bb3f3359
* lib/nanosleep.c [HAVE_SYS_SELECT_H]: Include <sys/select.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
224 /* Suspend execution for at least *REQUESTED_DELAY seconds. The |
9dc5bb3f3359
* lib/nanosleep.c [HAVE_SYS_SELECT_H]: Include <sys/select.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6275
diff
changeset
|
225 *REMAINING_DELAY part isn't implemented yet. */ |
2058 | 226 |
2052 | 227 int |
13134
080377ada58c
nanosleep: Fix C++ test error on mingw.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
228 nanosleep (const struct timespec *requested_delay, |
080377ada58c
nanosleep: Fix C++ test error on mingw.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
229 struct timespec *remaining_delay) |
2052 | 230 { |
5159 | 231 static bool initialized; |
5060
4e59cddb690f
nanosleep merge from coreutils
Paul Eggert <eggert@cs.ucla.edu>
parents:
3767
diff
changeset
|
232 |
12328
bf3fd58aaf19
nanosleep: improve port to mingw
Eric Blake <ebb9@byu.net>
parents:
12327
diff
changeset
|
233 if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) |
bf3fd58aaf19
nanosleep: improve port to mingw
Eric Blake <ebb9@byu.net>
parents:
12327
diff
changeset
|
234 { |
bf3fd58aaf19
nanosleep: improve port to mingw
Eric Blake <ebb9@byu.net>
parents:
12327
diff
changeset
|
235 errno = EINVAL; |
bf3fd58aaf19
nanosleep: improve port to mingw
Eric Blake <ebb9@byu.net>
parents:
12327
diff
changeset
|
236 return -1; |
bf3fd58aaf19
nanosleep: improve port to mingw
Eric Blake <ebb9@byu.net>
parents:
12327
diff
changeset
|
237 } |
bf3fd58aaf19
nanosleep: improve port to mingw
Eric Blake <ebb9@byu.net>
parents:
12327
diff
changeset
|
238 |
2058 | 239 /* set up sig handler */ |
5060
4e59cddb690f
nanosleep merge from coreutils
Paul Eggert <eggert@cs.ucla.edu>
parents:
3767
diff
changeset
|
240 if (! initialized) |
2058 | 241 { |
10232 | 242 struct sigaction oldact; |
2053 | 243 |
2058 | 244 sigaction (SIGCONT, NULL, &oldact); |
10230
54813304edd2
Use sigaction module rather than signal().
Eric Blake <ebb9@byu.net>
parents:
10227
diff
changeset
|
245 if (get_handler (&oldact) != SIG_IGN) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
246 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
247 struct sigaction newact; |
10232 | 248 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
249 newact.sa_handler = sighandler; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
250 sigemptyset (&newact.sa_mask); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
251 newact.sa_flags = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
252 sigaction (SIGCONT, &newact, NULL); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
253 } |
5159 | 254 initialized = true; |
2058 | 255 } |
2052 | 256 |
5813 | 257 suspended = 0; |
258 | |
2056 | 259 my_usleep (requested_delay); |
2052 | 260 |
2056 | 261 if (suspended) |
2052 | 262 { |
263 /* Calculate time remaining. */ | |
264 /* FIXME: the code in sleep doesn't use this, so there's no | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12328
diff
changeset
|
265 rush to implement it. */ |
2058 | 266 |
267 errno = EINTR; | |
2052 | 268 } |
269 | |
270 /* FIXME: Restore sig handler? */ | |
271 | |
2056 | 272 return suspended; |
2052 | 273 } |
7237
119870bc83d7
Work around a bug in both the Linux and SunOS 64-bit kernels:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6795
diff
changeset
|
274 #endif |