bug-coreutils
[Top][All Lists]
Advanced

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

Re: avoiding unnecessary dependency on -lrt and -lpthread


From: Paul Eggert
Subject: Re: avoiding unnecessary dependency on -lrt and -lpthread
Date: Mon, 21 Feb 2005 00:32:25 -0800
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.4 (gnu/linux)

Jim Meyering <address@hidden> writes:

> Paul Eggert <address@hidden> 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  <address@hidden>

        * 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
--- NEWS        15 Feb 2005 12:33:35 -0000      1.269
+++ NEWS        21 Feb 2005 08:05:11 -0000
@@ -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 +0000
+++ lib/xtime.h 2005-02-21 07:35:58 +0000
@@ -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 1000000000LL
+#else
+# include <limits.h>
+typedef long int xtime_t;
+# if LONG_MAX >> 31 >> 31 == 0
+#  define XTIME_PRECISION 1L
+# else
+#  define XTIME_PRECISION 1000000000L
+# 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 + XTIME_PRECISION - 1) / XTIME_PRECISION - 1
+         : xtime_nonnegative_sec (t));
+}
+
+/* Return the number of nanoseconds in T, which must be nonnegative.  */
+static inline int
+xtime_nonnegative_nsec (xtime_t t)
+{
+  return t % XTIME_PRECISION;
+}
+
+/* Return the number of nanoseconds in T.  */
+static inline int
+xtime_nsec (xtime_t t)
+{
+  int ns = t % XTIME_PRECISION;
+  if (ns < 0)
+    ns += XTIME_PRECISION;
+  return ns;
+}
+
+#endif
--- /dev/null   2003-03-18 21:55:57 +0000
+++ lib/gethrxtime.h    2005-02-21 08:03:26 +0000
@@ -0,0 +1,37 @@
+/* gethrxtime -- get high resolution real time
+
+   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 GETHRXTIME_H_
+#define GETHRXTIME_H_ 1
+
+#include "xtime.h"
+
+/* Get the current time, as a count of the number of nanoseconds since
+   an arbitrary epoch (e.g., the system boot time).  This clock can't
+   be set, is always increasing, and is nearly linear.  */
+
+#if HAVE_ARITHMETIC_HRTIME_T && HAVE_DECL_GETHRTIME
+# include <time.h>
+static inline xtime_t gethrxtime (void) { return gethrtime (); }
+#else
+xtime_t gethrxtime (void);
+#endif
+
+#endif
--- /dev/null   2003-03-18 21:55:57 +0000
+++ lib/gethrxtime.c    2005-02-21 08:03:44 +0000
@@ -0,0 +1,80 @@
+/* gethrxtime -- get high resolution real time
+
+   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.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "gethrxtime.h"
+
+#include <sys/types.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+/* Get the time of a high-resolution clock, preferably one that is not
+   subject to resetting or drifting.  */
+
+xtime_t
+gethrxtime (void)
+{
+#if HAVE_NANOUPTIME
+  {
+    struct timespec ts;
+    nanouptime (&ts);
+    return xtime_make (ts.tv_sec, ts.tv_nsec);
+  }
+#else
+
+# if defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME
+  {
+    struct timespec ts;
+    if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
+      return xtime_make (ts.tv_sec, ts.tv_nsec);
+  }
+# endif
+
+#if HAVE_MICROUPTIME
+  {
+    struct timeval tv;
+    microuptime (&tv);
+    return xtime_make (tv.tv_sec, 1000 * tv.tv_usec);
+  }
+
+  /* No monotonically increasing clocks are available; fall back on a
+     clock that might jump backwards, since it's the best we can do.  */
+# elif HAVE_GETTIMEOFDAY && XTIME_PRECISION != 1
+  {
+    struct timeval tv;
+    gettimeofday (&tv, NULL);
+    return xtime_make (tv.tv_sec, 1000 * tv.tv_usec);
+  }
+# else
+  return xtime_make (time (NULL), 0);
+# endif
+#endif
+}
Index: lib/getdate.y
===================================================================
RCS file: /fetish/cu/lib/getdate.y,v
retrieving revision 1.94
diff -p -u -r1.94 getdate.y
--- lib/getdate.y       24 Dec 2004 05:27:07 -0000      1.94
+++ lib/getdate.y       21 Feb 2005 08:05:11 -0000
@@ -1,6 +1,8 @@
 %{
 /* Parse a string into an internal time stamp.
-   Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   Copyright (C) 1999, 2000, 2002, 2003, 2004, 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
@@ -1125,8 +1127,7 @@ get_date (struct timespec *result, char 
 
   if (! now)
     {
-      if (gettime (&gettime_buffer) != 0)
-       return false;
+      gettime (&gettime_buffer);
       now = &gettime_buffer;
     }
 
Index: lib/gettime.c
===================================================================
RCS file: /fetish/cu/lib/gettime.c,v
retrieving revision 1.3
diff -p -u -r1.3 gettime.c
--- lib/gettime.c       5 Aug 2004 23:01:05 -0000       1.3
+++ lib/gettime.c       21 Feb 2005 08:05:11 -0000
@@ -1,5 +1,5 @@
 /* gettime -- get the system clock
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004, 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
@@ -23,37 +23,31 @@
 
 #include "timespec.h"
 
-/* Get the system time.  */
+/* Get the system time into *TS.  */
 
-int
+void
 gettime (struct timespec *ts)
 {
-#if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME
+#if HAVE_NANOTIME
+  nanotime (ts);
+#else
+
+# if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME
   if (clock_gettime (CLOCK_REALTIME, ts) == 0)
-    return 0;
-#endif
+    return;
+# endif
 
-#if HAVE_GETTIMEOFDAY
+# if HAVE_GETTIMEOFDAY
   {
     struct timeval tv;
-    if (gettimeofday (&tv, 0) == 0)
-      {
-       ts->tv_sec = tv.tv_sec;
-       ts->tv_nsec = tv.tv_usec * 1000;
-       return 0;
-      }
+    gettimeofday (&tv, NULL);
+    ts->tv_sec = tv.tv_sec;
+    ts->tv_nsec = tv.tv_usec * 1000;
   }
-#endif
+# else
+  ts->tv_sec = time (NULL);
+  ts->tv_nsec = 0;
+# endif
 
-  {
-    time_t t = time (0);
-    if (t != (time_t) -1)
-      {
-       ts->tv_sec = t;
-       ts->tv_nsec = 0;
-       return 0;
-      }
-  }
-
-  return -1;
+#endif
 }
Index: lib/timespec.h
===================================================================
RCS file: /fetish/cu/lib/timespec.h,v
retrieving revision 1.3
diff -p -u -r1.3 timespec.h
--- lib/timespec.h      5 Feb 2004 09:28:22 -0000       1.3
+++ lib/timespec.h      21 Feb 2005 08:05:11 -0000
@@ -1,6 +1,6 @@
 /* timespec -- System time interface
 
-   Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2004, 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
@@ -65,7 +65,7 @@ struct timespec
 int nanosleep ();
 # endif
 
-int gettime (struct timespec *);
+void gettime (struct timespec *);
 int settime (struct timespec const *);
 
 #endif
Index: lib/xnanosleep.c
===================================================================
RCS file: /fetish/cu/lib/xnanosleep.c,v
retrieving revision 1.10
diff -p -u -r1.10 xnanosleep.c
--- lib/xnanosleep.c    7 Aug 2004 07:16:54 -0000       1.10
+++ lib/xnanosleep.c    21 Feb 2005 08:05:11 -0000
@@ -1,5 +1,5 @@
 /* xnanosleep.c -- a more convenient interface to nanosleep
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 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
@@ -32,6 +32,10 @@
 #include <sys/types.h>
 #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))
 /* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
@@ -44,44 +48,18 @@
 # define TIME_T_MAX TYPE_MAXIMUM (time_t)
 #endif
 
-#include "timespec.h"
-#include "xalloc.h"
-
-/* Subtract the `struct timespec' values X and Y by computing X - Y.
-   If the difference is negative or zero, return false.
-   Otherwise, return true and store the difference in DIFF.
-   X and Y must have valid ts_nsec values, in the range 0 to 999999999.
-   If the difference would overflow, store the maximum possible difference.  */
-
-static bool
-timespec_subtract (struct timespec *diff,
-                  struct timespec const *x, struct timespec const *y)
-{
-  time_t sec = x->tv_sec - y->tv_sec;
-  long int nsec = x->tv_nsec - y->tv_nsec;
-
-  if (x->tv_sec < y->tv_sec)
-    return false;
-
-  if (sec < 0)
-    {
-      /* The difference has overflowed.  */
-      sec = TIME_T_MAX;
-      nsec = 999999999;
-    }
-  else if (sec == 0 && nsec <= 0)
-    return false;
-
-  if (nsec < 0)
-    {
-      sec--;
-      nsec += 1000000000;
-    }
-
-  diff->tv_sec = sec;
-  diff->tv_nsec = nsec;
-  return true;
-}
+/* 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.
@@ -93,22 +71,29 @@ timespec_subtract (struct timespec *diff
 int
 xnanosleep (double seconds)
 {
-  bool overflow;
+  enum { BILLION = 1000000000 };
+
+  bool overflow = false;
   double ns;
-  struct timespec ts_start;
   struct timespec ts_sleep;
-  struct timespec ts_stop;
+  xtime_t stop = 0;
 
   assert (0 <= seconds);
 
-  if (gettime (&ts_start) != 0)
-    return -1;
+  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;
-  ns = 1e9 * (seconds - ts_sleep.tv_sec);
-  overflow = ! (ts_sleep.tv_sec <= seconds && 0 <= ns && ns <= 1e9);
+  ns = BILLION * (seconds - ts_sleep.tv_sec);
+  overflow |= ! (ts_sleep.tv_sec <= seconds && 0 <= ns && ns <= BILLION);
   ts_sleep.tv_nsec = ns;
 
   /* Round up to the next whole number, if necessary, so that we
@@ -119,7 +104,7 @@ xnanosleep (double seconds)
   ts_sleep.tv_nsec += (ts_sleep.tv_nsec < ns);
 
   /* Normalize the interval length.  nanosleep requires this.  */
-  if (1000000000 <= ts_sleep.tv_nsec)
+  if (BILLION <= ts_sleep.tv_nsec)
     {
       time_t t = ts_sleep.tv_sec + 1;
 
@@ -127,45 +112,34 @@ xnanosleep (double seconds)
       overflow |= (t < ts_sleep.tv_sec);
 
       ts_sleep.tv_sec = t;
-      ts_sleep.tv_nsec -= 1000000000;
+      ts_sleep.tv_nsec -= BILLION;
     }
 
-  /* Compute the time until which we should sleep.  */
-  ts_stop.tv_sec = ts_start.tv_sec + ts_sleep.tv_sec;
-  ts_stop.tv_nsec = ts_start.tv_nsec + ts_sleep.tv_nsec;
-  if (1000000000 <= ts_stop.tv_nsec)
+  for (;;)
     {
-      ++ts_stop.tv_sec;
-      ts_stop.tv_nsec -= 1000000000;
-    }
-
-  /* Detect integer overflow.  */
-  overflow |= (ts_stop.tv_sec < ts_start.tv_sec
-              || (ts_stop.tv_sec == ts_start.tv_sec
-                  && ts_stop.tv_nsec < ts_start.tv_nsec));
+      if (overflow)
+       {
+         ts_sleep.tv_sec = TIME_T_MAX;
+         ts_sleep.tv_nsec = BILLION - 1;
+       }
 
-  if (overflow)
-    {
-      /* Fix ts_sleep and ts_stop, which may be garbage due to overflow.  */
-      ts_sleep.tv_sec = ts_stop.tv_sec = TIME_T_MAX;
-      ts_sleep.tv_nsec = ts_stop.tv_nsec = 999999999;
-    }
-
-  while (nanosleep (&ts_sleep, NULL) != 0)
-    {
-      if (errno != EINTR || gettime (&ts_start) != 0)
+      if (nanosleep (&ts_sleep, NULL) == 0)
+       break;
+      if (errno != EINTR)
        return -1;
 
-      /* 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 by computing the remaining time here, rather than by
-        relying on nanosleep's computation.  */
-
-      if (! timespec_subtract (&ts_sleep, &ts_stop, &ts_start))
-       break;
+      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;
--- /dev/null   2003-03-18 21:55:57 +0000
+++ m4/gethrxtime.m4    2005-02-21 07:33:53 +0000
@@ -0,0 +1,57 @@
+# gethrxtime.m4 serial 1
+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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_GETHRXTIME],
+[
+  AC_LIBSOURCES([gethrxtime.c, gethrxtime.h, xtime.h])
+  AC_REQUIRE([gl_ARITHMETIC_HRTIME_T])
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_REQUIRE([gl_XTIME])
+  AC_CHECK_DECLS([gethrtime], [], [], [#include <time.h>])
+  case $ac_cv_have_decl_gethrtime,$gl_cv_arithmetic_hrtime_t in
+  yes,yes) ;;
+  *)
+    AC_LIBOBJ([gethrxtime])
+    gl_PREREQ_GETHRXTIME;;
+  esac
+])
+
+# Test whether hrtime_t is an arithmetic type.
+# It is not arithmetic in older Solaris c89 (which insists on
+# not having a long long int type).
+AC_DEFUN([gl_ARITHMETIC_HRTIME_T],
+[
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_CACHE_CHECK([for arithmetic hrtime_t], gl_cv_arithmetic_hrtime_t,
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([#include <time.h>],
+         [hrtime_t x = 0; return x/x;])],
+       [gl_cv_arithmetic_hrtime_t=yes],
+       [gl_cv_arithmetic_hrtime_t=no])])
+  if test $gl_cv_arithmetic_hrtime_t = yes; then
+    AC_DEFINE([HAVE_ARITHMETIC_HRTIME_T], 1,
+      [Define if you have an arithmetic hrtime_t type.])
+  fi
+])
+
+# Prerequisites of lib/xtime.h.
+AC_DEFUN([gl_XTIME],
+[
+  AC_REQUIRE([AC_C_INLINE])
+  AC_REQUIRE([gl_AC_TYPE_LONG_LONG])
+  :
+])
+
+# Prerequisites of lib/gethrxtime.c.
+AC_DEFUN([gl_PREREQ_GETHRXTIME],
+[
+  dnl Do not AC_REQUIRE([gl_CLOCK_TIME]), since that would unnecessarily
+  dnl require -lrt on Solaris.  Invocations of clock_gettime should be
+  dnl safe in gethrxtime.c since Solaris has native gethrtime.
+  AC_REQUIRE([AC_HEADER_TIME])
+  AC_CHECK_FUNCS_ONCE(gettimeofday microuptime nanouptime)
+  :
+])
Index: m4/gettime.m4
===================================================================
RCS file: /fetish/cu/m4/gettime.m4,v
retrieving revision 1.3
diff -p -u -r1.3 gettime.m4
--- m4/gettime.m4       29 Jan 2005 00:16:39 -0000      1.3
+++ m4/gettime.m4       21 Feb 2005 08:05:11 -0000
@@ -1,4 +1,4 @@
-# gettime.m4 serial 4
+# gettime.m4 serial 5
 dnl Copyright (C) 2002, 2004, 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,
