+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.
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;
}
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;
}
Depends-on:
c99
intprops
+stdbool
stdckdint
timespec
Depends-on:
c99
intprops
+stdbool
stdckdint
timespec