[Git][NTPsec/ntpsec][master] 2 commits: Fix normalize_tspec
Eric S. Raymond
gitlab at mg.gitlab.com
Sat Mar 11 18:51:08 UTC 2017
Eric S. Raymond pushed to branch master at NTPsec / ntpsec
Commits:
65d89caf by Achim Gratz at 2017-03-11T13:50:59-05:00
Fix normalize_tspec
include/timespecops.h (normalize_tspec): Commit 'Attempt > to avoid
integer overflow warning.' disarmed the initial test by dropping a
minus sign and always ran through the normalization block even when it
was not necessary. Re-implement the normalization using ldiv library
function that should be highly optimized already, especially on modern
processors where this might be a single instruction. Unfortunately
there is no variant that does Euclidean division, so we have to fix up
the result for negative remainders ourselves.
- - - - -
c027ee95 by Achim Gratz at 2017-03-11T13:50:59-05:00
Use floor in d_to_tspec
include/timespecops.h (d_to_tspec): Use standard function floor in
d_to_tspec and also use NANOSECONDS instead of a magical constant.
Normalization is no longer necessary as the result is normalized by
construction, even for negative inputs.
- - - - -
1 changed file:
- include/timespecops.h
Changes:
=====================================
include/timespecops.h
=====================================
--- a/include/timespecops.h
+++ b/include/timespecops.h
@@ -77,25 +77,23 @@ normalize_tspec(
)
{
#if NTP_SIZEOF_LONG > 4
- long z;
-
/*
* tv_nsec is of type 'long', and on a 64-bit machine using only
* loops becomes prohibitive once the upper 32 bits get
* involved. On the other hand, division by constant should be
* fast enough; so we do a division of the nanoseconds in that
- * case. The floor adjustment step follows with the standard
- * normalisation loops. And labs() is intentionally not used
- * here: it has implementation-defined behaviour when applied
- * to LONG_MIN.
+ * case.
*/
- if (x.tv_nsec < NANOSECONDS ||
- x.tv_nsec > NANOSECONDS) {
- z = x.tv_nsec / NANOSECONDS;
- x.tv_nsec -= z * NANOSECONDS;
- x.tv_sec += z;
+ if (x.tv_nsec < 0 || x.tv_nsec >= NANOSECONDS) {
+ ldiv_t z = ldiv( x.tv_nsec, NANOSECONDS);
+ if (z.rem < 0) {
+ z.quot--;
+ z.rem += NANOSECONDS;
+ }
+ x.tv_sec += z.quot;
+ x.tv_nsec = z.rem;
}
-#endif
+#else
/* since 10**9 is close to 2**32, we don't divide but do a
* normalisation in a loop; this takes 3 steps max, and should
* outperform a division even if the mul-by-inverse trick is
@@ -110,6 +108,7 @@ normalize_tspec(
x.tv_nsec -= NANOSECONDS;
x.tv_sec++;
} while (x.tv_nsec >= NANOSECONDS);
+#endif
return x;
}
@@ -121,13 +120,11 @@ d_to_tspec(
)
{
struct timespec x;
+ double s = floor(d);
- d += 0.5e-9; /* round on LSB */
- x.tv_sec = (time_t) d;
- x.tv_nsec = (long)((d - (double)x.tv_sec) * 1e9);
-
- /* unlikely, but ensure it is normalized */
- return normalize_tspec(x);
+ x.tv_sec = (time_t) s;
+ x.tv_nsec = (long) (((d - s) * NANOSECONDS) + 0.5);
+ return x;
}
/* x = a + b */
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/bd98328999223c34c4e3be8f5b544abacfed89b0...c027ee95170456579840e85d795a1be79a4ec9d5
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20170311/57e11712/attachment.html>
More information about the vc
mailing list