From 6dc5c1be733cbfbcecaa44ceab070ea4724a1ba0 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 20 Apr 2022 10:42:51 -0700 Subject: [PATCH] gettime-res: more-robust sampling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 | 7 +++++++ lib/gettime-res.c | 19 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fee51331c8..4b39a6a443 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2022-04-20 Paul Eggert + + 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 Port _GL_HAS_C_ATTRIBUTE to pedantic gcc -std=c99 diff --git a/lib/gettime-res.c b/lib/gettime-res.c index 611f83ad27..bb4d0b191d 100644 --- a/lib/gettime-res.c +++ b/lib/gettime-res.c @@ -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); } -- 2.35.1