about summary refs log tree commit diff
path: root/support/timespec.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-07-13 16:15:56 -0700
committerH.J. Lu <hjl.tools@gmail.com>2020-07-14 04:42:58 -0700
commitf896fc0f2bfc9f3f8df0563a7c99dcbf24bab655 (patch)
treec141461a47a577e88373c197e10e3c7cbf5a6caa /support/timespec.c
parent5500cdba4018ddbda7909bc7f4f9718610b43cf0 (diff)
downloadglibc-f896fc0f2bfc9f3f8df0563a7c99dcbf24bab655.tar.gz
glibc-f896fc0f2bfc9f3f8df0563a7c99dcbf24bab655.tar.xz
glibc-f896fc0f2bfc9f3f8df0563a7c99dcbf24bab655.zip
Correct timespec implementation [BZ #26232]
commit 04deeaa9ea74b0679dfc9d9155a37b6425f19a9f
Author: Lucas A. M. Magalhaes <lamm@linux.ibm.com>
Date:   Fri Jul 10 19:41:06 2020 -0300

    Fix time/tst-cpuclock1 intermitent failures

has 2 issues:

1. It assumes time_t == long which is false on x32.
2. tst-timespec.c is compiled without -fexcess-precision=standard which
generates incorrect results on i686 in support_timespec_check_in_range:

  double ratio = (double)observed_norm / expected_norm;
  return (lower_bound <= ratio && ratio <= upper_bound);

This patch does

1. Compile tst-timespec.c with -fexcess-precision=standard.
2. Replace long with time_t.
3. Replace LONG_MIN and LONG_MAX with TYPE_MINIMUM (time_t) and
TYPE_MAXIMUM (time_t).
Diffstat (limited to 'support/timespec.c')
-rw-r--r--support/timespec.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/support/timespec.c b/support/timespec.c
index 9f5449e49e..edbdb165ec 100644
--- a/support/timespec.c
+++ b/support/timespec.c
@@ -60,21 +60,17 @@ test_timespec_equal_or_after_impl (const char *file, int line,
   }
 }
 
-/* Convert TIME to nanoseconds stored in a long.
-   Returns long maximum or minimum if the conversion overflows
+/* Convert TIME to nanoseconds stored in a time_t.
+   Returns time_t maximum or minimum if the conversion overflows
    or underflows, respectively.  */
-long
+time_t
 support_timespec_ns (struct timespec time)
 {
-  long time_ns;
+  time_t time_ns;
   if (INT_MULTIPLY_WRAPV(time.tv_sec, TIMESPEC_HZ, &time_ns))
-   {
-      return (time.tv_sec < 0) ? TYPE_MINIMUM(long): TYPE_MAXIMUM(long);
-   }
+    return time.tv_sec < 0 ? TYPE_MINIMUM(time_t) : TYPE_MAXIMUM(time_t);
   if (INT_ADD_WRAPV(time_ns, time.tv_nsec, &time_ns))
-   {
-      return (time.tv_nsec < 0) ? TYPE_MINIMUM(long): TYPE_MAXIMUM(long);
-   }
+    return time.tv_nsec < 0 ? TYPE_MINIMUM(time_t) : TYPE_MAXIMUM(time_t);
   return time_ns;
 }
 
@@ -113,7 +109,7 @@ support_timespec_check_in_range (struct timespec expected, struct timespec obser
 			      double lower_bound, double upper_bound)
 {
   assert (upper_bound >= lower_bound);
-  long expected_norm, observed_norm;
+  time_t expected_norm, observed_norm;
   expected_norm = support_timespec_ns (expected);
   /* Don't divide by zero  */
   assert(expected_norm != 0);