summaryrefslogtreecommitdiff
path: root/lib/xnanosleep.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xnanosleep.c')
-rw-r--r--lib/xnanosleep.c47
1 files changed, 8 insertions, 39 deletions
diff --git a/lib/xnanosleep.c b/lib/xnanosleep.c
index 8aa5e8a8de..fcfe3d551d 100644
--- a/lib/xnanosleep.c
+++ b/lib/xnanosleep.c
@@ -33,8 +33,6 @@
#include <time.h>
#include "timespec.h"
-#include "gethrxtime.h"
-#include "xtime.h"
/* The extra casts work around common compiler bugs. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
@@ -48,19 +46,6 @@
# define TIME_T_MAX TYPE_MAXIMUM (time_t)
#endif
-/* POSIX.1-2001 requires that when a process is suspended, then
- resumed, nanosleep (A, B) returns -1, sets errno to EINTR, and sets
- *B to the time remaining at the point of resumption. However, some
- versions of the Linux kernel incorrectly return the time remaining
- at the point of suspension. Work around this bug on GNU/Linux
- hosts by computing the remaining time here after nanosleep returns,
- rather than by relying on nanosleep's computation. */
-#ifdef __linux__
-enum { NANOSLEEP_BUG_WORKAROUND = true };
-#else
-enum { NANOSLEEP_BUG_WORKAROUND = false };
-#endif
-
/* Sleep until the time (call it WAKE_UP_TIME) specified as
SECONDS seconds after the time this function is called.
SECONDS must be non-negative. If SECONDS is so large that
@@ -76,19 +61,9 @@ xnanosleep (double seconds)
bool overflow = false;
double ns;
struct timespec ts_sleep;
- xtime_t stop = 0;
assert (0 <= seconds);
- if (NANOSLEEP_BUG_WORKAROUND)
- {
- xtime_t now = gethrxtime ();
- double increment = XTIME_PRECISION * seconds;
- xtime_t incr = increment;
- stop = now + incr + (incr < increment);
- overflow = (stop < now);
- }
-
/* Separate whole seconds from nanoseconds.
Be careful to detect any overflow. */
ts_sleep.tv_sec = seconds;
@@ -123,23 +98,17 @@ xnanosleep (double seconds)
ts_sleep.tv_nsec = BILLION - 1;
}
+ /* Linux-2.6.8.1's nanosleep returns -1, but doesn't set errno
+ when resumed after being suspended. Earlier versions would
+ set errno to EINTR. nanosleep from linux-2.6.10, as well as
+ implementations by (all?) other vendors, doesn't return -1
+ in that case; either it continues sleeping (if time remains)
+ or it returns zero (if the wake-up time has passed). */
+ errno = 0;
if (nanosleep (&ts_sleep, NULL) == 0)
break;
- if (errno != EINTR)
+ if (errno != EINTR && errno != 0)
return -1;
-
- if (NANOSLEEP_BUG_WORKAROUND)
- {
- xtime_t now = gethrxtime ();
- if (stop <= now)
- break;
- else
- {
- xtime_t remaining = stop - now;
- ts_sleep.tv_sec = xtime_nonnegative_sec (remaining);
- ts_sleep.tv_nsec = xtime_nonnegative_nsec (remaining);
- }
- }
}
return 0;