X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fxnanosleep.c;h=f2d9e93be3a80648b94f8c33ac4a1c1b26b8da88;hb=083768e30add2d4c53372b98ae64092d1b97ee4b;hp=8aa5e8a8de68c502f8499521e23e99db71fb00eb;hpb=10ce26c08f4e8ffe6ac636b1fec6a33a847b0d3a;p=gnulib.git diff --git a/lib/xnanosleep.c b/lib/xnanosleep.c index 8aa5e8a8d..f2d9e93be 100644 --- a/lib/xnanosleep.c +++ b/lib/xnanosleep.c @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Mostly written (for sleep.c) by Paul Eggert. Factored out (creating this file) by Jim Meyering. */ @@ -32,35 +32,13 @@ #include #include +#include "intprops.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)) -/* The outer cast is needed to work around a bug in Cray C 5.0.3.0. - It is necessary at least when t == time_t. */ -#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ - ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) -#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t))) #ifndef TIME_T_MAX # 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 +54,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 +91,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;