changeset 39833:4c9d0c898076

timespec: fix resolution confusion In normal usage, clock resolution is given in seconds, but the code was mistakenly using inverse seconds and calling it “resolution”. Fix this, partly by renaming two identifiers. The old names will be kept for a bit, to ease transition. * lib/timespec.h (TIMESPEC_HZ, LOG10_TIMESPEC_HZ): New constants, replacing TIMESPEC_RESOLUTION and LOG10_TIMESPEC_RESOLUTION, which are now obsolescent. All uses changed.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 10 Sep 2018 18:42:25 -0700
parents 8228a72f9f50
children d5a1b82291f0
files ChangeLog doc/posix-functions/futimens.texi doc/posix-functions/utimensat.texi lib/dtotimespec.c lib/stat-time.h lib/timespec-add.c lib/timespec-sub.c lib/timespec.h lib/utimens.c lib/utimensat.c tests/test-futimens.h tests/test-timespec.c tests/test-utimens.h
diffstat 13 files changed, 62 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Sep 09 08:56:15 2018 -0700
+++ b/ChangeLog	Mon Sep 10 18:42:25 2018 -0700
@@ -1,3 +1,15 @@
+2018-09-10  Paul Eggert  <eggert@cs.ucla.edu>
+
+	timespec: fix resolution confusion
+	In normal usage, clock resolution is given in seconds, but the
+	code was mistakenly using inverse seconds and calling it
+	“resolution”.  Fix this, partly by renaming two identifiers.
+	The old names will be kept for a bit, to ease transition.
+	* lib/timespec.h (TIMESPEC_HZ, LOG10_TIMESPEC_HZ):
+	New constants, replacing TIMESPEC_RESOLUTION and
+	LOG10_TIMESPEC_RESOLUTION, which are now obsolescent.
+	All uses changed.
+
 2018-09-09  Paul Eggert  <eggert@cs.ucla.edu>
 
 	mktime: simplify in prep for glibc merge
--- a/doc/posix-functions/futimens.texi	Sun Sep 09 08:56:15 2018 -0700
+++ b/doc/posix-functions/futimens.texi	Mon Sep 10 18:42:25 2018 -0700
@@ -12,7 +12,7 @@
 This function is missing on some platforms:
 glibc 2.3.6, Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.3.
 However, the replacement function may end up truncating timestamps to
-less resolution than supported by the file system.
+worse resolution than supported by the file system.
 @item
 This function returns a bogus value instead of failing with
 @code{ENOSYS} on some platforms:
--- a/doc/posix-functions/utimensat.texi	Sun Sep 09 08:56:15 2018 -0700
+++ b/doc/posix-functions/utimensat.texi	Mon Sep 10 18:42:25 2018 -0700
@@ -12,7 +12,7 @@
 This function is missing on some platforms:
 glibc 2.3.6, Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x, mingw, MSVC 14, Interix 3.5, BeOS, Android 3.0.
 However, the replacement function may end up truncating timestamps to
-less resolution than supported by the file system.  Furthermore, the
+worse resolution than supported by the file system.  Furthermore, the
 replacement function is not safe to be used in libraries and is not
 multithread-safe.
 @item
--- a/lib/dtotimespec.c	Sun Sep 09 08:56:15 2018 -0700
+++ b/lib/dtotimespec.c	Mon Sep 10 18:42:25 2018 -0700
@@ -32,20 +32,20 @@
   if (! (TYPE_MINIMUM (time_t) < sec))
     return make_timespec (TYPE_MINIMUM (time_t), 0);
   else if (! (sec < 1.0 + TYPE_MAXIMUM (time_t)))
