]> Savannah Git Hosting - gnulib.git/commitdiff
gettime-res: more-robust sampling
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 20 Apr 2022 17:42:51 +0000 (10:42 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 20 Apr 2022 17:44:25 +0000 (10:44 -0700)
* lib/gettime-res.c (gettime_res): If adjacent timestamps are
identical search for a differing timestamp.  Also, stop collecting
samples thereafter since they surely won’t help.

ChangeLog
lib/gettime-res.c

index fee51331c89f1c961ce96b17058ca466bd800ea6..4b39a6a4437840ec8269fe0e84afeef093fa8eac 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2022-04-20  Paul Eggert  <eggert@cs.ucla.edu>
+
+       gettime-res: more-robust sampling
+       * lib/gettime-res.c (gettime_res): If adjacent timestamps are
+       identical search for a differing timestamp.  Also, stop collecting
+       samples thereafter since they surely won’t help.
+
 2022-04-19  Paul Eggert  <eggert@cs.ucla.edu>
 
        Port _GL_HAS_C_ATTRIBUTE to pedantic gcc -std=c99
index 611f83ad27a77a725d31be367908b13ed7b0a68a..bb4d0b191d72f69978177242f9c01dda25244f93 100644 (file)
@@ -53,6 +53,8 @@ gettime_res (void)
 
   long int hz = TIMESPEC_HZ;
   long int r = hz * res.tv_sec + res.tv_nsec;
+  struct timespec earlier;
+  earlier.tv_nsec = -1;
 
   /* On some platforms, clock_getres (CLOCK_REALTIME, ...) yields a
      too-large resolution, under the mistaken theory that it should
@@ -61,9 +63,22 @@ gettime_res (void)
      resolution.  Work around the problem with high probability by
      trying clock_gettime several times and observing the resulting
      bounds on resolution.  */
-  for (int i = 0; 1 < r && i < 32; i++)
+  int nsamples = 32;
+  for (int i = 0; 1 < r && i < nsamples; i++)
     {
-      struct timespec now = current_timespec ();
+      /* If successive timestamps disagree the clock resolution must
+         be small, so exit the inner loop to check this sample.
+         Otherwise, arrange for the outer loop to exit but continue
+         the inner-loop search for a differing timestamp sample.  */
+      struct timespec now;
+      for (;; i = nsamples)
+        {
+          now = current_timespec ();
+          if (earlier.tv_nsec != now.tv_nsec || earlier.tv_sec != now.tv_sec)
+            break;
+        }
+      earlier = now;
+
       r = gcd (r, now.tv_nsec ? now.tv_nsec : hz);
     }