[ntpsec commit] Change ntp_set_tod() to take a timespec, increasing time-setting precision.

Eric S. Raymond esr at ntpsec.org
Fri Oct 9 04:01:30 UTC 2015


Module:    ntpsec
Branch:    master
Commit:    fa16c45ffa82507efcc92a7345e2aa94a641053c
Changeset: http://git.ntpsec.org/ntpsec/commit/?id=fa16c45ffa82507efcc92a7345e2aa94a641053c

Author:    Eric S. Raymond <esr at thyrsus.com>
Date:      Thu Oct  8 23:36:13 2015 -0400

Change ntp_set_tod() to take a timespec, increasing time-setting precision.

This is potentially a big deal for platforms with a POSIX-conformant
clock_settime(2) that takes a timespec.  Before, when a time step
was calculated, it was always rounded to microseconds to be passed to
settimeofday(2).  Now, precision down to nanoseconds is passed through
ntp_set_tod() to be used by clock_settime(2) if the platform has it,
for a potential gain of up to 10**3 in stepping accuracy.

Today few time sources actually deliver with that accuracy, but it is
reasonable to expect lesser gains to the exact extent that
clock_gettime(2) and primary time sources are capable of delivering
sub-microsecond accuracy - in particular for GPSDOs, which often
deliver in the 100ns range, and dedicated time receivers which may
reach 50ns accuracy.

We may thus expect an order of magnitude or more accuracy improvement
from this change with real hardware.

---

 include/ntp_machine.h              |  2 +-
 libntp/machines.c                  | 15 ++++++---------
 libntp/systime.c                   |  6 ++----
 ports/winnt/libntp/SetSystemTime.c |  4 ++--
 4 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/include/ntp_machine.h b/include/ntp_machine.h
index 9f869bd..7f23dd4 100644
--- a/include/ntp_machine.h
+++ b/include/ntp_machine.h
@@ -15,7 +15,7 @@
 
 #include "ntp_proto.h"
 
-int ntp_set_tod (struct timeval *tvp, void *tzp);
+int ntp_set_tod (struct timespec *tvs, void *tzp);
 
 #ifdef NO_MAIN_ALLOWED
 /* we have no main routines so lets make a plan */
diff --git a/libntp/machines.c b/libntp/machines.c
index 18c2a6c..5e0681b 100644
--- a/libntp/machines.c
+++ b/libntp/machines.c
@@ -57,7 +57,7 @@ pset_tod_using	set_tod_using = NULL;
 
 int
 ntp_set_tod(
-	struct timeval *tvp,
+	struct timespec *tvs,
 	void *tzp
 	)
 {
@@ -71,14 +71,8 @@ ntp_set_tod(
 
 #ifdef HAVE_CLOCK_SETTIME
 	if (rc && (SET_TOD_CLOCK_SETTIME == tod || !tod)) {
-		struct timespec ts;
-
-		/* Convert timeval to timespec */
-		ts.tv_sec = tvp->tv_sec;
-		ts.tv_nsec = 1000 *  tvp->tv_usec;
-
 		errno = 0;
-		rc = clock_settime(CLOCK_REALTIME, &ts);
+		rc = clock_settime(CLOCK_REALTIME, tvs);
 		saved_errno = errno;
 		TRACE(1, ("ntp_set_tod: clock_settime: %d %m\n", rc));
 		if (!tod && !rc)
@@ -97,7 +91,10 @@ ntp_set_tod(
 		adjtv.tv_sec = adjtv.tv_usec = 0;
 		adjtime(&adjtv, NULL);
 		errno = 0;
-		rc = settimeofday(tvp, tzp);
+
+		adjtv.tv_sec = tvs->tv_sec;
+		adjtv.tv_usec = (tvs->tv_nsec + 500) / 1000;
+		rc = settimeofday(&adjtv, tzp);
 		saved_errno = errno;
 		TRACE(1, ("ntp_set_tod: settimeofday: %d %m\n", rc));
 		if (!tod && !rc)
diff --git a/libntp/systime.c b/libntp/systime.c
index 14f8e21..ea7dc78 100644
--- a/libntp/systime.c
+++ b/libntp/systime.c
@@ -455,17 +455,15 @@ step_systime(
 	/* get the current time as l_fp (without fuzz) and as struct timeval */
 	get_ostime(&timets);
 	fp_sys = tspec_stamp_to_lfp(timets);
-	tvlast.tv_sec = timets.tv_sec;
-	tvlast.tv_usec = (timets.tv_nsec + 500) / 1000;
 
 	/* get the target time as l_fp */
 	L_ADD(&fp_sys, &fp_ofs);
 
 	/* unfold the new system time */
-	timetv = lfp_stamp_to_tval(fp_sys, &pivot);
+	timets = lfp_stamp_to_tspec(fp_sys, &pivot);
 
 	/* now set new system time */
-	if (ntp_set_tod(&timetv, NULL) != 0) {
+	if (ntp_set_tod(&timets, NULL) != 0) {
 		msyslog(LOG_ERR, "step-systime: %m");
 		return false;
 	}
diff --git a/ports/winnt/libntp/SetSystemTime.c b/ports/winnt/libntp/SetSystemTime.c
index 8cb4317..0be4ea4 100644
--- a/ports/winnt/libntp/SetSystemTime.c
+++ b/ports/winnt/libntp/SetSystemTime.c
@@ -9,7 +9,7 @@ pset_tod_using		set_tod_using = NULL;
 
 int
 ntp_set_tod(
-	struct timeval *tv,
+	struct timespec *tp,
 	void *tzp
 	)
 {
@@ -23,7 +23,7 @@ ntp_set_tod(
 
 	t.ull = FILETIME_1970 +
 		(ULONGLONG)tv->tv_sec * 10 * 1000 * 1000 +
-		(ULONGLONG)tv->tv_usec * 10;
+		(ULONGLONG)tv->tv_nsec / 100;
 
 	if (!FileTimeToSystemTime(&t.ft, &st) || !SetSystemTime(&st)) {
 		msyslog(LOG_ERR, "SetSystemTime failed: %m");



More information about the vc mailing list