[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