@@ -12,5 +12,5 @@ AC_DEFUN([gl_GETTIME],
   dnl Prerequisites of lib/gettime.c.
   AC_REQUIRE([gl_CLOCK_TIME])
   AC_REQUIRE([gl_TIMESPEC])
-  AC_CHECK_FUNCS_ONCE(gettimeofday)
+  AC_CHECK_FUNCS_ONCE(gettimeofday nanotime)
 ])
Index: m4/jm-macros.m4
===================================================================
RCS file: /fetish/cu/m4/jm-macros.m4,v
retrieving revision 1.208
diff -p -u -r1.208 jm-macros.m4
--- m4/jm-macros.m4     3 Jan 2005 23:45:48 -0000       1.208
+++ m4/jm-macros.m4     21 Feb 2005 08:05:11 -0000
@@ -104,7 +104,6 @@ AC_DEFUN([gl_MACROS],
     endgrent \
     endpwent \
     ftruncate \
-    gethrtime \
     hasmntopt \
     isascii \
     iswspace \
Index: m4/prereq.m4
===================================================================
RCS file: /fetish/cu/m4/prereq.m4,v
retrieving revision 1.100
diff -p -u -r1.100 prereq.m4
--- m4/prereq.m4        8 Feb 2005 09:55:39 -0000       1.100
+++ m4/prereq.m4        21 Feb 2005 08:05:11 -0000
@@ -1,4 +1,4 @@
-#serial 47
+#serial 48
 
 dnl We use gl_ for non Autoconf macros.
 m4_pattern_forbid([^gl_[ABCDEFGHIJKLMNOPQRSTUVXYZ]])dnl
@@ -70,6 +70,7 @@ AC_DEFUN([gl_PREREQ],
   AC_REQUIRE([gl_FUNC_VASNPRINTF])
   AC_REQUIRE([gl_FUNC_VASPRINTF])
   AC_REQUIRE([gl_GETDATE])
+  AC_REQUIRE([gl_GETHRXTIME])
   AC_REQUIRE([gl_GETNDELIM2])
   AC_REQUIRE([gl_GETOPT])
   AC_REQUIRE([gl_GETPAGESIZE])
@@ -81,6 +82,7 @@ AC_DEFUN([gl_PREREQ],
   AC_REQUIRE([gl_HUMAN])
   AC_REQUIRE([gl_IDCACHE])
   AC_REQUIRE([gl_INTTOSTR])
+  AC_REQUIRE([gl_LINEBUFFER])
   AC_REQUIRE([gl_LONG_OPTIONS])
   AC_REQUIRE([gl_MAKEPATH])
   AC_REQUIRE([gl_MBSWIDTH])
@@ -108,6 +110,7 @@ AC_DEFUN([gl_PREREQ],
   AC_REQUIRE([gl_SHA1])
   AC_REQUIRE([gl_STDIO_SAFER])
   AC_REQUIRE([gl_STRCASE])
+  AC_REQUIRE([gl_STRIPSLASH])
   AC_REQUIRE([gl_TIMESPEC])
   AC_REQUIRE([gl_UNICODEIO])
   AC_REQUIRE([gl_UNISTD_SAFER])
Index: src/Makefile.am
===================================================================
RCS file: /fetish/cu/src/Makefile.am,v
retrieving revision 1.49
diff -p -u -r1.49 Makefile.am
--- src/Makefile.am     24 Jan 2005 08:22:06 -0000      1.49
+++ src/Makefile.am     21 Feb 2005 08:05:11 -0000
@@ -43,10 +43,10 @@ test_LDADD = $(LDADD) $(LIB_EACCESS)
 __LDADD = $(LDADD) $(LIB_EACCESS)
 
 # for clock_gettime and fdatasync
-dd_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_FDATASYNC)
+dd_LDADD = $(LDADD) $(LIB_FDATASYNC)
 dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
 ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
-shred_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_FDATASYNC)
+shred_LDADD = $(LDADD) $(LIB_FDATASYNC)
 vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
 
 ## If necessary, add -lm to resolve use of pow in lib/strtod.c.
@@ -69,7 +69,7 @@ seq_LDADD = $(LDADD) $(SEQ_LIBM)
 # If necessary, add -lm to resolve the `pow' reference in lib/strtod.c
 # or for the fesetround reference in programs using nanosec.c.
 nanosec_libs = \
-  $(LDADD) $(FESETROUND_LIBM) $(POW_LIB) $(LIB_CLOCK_GETTIME) $(LIB_NANOSLEEP)
+  $(LDADD) $(FESETROUND_LIBM) $(POW_LIB) $(LIB_NANOSLEEP)
 
 sleep_LDADD = $(nanosec_libs)
 tail_LDADD = $(nanosec_libs)
Index: src/date.c
===================================================================
RCS file: /fetish/cu/src/date.c,v
retrieving revision 1.139
diff -p -u -r1.139 date.c
--- src/date.c  21 Sep 2004 22:26:42 -0000      1.139
+++ src/date.c  21 Feb 2005 08:05:11 -0000
@@ -1,5 +1,5 @@
 /* date - print or set the system date and time
-   Copyright (C) 1989-2004 Free Software Foundation, Inc.
+   Copyright (C) 1989-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
@@ -424,8 +424,7 @@ argument must be a format string beginni
            {
              /* Prepare to print the current date/time.  */
              datestr = _("undefined");
-             if (gettime (&when) != 0)
-               error (EXIT_FAILURE, errno, _("cannot get time of day"));
+             gettime (&when);
              format = (n_args == 1 ? argv[optind] + 1 : NULL);
            }
        }