-    return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_RESOLUTION - 1);
+    return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1);
   else
     {
       time_t s = sec;
-      double frac = TIMESPEC_RESOLUTION * (sec - s);
+      double frac = TIMESPEC_HZ * (sec - s);
       long ns = frac;
       ns += ns < frac;
-      s += ns / TIMESPEC_RESOLUTION;
-      ns %= TIMESPEC_RESOLUTION;
+      s += ns / TIMESPEC_HZ;
+      ns %= TIMESPEC_HZ;
 
       if (ns < 0)
         {
           s--;
-          ns += TIMESPEC_RESOLUTION;
+          ns += TIMESPEC_HZ;
         }
 
       return make_timespec (s, ns);
--- a/lib/stat-time.h	Sun Sep 09 08:56:15 2018 -0700
+++ b/lib/stat-time.h	Mon Sep 10 18:42:25 2018 -0700
@@ -213,7 +213,7 @@
 #if defined __sun && defined STAT_TIMESPEC
   if (result == 0)
     {
-      long int timespec_resolution = 1000000000;
+      long int timespec_hz = 1000000000;
       short int const ts_off[] = { offsetof (struct stat, st_atim),
                                    offsetof (struct stat, st_mtim),
                                    offsetof (struct stat, st_ctim) };
@@ -221,11 +221,11 @@
       for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++)
         {
           struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]);
-          long int q = ts->tv_nsec / timespec_resolution;
-          long int r = ts->tv_nsec % timespec_resolution;
+          long int q = ts->tv_nsec / timespec_hz;
+          long int r = ts->tv_nsec % timespec_hz;
           if (r < 0)
             {
-              r += timespec_resolution;
+              r += timespec_hz;
               q--;
             }
           ts->tv_nsec = r;
--- a/lib/timespec-add.c	Sun Sep 09 08:56:15 2018 -0700
+++ b/lib/timespec-add.c	Mon Sep 10 18:42:25 2018 -0700
@@ -18,7 +18,7 @@
 /* Written by Paul Eggert.  */
 
 /* Return the sum of two timespec values A and B.  On overflow, return
-   an extremal value.  This assumes 0 <= tv_nsec < TIMESPEC_RESOLUTION.  */
+   an extremal value.  This assumes 0 <= tv_nsec < TIMESPEC_HZ.  */
 
 #include <config.h>
 #include "timespec.h"
@@ -31,7 +31,7 @@
   time_t rs = a.tv_sec;
   time_t bs = b.tv_sec;
   int ns = a.tv_nsec + b.tv_nsec;
-  int nsd = ns - TIMESPEC_RESOLUTION;
+  int nsd = ns - TIMESPEC_HZ;
   int rns = ns;
   time_t tmin = TYPE_MINIMUM (time_t);
   time_t tmax = TYPE_MAXIMUM (time_t);
@@ -63,7 +63,7 @@
         {
         high_overflow:
           rs = tmax;
-          rns = TIMESPEC_RESOLUTION - 1;
+          rns = TIMESPEC_HZ - 1;
         }
     }
 
--- a/lib/timespec-sub.c	Sun Sep 09 08:56:15 2018 -0700
+++ b/lib/timespec-sub.c	Mon Sep 10 18:42:25 2018 -0700
@@ -19,7 +19,7 @@
 
 /* Return the difference between two timespec values A and B.  On
    overflow, return an extremal value.  This assumes 0 <= tv_nsec <
-   TIMESPEC_RESOLUTION.  */
+   TIMESPEC_HZ.  */
 
 #include <config.h>
 #include "timespec.h"
@@ -38,7 +38,7 @@
 
   if (ns < 0)
     {
-      rns = ns + TIMESPEC_RESOLUTION;
+      rns = ns + TIMESPEC_HZ;
       if (bs < tmax)
         bs++;
       else if (- TYPE_SIGNED (time_t) < rs)
@@ -63,7 +63,7 @@
       else
         {
           rs = tmax;
-          rns = TIMESPEC_RESOLUTION - 1;
+          rns = TIMESPEC_HZ - 1;
         }
     }
 
--- a/lib/timespec.h	Sun Sep 09 08:56:15 2018 -0700
+++ b/lib/timespec.h	Mon Sep 10 18:42:25 2018 -0700
@@ -35,11 +35,17 @@
 
 #include "verify.h"
 
