bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-gnulib] Re: avoiding unnecessary dependency on -lrt and -lpthread


From: Jim Meyering
Subject: [bug-gnulib] Re: avoiding unnecessary dependency on -lrt and -lpthread
Date: Sun, 27 Feb 2005 23:29:26 +0100

Paul Eggert <address@hidden> wrote:
> Jim Meyering <address@hidden> writes:
>> gethrxtime uses clock_gettime on Linux systems (and any other system
>> without nanouptime), so such systems will get link errors for
>> clock_gettime if it's in a separate library like -lrt.
>
> Sorry, I didn't test with new-enough GNU/Linux systems.  I installed
> this further patch to work around the problem.  This is "make check"
> tested with Debian GNU/Linux 3.0 and 3.1-beta (x86), Solaris 8 64-bit
> sparc (Forte 6 cc), Solaris 9 32-bit sparc (Forte 7 c89), and OpenBSD
> 3.4 x86.
>
> 2005-02-21  Paul Eggert  <address@hidden>
>
>       * m4/xnanosleep.m4: New file.
>       * lib/Makefile.am (libfetish_a_SOURCES): Remove xnanosleep.c,
>       xnanosleep.h; now done by ../m4/xnanosleep.m4 automatically.
>       * m4/gethrxtime.m4 (gl_PREREQ_GETHRXTIME): Require gl_CLOCK_TIME,
>       gl_USE_SYSTEM_EXTENSIONS.  Check whether CLOCK_MONOTONIC is
>       defined, and set LIB_GETHRXTIME accordingly.  This is needed
>       for newer GNU/Linux systems that have clock_gettime, so that they
>       link in the appropriate library for it when needed.
>       * m4/prereq.m4 (gl_PREREQ): Require gl_XNANOSLEEP.
>       * src/Makefile.am (dd_LDADD, shred_LDADD): Add $(LIB_GETHRXTIME).
>       (nanosec_libs): Add $(LIB_XNANOSLEEP).  Needed for newer GNU/Linux
>       hosts with clock_gettime.

Hi Paul,

Thanks for doing that.
This all started with the lament, http://bugs.debian.org/122639,
that sleep(1) require linking with librt and hence libpthread
on a system with a Linux kernel.

Currently, coreutils' lib/xnanosleep.c needs -lrt solely to work
around a bug in the Linux kernel's implementation of nanosleep.

  /* 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

But it looks like that bug was fixed sometime between linux-2.6.8
(which has the bug) and linux-2.6.10, which apparently does not.
So if configure automatically detects whether xnanosleep needs the
workaround, binaries built for the newer systems won't have to use
the work-around code or -lrt.

I've written a test program to do that and will post it separately, to
address@hidden  That exercise led me to discover that a variant of
this Linux kernel bug makes sleep malfunction, at least on linux-2.6.8.1
systems.  Sleep fails when suspended and then resumed on such systems:

  $ sleep 9 & pid=$!
  [1] 6451
  $ kill -TSTP $pid; kill -CONT $pid
  sleep: cannot read realtime clock
  [1]+  Exit 1                  sleep 9

We can fix it with this patch:

2005-02-27  Jim Meyering  <address@hidden>

        * xnanosleep.c (xnanosleep): Work around bug in Linux-2.6.8.1's
        nanosleep whereby it fails without setting errno upon being resumed
        after being suspended.

Index: lib/xnanosleep.c
===================================================================
RCS file: /fetish/cu/lib/xnanosleep.c,v
retrieving revision 1.11
diff -u -p -r1.11 xnanosleep.c
--- lib/xnanosleep.c    21 Feb 2005 08:10:47 -0000      1.11
+++ lib/xnanosleep.c    25 Feb 2005 23:46:23 -0000
@@ -123,9 +123,10 @@ xnanosleep (double seconds)
          ts_sleep.tv_nsec = BILLION - 1;
        }
 
+      errno = 0;
       if (nanosleep (&ts_sleep, NULL) == 0)
        break;
-      if (errno != EINTR)
+      if (errno != EINTR && errno != 0)
        return -1;
 
       if (NANOSLEEP_BUG_WORKAROUND)

I'll probably check that in.  The alternative is to provide
a nanosleep wrapper that sets errno in this case.  But the
only uses of nanosleep in coreutils are through xnanosleep,
so it's probably not worth it, there.

If any of you know of a package that uses nanosleep where
this would matter, please provide details.

Jim




reply via email to

[Prev in Thread] Current Thread [Next in Thread]