Index: src/dd.c
===================================================================
RCS file: /fetish/cu/src/dd.c,v
retrieving revision 1.171
diff -p -u -r1.171 dd.c
--- src/dd.c    20 Nov 2004 08:56:44 -0000      1.171
+++ src/dd.c    21 Feb 2005 08:05:11 -0000
@@ -1,5 +1,5 @@
 /* dd -- convert a file while copying it.
-   Copyright (C) 85, 90, 91, 1995-2004 Free Software Foundation, Inc.
+   Copyright (C) 85, 90, 91, 1995-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
@@ -29,6 +29,7 @@
 #include "system.h"
 #include "error.h"
 #include "full-write.h"
+#include "gethrxtime.h"
 #include "getpagesize.h"
 #include "human.h"
 #include "inttostr.h"
@@ -36,6 +37,7 @@
 #include "quote.h"
 #include "safe-read.h"
 #include "xstrtol.h"
+#include "xtime.h"
 
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "dd"
@@ -161,7 +163,7 @@ static uintmax_t r_full = 0;
 static uintmax_t w_bytes = 0;
 
 /* Time that dd started.  */
-static struct timespec start_time;
+static xtime_t start_time;
 
 /* True if input is seekable.  */
 static bool input_seekable;
@@ -477,18 +479,15 @@ multiple_bits_set (int i)
 static void
 print_stats (void)
 {
+  xtime_t now = gethrxtime ();
   char buf[2][MAX (INT_BUFSIZE_BOUND (uintmax_t), LONGEST_HUMAN_READABLE + 1)];
-  struct timespec now;
   int human_opts =
     (human_autoscale | human_round_to_nearest
      | human_space_before_unit | human_SI | human_B);
-  uintmax_t start_sec = start_time.tv_sec;
-  enum { BILLION = 1000000000 };
-  double BILLIONe0 = BILLION;
+  double XTIME_PRECISIONe0 = XTIME_PRECISION;
   double delta_s;
   char const *bytes_per_second;
 
-  gettime (&now);
   fprintf (stderr, _("%s+%s records in\n"),
           umaxtostr (r_full, buf[0]), umaxtostr (r_partial, buf[1]));
   fprintf (stderr, _("%s+%s records out\n"),
@@ -505,9 +504,8 @@ print_stats (void)
   if (status_flags & STATUS_NOXFER)
     return;
 
-  /* Use integer arithmetic to compute the transfer rate if possible,
-     since that makes it easy to use SI abbreviations; otherwise, fall
-     back on floating-point without abbreviations.  */
+  /* Use integer arithmetic to compute the transfer rate,
+     since that makes it easy to use SI abbreviations.  */
 
   fprintf (stderr,
           ngettext ("%s byte (%s) copied",
@@ -515,26 +513,18 @@ print_stats (void)
           umaxtostr (w_bytes, buf[0]),
           human_readable (w_bytes, buf[1], human_opts, 1, 1));
 
-  if ((start_time.tv_sec < now.tv_sec
-       || (start_time.tv_sec == now.tv_sec
-          && start_time.tv_nsec < now.tv_nsec))
-      && now.tv_sec - start_sec < UINTMAX_MAX / BILLION)
-    {
-      uintmax_t delta_ns = (BILLION * (now.tv_sec - start_sec)
-                           + now.tv_nsec - start_time.tv_nsec);
-      delta_s = delta_ns / BILLIONe0;
+  if (start_time < now)
+    {
+      uintmax_t delta_xtime = now;
+      delta_xtime -= start_time;
+      delta_s = delta_xtime / XTIME_PRECISIONe0;
       bytes_per_second = human_readable (w_bytes, buf[1], human_opts,
-                                        BILLION, delta_ns);
+                                        XTIME_PRECISION, delta_xtime);
     }
   else
     {
-      delta_s = now.tv_sec;
-      delta_s -= start_time.tv_sec;
-      delta_s += (now.tv_nsec - start_time.tv_nsec) / BILLIONe0;
-      if (0 < delta_s)
-       sprintf (buf[1], "%gB", w_bytes / delta_s);
-      else
-       sprintf (buf[1], "%s B", _("Infinity"));
+      delta_s = 0;
+      sprintf (buf[1], "%s B", _("Infinity"));
       bytes_per_second = buf[1];
     }
 
@@ -1540,7 +1530,7 @@ main (int argc, char **argv)
   install_handler (SIGPIPE, interrupt_handler);
   install_handler (SIGINFO, siginfo_handler);
 
-  gettime (&start_time);
+  start_time = gethrxtime ();
 
   exit_status = dd_copy ();
 
Index: src/ls.c
===================================================================
RCS file: /fetish/cu/src/ls.c,v
retrieving revision 1.373
diff -p -u -r1.373 ls.c
--- src/ls.c    17 Dec 2004 05:08:40 -0000      1.373
+++ src/ls.c    21 Feb 2005 08:05:12 -0000
@@ -1,5 +1,5 @@
 /* `dir', `vdir' and `ls' directory listing programs for GNU.
-   Copyright (C) 85, 88, 90, 91, 1995-2004 Free Software Foundation, Inc.
+   Copyright (C) 85, 88, 90, 91, 1995-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
@@ -216,10 +216,6 @@ struct bin_str
     const char *string;                /* Pointer to the same */
   };
 
-#ifndef STDC_HEADERS
-time_t time ();
-#endif
-
 char *getgroup ();
 char *getuser ();
 
@@ -3100,17 +3096,14 @@ get_current_time (void)
 #if HAVE_GETTIMEOFDAY
   {
     struct timeval timeval;
-    if (gettimeofday (&timeval, NULL) == 0)
-      {
-       current_time = timeval.tv_sec;
-       current_time_ns = timeval.tv_usec * 1000 + 999;
-       return;
-      }
+    gettimeofday (&timeval, NULL);
+    current_time = timeval.tv_sec;
+    current_time_ns = timeval.tv_usec * 1000 + 999;
   }
-#endif
-
+#else
   current_time = time (NULL);
   current_time_ns = 999999999;
+#endif
 }
 
 /* Print the user or group name NAME, with numeric id ID, using a
Index: src/shred.c
===================================================================
RCS file: /fetish/cu/src/shred.c,v
retrieving revision 1.106
diff -p -u -r1.106 shred.c
--- src/shred.c 15 Jan 2005 17:19:47 -0000      1.106
+++ src/shred.c 21 Feb 2005 08:05:12 -0000
@@ -27,9 +27,6 @@
   - Add -i/--interactive
   - Reserve -d
   - Add -L
-  - Deal with the amazing variety of gettimeofday() implementation bugs.
-    (Some systems use a one-arg form; still others insist that the timezone
-    either be NULL or be non-NULL.  Whee.)
   - Add an unlink-all option to emulate rm.
  */
 
@@ -106,6 +103,7 @@
 #include "xstrtol.h"
 #include "dirname.h"
 #include "error.h"
+#include "gethrxtime.h"
 #include "getpagesize.h"
 #include "human.h"
 #include "inttostr.h"
@@ -587,20 +585,7 @@ isaac_seed (struct isaac_state *s)
   { gid_t t = getgid ();   ISAAC_SEED (s, t); }
 
   {
-#if 0 && HAVE_GETHRTIME
-    /* This block if if-0'd out for now because it makes shred
-       fail with an `illegal instruction' when compiled with Sun's
-       c89 on Solaris 8 and 9.  */
-    hrtime_t t = gethrtime ();
-#elif HAVE_CLOCK_GETTIME               /* POSIX ns-resolution */
-    struct timespec t;
-    clock_gettime (CLOCK_REALTIME, &t);
-#elif HAVE_GETTIMEOFDAY
-    struct timeval t;
-    gettimeofday (&t, (struct timezone *) 0);
-#else
-    time_t t = time (NULL);
-#endif
+    xtime_t t = gethrxtime ();
     ISAAC_SEED (s, t);
   }
 
Index: src/touch.c
===================================================================
RCS file: /fetish/cu/src/touch.c,v
retrieving revision 1.126
diff -p -u -r1.126 touch.c
--- src/touch.c 23 Nov 2004 20:43:47 -0000      1.126
+++ src/touch.c 21 Feb 2005 08:05:12 -0000
@@ -1,5 +1,5 @@
 /* touch -- change modification and access times of files
-   Copyright (C) 87, 1989-1991, 1995-2004 Free Software Foundation, Inc.
+   Copyright (C) 87, 1989-1991, 1995-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
@@ -39,10 +39,6 @@
 #define AUTHORS \
 "Paul Rubin", "Arnold Robbins, Jim Kingdon, David MacKenzie", "Randy Smith"
 
-#ifndef STDC_HEADERS
-time_t time ();
-#endif
-
 /* Bitmasks for `change_times'. */
 #define CH_ATIME 1
 #define CH_MTIME 2
@@ -396,8 +392,7 @@ main (int argc, char **argv)
        amtime_now = true;
       else
        {
-         if (gettime (&newtime[0]) != 0)
-           error (EXIT_FAILURE, errno, _("cannot get time of day"));
+         gettime (&newtime[0]);
          newtime[1] = newtime[0];
        }
     }




reply via email to

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