-/* Resolution of timespec timestamps (in units per second), and log
-   base 10 of the resolution.  */
+/* Inverse resolution of timespec timestamps (in units per second),
+   and log base 10 of the inverse resolution.  */
+
+enum { TIMESPEC_HZ = 1000000000 };
+enum { LOG10_TIMESPEC_HZ = 9 };
 
-enum { TIMESPEC_RESOLUTION = 1000000000 };
-enum { LOG10_TIMESPEC_RESOLUTION = 9 };
+/* Obsolescent names for backward compatibility.
+   They are misnomers, because TIMESPEC_RESOLUTION is not a resolution.  */
+
+enum { TIMESPEC_RESOLUTION = TIMESPEC_HZ };
+enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ };
 
 /* Return a timespec with seconds S and nanoseconds NS.  */
 
@@ -88,8 +94,8 @@
 
   /* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02).  See:
      https://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html  */
-  assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
-  assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
+  assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_HZ);
+  assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_HZ);
 
   return a.tv_nsec - b.tv_nsec;
 }
--- a/lib/utimens.c	Sun Sep 09 08:56:15 2018 -0700
+++ b/lib/utimens.c	Mon Sep 10 18:42:25 2018 -0700
@@ -91,11 +91,11 @@
   if ((timespec[0].tv_nsec != UTIME_NOW
        && timespec[0].tv_nsec != UTIME_OMIT
        && ! (0 <= timespec[0].tv_nsec
-             && timespec[0].tv_nsec < TIMESPEC_RESOLUTION))
+             && timespec[0].tv_nsec < TIMESPEC_HZ))
       || (timespec[1].tv_nsec != UTIME_NOW
           && timespec[1].tv_nsec != UTIME_OMIT
           && ! (0 <= timespec[1].tv_nsec
-                && timespec[1].tv_nsec < TIMESPEC_RESOLUTION)))
+                && timespec[1].tv_nsec < TIMESPEC_HZ)))
     {
       errno = EINVAL;
       return -1;
--- a/lib/utimensat.c	Sun Sep 09 08:56:15 2018 -0700
+++ b/lib/utimensat.c	Mon Sep 10 18:42:25 2018 -0700
@@ -94,10 +94,10 @@
       else if (times
                && ((times[0].tv_nsec != UTIME_NOW
                     && ! (0 <= times[0].tv_nsec
-                          && times[0].tv_nsec < TIMESPEC_RESOLUTION))
+                          && times[0].tv_nsec < TIMESPEC_HZ))
                    || (times[1].tv_nsec != UTIME_NOW
                        && ! (0 <= times[1].tv_nsec
-                             && times[1].tv_nsec < TIMESPEC_RESOLUTION))))
+                             && times[1].tv_nsec < TIMESPEC_HZ))))
         {
           errno = EINVAL;
           return -1;
--- a/tests/test-futimens.h	Sun Sep 09 08:56:15 2018 -0700
+++ b/tests/test-futimens.h	Mon Sep 10 18:42:25 2018 -0700
@@ -47,7 +47,7 @@
     }
   ASSERT (!result);
   ASSERT (fstat (fd, &st2) == 0);
