about summary refs log tree commit diff
path: root/support/tst-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/tst-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/tst-timespec.c')
-rw-r--r--support/tst-timespec.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/support/tst-timespec.c b/support/tst-timespec.c
index 71423555a9..ac5ed228ba 100644
--- a/support/tst-timespec.c
+++ b/support/tst-timespec.c
@@ -19,13 +19,14 @@
 #include <support/timespec.h>
 #include <support/check.h>
 #include <limits.h>
+#include <intprops.h>
 
 #define TIMESPEC_HZ 1000000000
 
 struct timespec_ns_test_case
 {
   struct timespec time;
-  long time_ns;
+  time_t time_ns;
 };
 
 struct timespec_norm_test_case
@@ -43,6 +44,9 @@ struct timespec_test_case
   int result;
 };
 
+#define TIME_T_MIN TYPE_MINIMUM (time_t)
+#define TIME_T_MAX TYPE_MAXIMUM (time_t)
+
 /* Test cases for timespec_ns */
 struct timespec_ns_test_case ns_cases[] = {
   {.time = {.tv_sec = 0, .tv_nsec = 0},
@@ -73,36 +77,42 @@ struct timespec_ns_test_case ns_cases[] = {
    .time_ns = -TIMESPEC_HZ + 1,
   },
   /* Overflow bondary by 2  */
-  {.time = {.tv_sec = LONG_MAX / TIMESPEC_HZ, .tv_nsec = LONG_MAX%TIMESPEC_HZ - 1},
-   .time_ns = LONG_MAX - 1,
+  {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
+	    .tv_nsec = TIME_T_MAX % TIMESPEC_HZ - 1},
+   .time_ns = TIME_T_MAX - 1,
   },
   /* Overflow bondary  */
-  {.time = {.tv_sec = LONG_MAX / TIMESPEC_HZ, .tv_nsec = LONG_MAX%TIMESPEC_HZ},
-   .time_ns = LONG_MAX,
+  {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
+	    .tv_nsec = TIME_T_MAX % TIMESPEC_HZ},
+   .time_ns = TIME_T_MAX,
   },
   /* Underflow bondary by 1  */
-  {.time = {.tv_sec = LONG_MIN / TIMESPEC_HZ, .tv_nsec = LONG_MIN%TIMESPEC_HZ + 1},
-   .time_ns = LONG_MIN + 1,
+  {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ,
+	    .tv_nsec = TIME_T_MIN % TIMESPEC_HZ + 1},
+   .time_ns = TIME_T_MIN + 1,
   },
   /* Underflow bondary  */
-  {.time = {.tv_sec = LONG_MIN / TIMESPEC_HZ, .tv_nsec = LONG_MIN%TIMESPEC_HZ},
-   .time_ns = LONG_MIN,
+  {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ,
+	    .tv_nsec = TIME_T_MIN % TIMESPEC_HZ},
+   .time_ns = TIME_T_MIN,
   },
   /* Multiplication overflow  */
-  {.time = {.tv_sec = LONG_MAX / TIMESPEC_HZ + 1, .tv_nsec = 1},
-   .time_ns = LONG_MAX,
+  {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ + 1, .tv_nsec = 1},
+   .time_ns = TIME_T_MAX,
   },
   /* Multiplication underflow  */
-  {.time = {.tv_sec = LONG_MIN / TIMESPEC_HZ - 1, .tv_nsec = -1},
-   .time_ns = LONG_MIN,
+  {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ - 1, .tv_nsec = -1},
+   .time_ns = TIME_T_MIN,
   },
   /* Sum overflows  */
-  {.time = {.tv_sec = LONG_MAX / TIMESPEC_HZ, .tv_nsec = LONG_MAX%TIMESPEC_HZ + 1},
-   .time_ns = LONG_MAX,
+  {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
+	    .tv_nsec = TIME_T_MAX % TIMESPEC_HZ + 1},
+   .time_ns = TIME_T_MAX,
   },
   /* Sum underflow  */
-  {.time = {.tv_sec = LONG_MIN / TIMESPEC_HZ, .tv_nsec = LONG_MIN%TIMESPEC_HZ - 1},
-   .time_ns = LONG_MIN,
+  {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ,
+	    .tv_nsec = TIME_T_MIN % TIMESPEC_HZ - 1},
+   .time_ns = TIME_T_MIN,
   }
 };
 
@@ -144,28 +154,28 @@ struct timespec_norm_test_case norm_cases[] = {
    .norm = {.tv_sec = -2, .tv_nsec = -1}
   },
   /* Overflow bondary by 2  */
-  {.time = {.tv_sec = LONG_MAX - 2, .tv_nsec = TIMESPEC_HZ + 1},
-   .norm = {.tv_sec = LONG_MAX - 1, 1},
+  {.time = {.tv_sec = TIME_T_MAX - 2, .tv_nsec = TIMESPEC_HZ + 1},
+   .norm = {.tv_sec = TIME_T_MAX - 1, 1},
   },
   /* Overflow bondary by 1  */
-  {.time = {.tv_sec = LONG_MAX - 1, .tv_nsec = TIMESPEC_HZ + 1},
-   .norm = {.tv_sec = LONG_MAX, .tv_nsec = 1},
+  {.time = {.tv_sec = TIME_T_MAX - 1, .tv_nsec = TIMESPEC_HZ + 1},
+   .norm = {.tv_sec = TIME_T_MAX, .tv_nsec = 1},
   },
   /* Underflow bondary by 2  */
-  {.time = {.tv_sec = LONG_MIN + 2, .tv_nsec = -TIMESPEC_HZ - 1},
-   .norm = {.tv_sec = LONG_MIN + 1, -1},
+  {.time = {.tv_sec = TIME_T_MIN + 2, .tv_nsec = -TIMESPEC_HZ - 1},
+   .norm = {.tv_sec = TIME_T_MIN + 1, -1},
   },
   /* Underflow bondary by 1  */
-  {.time = {.tv_sec = LONG_MIN + 1, .tv_nsec = -TIMESPEC_HZ - 1},
-   .norm = {.tv_sec = LONG_MIN, .tv_nsec = -1},
+  {.time = {.tv_sec = TIME_T_MIN + 1, .tv_nsec = -TIMESPEC_HZ - 1},
+   .norm = {.tv_sec = TIME_T_MIN, .tv_nsec = -1},
   },
   /* SUM overflow  */
-  {.time = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ},
-   .norm = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ - 1},
+  {.time = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
+   .norm = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ - 1},
   },
   /* SUM underflow  */
-  {.time = {.tv_sec = LONG_MIN, .tv_nsec = -TIMESPEC_HZ},
-   .norm = {.tv_sec = LONG_MIN, .tv_nsec = -1 * (TIMESPEC_HZ - 1)},
+  {.time = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
+   .norm = {.tv_sec = TIME_T_MIN, .tv_nsec = -1 * (TIMESPEC_HZ - 1)},
   }
 };
 
@@ -243,39 +253,41 @@ struct timespec_test_case check_cases[] = {
   },
   /* Maximum/Minimum long values  */
   /* 14  */
-  {.expected = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ - 1},
-   .observed = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ - 2},
+  {.expected = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ - 1},
+   .observed = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ - 2},
    .upper_bound = 1, .lower_bound = .9, .result = 1,
   },
   /* 15 - support_timespec_ns overflow  */
