]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - support/timespec-sub.c
Fix time/tst-cpuclock1 intermitent failures
[thirdparty/glibc.git] / support / timespec-sub.c
index bf95c7f80de08242b7dc349c5cf4d1a6d2939acd..a1d1a8df92a51d812f4ad4425a13ae9ae7247cb9 100644 (file)
@@ -1,5 +1,5 @@
 /* Subtract two struct timespec values.
-   Copyright (C) 2011-2019 Free Software Foundation, Inc.
+   Copyright (C) 2011-2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library and is also part of gnulib.
    Patches to this file should be submitted to both projects.
 
@@ -15,7 +15,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+   <https://www.gnu.org/licenses/>.  */
 
 /* Return the difference between two timespec values A and B.  On
    overflow, return an extremal value.  This assumes 0 <= tv_nsec <
@@ -33,36 +33,30 @@ timespec_sub (struct timespec a, struct timespec b)
   time_t bs = b.tv_sec;
   int ns = a.tv_nsec - b.tv_nsec;
   int rns = ns;
-  time_t tmin = TYPE_MINIMUM (time_t);
-  time_t tmax = TYPE_MAXIMUM (time_t);
 
   if (ns < 0)
     {
       rns = ns + TIMESPEC_HZ;
-      if (bs < tmax)
-        bs++;
+      time_t bs1;
+      if (!INT_ADD_WRAPV (bs, 1, &bs1))
+        bs = bs1;
       else if (- TYPE_SIGNED (time_t) < rs)
         rs--;
       else
         goto low_overflow;
     }
 
-  /* INT_SUBTRACT_WRAPV is not appropriate since time_t might be unsigned.
-     In theory time_t might be narrower than int, so plain
-     INT_SUBTRACT_OVERFLOW does not suffice.  */
-  if (! INT_SUBTRACT_OVERFLOW (rs, bs) && tmin <= rs - bs && rs - bs <= tmax)
-    rs -= bs;
-  else
+  if (INT_SUBTRACT_WRAPV (rs, bs, &rs))
     {
-      if (rs < 0)
+      if (0 < bs)
         {
         low_overflow:
-          rs = tmin;
+          rs = TYPE_MINIMUM (time_t);
           rns = 0;
         }
       else
         {
-          rs = tmax;
+          rs = TYPE_MAXIMUM (time_t);
           rns = TIMESPEC_HZ - 1;
         }
     }