-  /* If utimens truncates to less resolution than the file system
+  /* If utimens truncates to worse resolution than the file system
      supports, then time can appear to go backwards between now and a
      follow-up utimens with UTIME_NOW or a NULL timespec.  Use
      UTIMECMP_TRUNCATE_SOURCE to compensate, with st1 as the
--- a/tests/test-timespec.c	Sun Sep 09 08:56:15 2018 -0700
+++ b/tests/test-timespec.c	Mon Sep 10 18:42:25 2018 -0700
@@ -30,36 +30,36 @@
   {
     { INT_MIN, 0 },
     { INT_MIN, 1 },
-    { INT_MIN, TIMESPEC_RESOLUTION - 1 },
+    { INT_MIN, TIMESPEC_HZ - 1 },
     { INT_MIN + 1, 0 },
     { INT_MIN + 1, 1 },
-    { INT_MIN + 1, TIMESPEC_RESOLUTION - 1 },
+    { INT_MIN + 1, TIMESPEC_HZ - 1 },
     { -1, 0 },
     { -1, 1 },
-    { -1, TIMESPEC_RESOLUTION - 1 },
+    { -1, TIMESPEC_HZ - 1 },
     { 0, 0 },
     { 0, 1 },
-    { 0, TIMESPEC_RESOLUTION - 1 },
+    { 0, TIMESPEC_HZ - 1 },
     { 1, 0 },
     { 1, 1 },
-    { 1, TIMESPEC_RESOLUTION - 1 },
+    { 1, TIMESPEC_HZ - 1 },
     { 1234567890, 0 },
     { 1234567890, 1 },
-    { 1234567890, TIMESPEC_RESOLUTION - 1 },
+    { 1234567890, TIMESPEC_HZ - 1 },
     { INT_MAX - 1, 0 },
     { INT_MAX - 1, 1 },
-    { INT_MAX - 1, TIMESPEC_RESOLUTION - 1 },
+    { INT_MAX - 1, TIMESPEC_HZ - 1 },
     { INT_MAX, 0 },
     { INT_MAX, 1 },
-    { INT_MAX, TIMESPEC_RESOLUTION - 1 },
-    { INT_MAX, 2 * TIMESPEC_RESOLUTION }
+    { INT_MAX, TIMESPEC_HZ - 1 },
+    { INT_MAX, 2 * TIMESPEC_HZ }
   };
 enum { nprototypes = sizeof prototype / sizeof *prototype };
 
 static bool
 valid (struct timespec a)
 {
-  return 0 <= a.tv_nsec && a.tv_nsec < TIMESPEC_RESOLUTION;
+  return 0 <= a.tv_nsec && a.tv_nsec < TIMESPEC_HZ;
 }
 
 static int
@@ -85,7 +85,7 @@
 {
   return ((a.tv_sec == TYPE_MINIMUM (time_t) && a.tv_nsec == 0)
           || (a.tv_sec == TYPE_MAXIMUM (time_t)
-              && a.tv_nsec == TIMESPEC_RESOLUTION - 1));
+              && a.tv_nsec == TIMESPEC_HZ - 1));
 }
 
 int
@@ -94,7 +94,7 @@
   int i, j, k;
   struct timespec test[nprototypes + 1];
   int ntests;
-  int computed_resolution = 1;
+  int computed_hz = 1;
   struct timespec prevroundtrip;
 
   test[0] = make_timespec (TYPE_MINIMUM (time_t), -1);
@@ -111,9 +111,9 @@
         }
     }
 
-  for (i = 0; i < LOG10_TIMESPEC_RESOLUTION; i++)
-    computed_resolution *= 10;
-  ASSERT (computed_resolution == TIMESPEC_RESOLUTION);
+  for (i = 0; i < LOG10_TIMESPEC_HZ; i++)
+    computed_hz *= 10;
+  ASSERT (computed_hz == TIMESPEC_HZ);
 
   for (i = 0; i < ntests; i++)
     {
--- a/tests/test-utimens.h	Sun Sep 09 08:56:15 2018 -0700
+++ b/tests/test-utimens.h	Mon Sep 10 18:42:25 2018 -0700
@@ -27,7 +27,7 @@
   struct stat st2;
 
   ASSERT (close (creat (BASE "file", 0600)) == 0);
-  /* If utimens truncates to less resolution than the file system
+  /* If utimens truncates to worse resolution than the file system
      supports, then time can appear to go backwards between now and a
      follow-up utimens with UTIME_NOW or a NULL timespec.  Use
      UTIMECMP_TRUNCATE_SOURCE to compensate, with st1 as the