]> Savannah Git Hosting - gnulib.git/commitdiff
timespec-add,timespec-sub: tune
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 15 Jun 2024 06:11:05 +0000 (23:11 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 15 Jun 2024 06:12:23 +0000 (23:12 -0700)
* lib/timespec-add.c (timespec_add):
* lib/timespec-sub.c (timespec_sub):
Simplify by detecting overflow when the two overflow bits of the
underlying operation differ.  This avoids some gotos and labels
and conditional branches; GCC 14 x86-64 now generates just one
conditional branch for the resulting code.  Idea stolen from
my recent changes to the glibc manual’s time chapter.
* modules/timespec-add (Depends-on):
* modules/timespec-sub (Depends-on): Add stdbool.

ChangeLog
lib/timespec-add.c
lib/timespec-sub.c
modules/timespec-add
modules/timespec-sub

index 12b392648dc88658a061f6a1b130c9025e66c089..93266c7e231794535db5dcc075a694f201ef4627 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2024-06-14  Paul Eggert  <eggert@cs.ucla.edu>
+
+       timespec-add,timespec-sub: tune
+       * lib/timespec-add.c (timespec_add):
+       * lib/timespec-sub.c (timespec_sub):
+       Simplify by detecting overflow when the two overflow bits of the
+       underlying operation differ.  This avoids some gotos and labels
+       and conditional branches; GCC 14 x86-64 now generates just one
+       conditional branch for the resulting code.  Idea stolen from
+       my recent changes to the glibc manual’s time chapter.
+       * modules/timespec-add (Depends-on):
+       * modules/timespec-sub (Depends-on): Add stdbool.
+
 2024-06-14  Collin Funk  <collin.funk1@gmail.com>
 
        gnulib-tool.py: Simplify joining paths.
index e10c19842cd0d2a2861836c3e70a0cb645ee58b2..50683187117a185b7931e2788ca0ee38e53c1e4a 100644 (file)
 struct timespec
 timespec_add (struct timespec a, struct timespec b)
 {
-  time_t rs = a.tv_sec;
-  time_t bs = b.tv_sec;
-  int ns = a.tv_nsec + b.tv_nsec;
-  int nsd = ns - TIMESPEC_HZ;
-  int rns = ns;
-
-  if (0 <= nsd)
-    {
-      rns = nsd;
-      time_t bs1;
-      if (!ckd_add (&bs1, bs, 1))
-        bs = bs1;
-      else if (rs < 0)
-        rs++;
-      else
-        goto high_overflow;
-    }
-
-  if (ckd_add (&rs, rs, bs))
+  int nssum = a.tv_nsec + b.tv_nsec;
+  int carry = TIMESPEC_HZ <= nssum;
+  time_t rs;
+  int rns;
+  bool v = ckd_add (&rs, a.tv_sec, b.tv_sec);
+  if (v == ckd_add (&rs, rs, carry))
+    rns = nssum - TIMESPEC_HZ * carry;
+  else
     {
-      if (bs < 0)
+      if ((TYPE_MINIMUM (time_t) + TYPE_MAXIMUM (time_t)) / 2 < rs)
         {
           rs = TYPE_MINIMUM (time_t);
           rns = 0;
         }
       else
         {
-        high_overflow:
           rs = TYPE_MAXIMUM (time_t);
           rns = TIMESPEC_HZ - 1;
         }
index 315cc638369825264ce1caa876417a4c23551e5a..f6d948780e4dfa9cc3a6a8c0c83a13f21ff1dad5 100644 (file)
 struct timespec
 timespec_sub (struct timespec a, struct timespec b)
 {
-  time_t rs = a.tv_sec;
-  time_t bs = b.tv_sec;
-  int ns = a.tv_nsec - b.tv_nsec;
-  int rns = ns;
-
-  if (ns < 0)
-    {
-      rns = ns + TIMESPEC_HZ;
-      time_t bs1;
-      if (!ckd_add (&bs1, bs, 1))
-        bs = bs1;
-      else if (- TYPE_SIGNED (time_t) < rs)
-        rs--;
-      else
-        goto low_overflow;
-    }
-
-  if (ckd_sub (&rs, rs, bs))
+  int nsdiff = a.tv_nsec - b.tv_nsec;
+  bool borrow = nsdiff < 0;
+  time_t rs;
+  int rns;
+  bool v = ckd_sub (&rs, a.tv_sec, b.tv_sec);
+  if (v == ckd_sub (&rs, rs, borrow))
+    rns = nsdiff + TIMESPEC_HZ * borrow;
+  else
     {
-      if (0 < bs)
+      if ((TYPE_MINIMUM (time_t) + TYPE_MAXIMUM (time_t)) / 2 < rs)
         {
-        low_overflow:
           rs = TYPE_MINIMUM (time_t);
           rns = 0;
         }
index 45daf6e26b443a0494332c3bce4bc42c795f40ff..d509f3019ee90b80272644f96ae47128191e5f09 100644 (file)
@@ -7,6 +7,7 @@ lib/timespec-add.c
 Depends-on:
 c99
 intprops
+stdbool
 stdckdint
 timespec
 
index d7316a5c9c523d5e77ac7072043b3d678860e897..1fd2309ae48b157d12e79a7475c31debe94c0894 100644 (file)
@@ -7,6 +7,7 @@ lib/timespec-sub.c
 Depends-on:
 c99
 intprops
+stdbool
 stdckdint
 timespec