Re: avoiding unnecessary dependency on -lrt and -lpthread

2005-02-27 Thread Jim Meyering
Paul Eggert [EMAIL PROTECTED] wrote:
 Jim Meyering [EMAIL PROTECTED] 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  [EMAIL PROTECTED]

   * 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
[EMAIL PROTECTED]  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  [EMAIL PROTECTED]

* 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.c21 Feb 2005 08:10:47 -  1.11
+++ lib/xnanosleep.c25 Feb 2005 23:46:23 -
@@ -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


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: avoiding unnecessary dependency on -lrt and -lpthread

2005-02-21 Thread Paul Eggert
Jim Meyering [EMAIL PROTECTED] writes:

 Paul Eggert [EMAIL PROTECTED] wrote:
 How about if we add a new module (getmonotime, say?) that gets
 CLOCK_MONTONIC time, and use that in dd and sleep?  On Solaris this
 could be done via gethrtime()...

 That sounds good.

OK, I did that, and installed the following patch.  It also cleans up
gettime a bit too, by using some of the ideas now in gethrxtime.  I
realize this is all a bit much if you're trying for a stable coreutils
release sometime real soon, so if that's a problem please let me know
and I'll back out the change.

2005-02-20  Paul Eggert  [EMAIL PROTECTED]

* NEWS: Describe user-visible change to dd.

* lib/gethrxtime.h, lib/gethrxtime.c, lib/xtime.h: New files.
* lib/timespec.h (gettime): Return void, since it always
succeeds now.  All uses changed.
* lib/gettime.c (gettime) Likewise.
[HAVE_NANOTIME]: Prefer nanotime.
Assume gettimeofday succeeds, as POSIX requires.
Assime time () succeeds, since other code already does.
* lib/xnanosleep.c: Include xtime.h and gethrxtime.h, not xalloc.h.
(timespec_subtract): Remove.
(NANOSLEEP_BUG_WORKAROUND): New constant.
(xnanosleep): Use gethrxtime rather than gettime; this simplifies
things considerably.  Use it only on GNU/Linux hosts, since the
workaround shouldn't be needed elsewhere.

* m4/gethrxtime.m4: New file.
* m4/gettime.m4 (gl_GETTIME): Check for nanotime.
* m4/jm-macros.m4 (gl_MACROS): Don't check for gethrtime.
* m4/prereq.m4 (gl_PREREQ): Require gl_GETHRXTIME.

* src/Makefile.am (dd_LDADD, shred_LDADD, nanosec_libs):
Remove $(LIB_CLOCK_GETTIME).  These functions now use
gethrxtime instead.
* src/dd.c: Include gethrxtime.h, xtime.h.
(start_time): Now of type xtime_t, not struct timespec.
(print_stats, main): Use gethrxtime rather than gettime.
* src/ls.c (time): Remove obsolete decl.
(get_current_time): gettimeofday always returns 0, so don't
check its result.
* src/shred.c: Include gethrxtime.h.
(isaac_seed): Use gethrxtime rather than a mishmash.
* src/touch.c (time): Remove obsolete decl.

Index: NEWS
===
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.269
diff -p -u -r1.269 NEWS
--- NEWS15 Feb 2005 12:33:35 -  1.269
+++ NEWS21 Feb 2005 08:05:11 -
@@ -20,6 +20,10 @@ GNU coreutils NEWS  
 
 ** Bug fixes
 
+  dd now computes statistics using a realtime clock (if available)
+  rather than the time-of-day clock, to avoid glitches if the
+  time-of-day is changed while dd is running.
+
   expr now detects integer overflow when evaluating large integers,
   rather than silently wrapping around.
 
--- /dev/null   2003-03-18 21:55:57 +
+++ lib/xtime.h 2005-02-21 07:35:58 +
@@ -0,0 +1,87 @@
+/* xtime -- extended-resolution integer time stamps
+
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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.  */
+
+/* Written by Paul Eggert.  */
+
+#ifndef XTIME_H_
+#define XTIME_H_ 1
+
+/* xtime_t is a signed type used for time stamps.  It is an integer
+   type that is a count of nanoseconds -- except for obsolescent hosts
+   without sufficiently-wide integers, where it is a count of
+   seconds.  */
+#if HAVE_LONG_LONG
+typedef long long int xtime_t;
+# define XTIME_PRECISION 10LL
+#else
+# include limits.h
+typedef long int xtime_t;
+# if LONG_MAX  31  31 == 0
+#  define XTIME_PRECISION 1L
+# else
+#  define XTIME_PRECISION 10L
+# endif
+#endif
+
+/* Return an extended time value that contains S seconds and NS
+   nanoseconds, without any overflow checking.  */
+static inline xtime_t
+xtime_make (xtime_t s, int ns)
+{
+  if (XTIME_PRECISION == 1)
+return s;
+  else
+return XTIME_PRECISION * s + ns;
+}
+
+/* Return the number of seconds in T, which must be nonnegative.  */
+static inline xtime_t
+xtime_nonnegative_sec (xtime_t t)
+{
+  return t / XTIME_PRECISION;
+}
+
+/* Return the number of seconds in T.  */
+static inline xtime_t
+xtime_sec (xtime_t t)
+{
+  return (XTIME_PRECISION == 1
+ ? t
+ : t  0
+ ? (t +