-  {.expected = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ},
-   .observed = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ},
+  {.expected = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
+   .observed = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
    .upper_bound = 1, .lower_bound = 1, .result = 1,
   },
   /* 16 - support_timespec_ns overflow + underflow  */
-  {.expected = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ},
-   .observed = {.tv_sec = LONG_MIN, .tv_nsec = -TIMESPEC_HZ},
+  {.expected = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
+   .observed = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
    .upper_bound = 1, .lower_bound = 1, .result = 0,
   },
   /* 17 - support_timespec_ns underflow  */
-  {.expected = {.tv_sec = LONG_MIN, .tv_nsec = -TIMESPEC_HZ},
-   .observed = {.tv_sec = LONG_MIN, .tv_nsec = -TIMESPEC_HZ},
+  {.expected = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
+   .observed = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
    .upper_bound = 1, .lower_bound = 1, .result = 1,
   },
   /* 18 - support_timespec_ns underflow + overflow  */
-  {.expected = {.tv_sec = LONG_MIN, .tv_nsec = -TIMESPEC_HZ},
-   .observed = {.tv_sec = LONG_MAX, .tv_nsec = TIMESPEC_HZ},
+  {.expected = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
+   .observed = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
    .upper_bound = 1, .lower_bound = 1, .result = 0,
   },
   /* 19 - Biggest division  */
-  {.expected = {.tv_sec = LONG_MAX / TIMESPEC_HZ , .tv_nsec = TIMESPEC_HZ - 1},
+  {.expected = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
+		.tv_nsec = TIMESPEC_HZ - 1},
    .observed = {.tv_sec = 0, .tv_nsec = 1},
    .upper_bound = 1, .lower_bound = 1.0842021724855044e-19, .result = 1,
   },
   /* 20 - Lowest division  */
   {.expected = {.tv_sec = 0, .tv_nsec = 1},
-   .observed = {.tv_sec = LONG_MAX / TIMESPEC_HZ , .tv_nsec = TIMESPEC_HZ - 1},
-   .upper_bound = LONG_MAX, .lower_bound = 1, .result = 1,
+   .observed = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
+		.tv_nsec = TIMESPEC_HZ - 1},
+   .upper_bound = TIME_T_MAX, .lower_bound = 1, .result = 1,
   },
 };
 
@@ -288,6 +300,7 @@ do_test (void)
   printf("Testing support_timespec_ns\n");
   for (i = 0; i < ntests; i++)
     {
+      printf("Test case %d\n", i);
       TEST_COMPARE (support_timespec_ns (ns_cases[i].time),
 		    ns_cases[i].time_ns);
     }
@@ -297,6 +310,7 @@ do_test (void)
   printf("Testing support_timespec_normalize\n");
   for (i = 0; i < ntests; i++)
     {
+      printf("Test case %d\n", i);
       result = support_timespec_normalize (norm_cases[i].time);
       TEST_COMPARE (norm_cases[i].norm.tv_sec, result.tv_sec);
       TEST_COMPARE (norm_cases[i].norm.tv_nsec, result.tv_nsec);