+2005-03-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remove workaround for bug in Linux kernel 2.6.8 or thereabouts.
+ The workaround isn't strictly needed for POSIX conformance, and
+ it's too much of a pain to configure and maintain. We'll ask
+ people to fix their kernels instead.
+ * xnanosleep.c: Don't include gethrxtime.h or xtime.h.
+ (NANOSLEEP_BUG_WORKAROUND): Remove.
+ (xnanosleep): Remove the workaround.
+
2005-02-12 Bruno Haible <bruno@clisp.org>
* vasnprintf.c (EOVERFLOW): Define to a fallback if needed.
#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))
# 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
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;
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;
-# xnanosleep.m4 serial 1
+# xnanosleep.m4 serial 2
dnl Copyright (C) 2005 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
[
AC_LIBSOURCES([xnanosleep.c, xnanosleep.h])
AC_LIBOBJ([xnanosleep])
-
- dnl Prerequisites of lib/xnanosleep.c.
- AC_REQUIRE([gl_PREREQ_GETHRXTIME])
-
- LIB_XNANOSLEEP=
- case $LIB_GETHRXTIME in
- ?*)
- AC_CACHE_CHECK([whether __linux__ is defined],
- gl_cv_have___linux__,
- [AC_EGREP_CPP([have___linux__],
- [
-# ifdef __linux__
- have___linux__
-# endif
- ],
- gl_cv_have___linux__=yes,
- gl_cv_have___linux__=no)])
- if test $gl_cv_have___linux__ = yes; then
- LIB_XNANOSLEEP=$LIB_GETHRXTIME
- fi;;
- esac
- AC_SUBST([LIB_XNANOSLEEP])
])