]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2009] EVNT_NSET adj_systime() mishandled by Windows ntpd.
authorDave Hart <hart@ntp.org>
Tue, 20 Sep 2011 01:32:36 +0000 (01:32 +0000)
committerDave Hart <hart@ntp.org>
Tue, 20 Sep 2011 01:32:36 +0000 (01:32 +0000)
bk: 4e77ed340mOubTK4uXdZNY3RlM_Gaw

ChangeLog
ports/winnt/ntpd/nt_clockstuff.c

index 2aa951266e4fcd96594dfa25b6e1fe91acba5b5d..5d99da9738036377dc44472e7d4a03a5a107059e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 * [Bug 1981] Initial offset convergence applies frequency correction 2x
   with kernel discipline.
 * [Bug 2008] Initial offset convergence degraded with 500 PPM adjtime().
+* [Bug 2009] EVNT_NSET adj_systime() mishandled by Windows ntpd.
 (4.2.7p213) 2011/09/08 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 1999] NMEA does not send PMOTG messages any more.
 (4.2.7p212) 2011/09/07 Released by Harlan Stenn <stenn@ntp.org>
index 3036e835e1ffd92b3ea2bb1cf0a1fa6f35c58d2a..e1c93dabf9c76882df2f31cacff6e65b0e52108d 100644 (file)
@@ -406,7 +406,14 @@ set_mm_timer(
 }
 
 /*
- * adj_systime - called once every second to make system time adjustments.
+ * adj_systime - called once every second to discipline system clock.
+ * Normally, the offset passed in (parameter now) is in the range
+ * [-NTP_MAXFREQ, NTP_MAXFREQ].  However, at EVNT_NSET, a much larger
+ * slew is requested if the initial offset is less than the step
+ * threshold, in the range [-step, step] where step is the step
+ * threshold, 128 msec by default.  For the remainder of the frequency
+ * training interval, adj_systime is called with 0 offset each second
+ * and slew the large offset at 500 PPM (500 usec/sec).
  * Returns 1 if okay, 0 if trouble.
  */
 int
@@ -414,20 +421,22 @@ adj_systime(
        double now
        )
 {
-       double dtemp;
-       u_char isneg;
-       BOOL rc;
-       long TimeAdjustment;
-       SYSTEMTIME st;
-       ULONGLONG this_perf_count;
-       FT_ULL curr_ft;
+       static double   adjtime_carry;
+       double          dtemp;
+       u_char          isneg;
+       BOOL            rc;
+       long            TimeAdjustment;
+       SYSTEMTIME      st;
+       ULONGLONG       this_perf_count;
+       FT_ULL          curr_ft;
 
        /*
         * Add the residual from the previous adjustment to the new
         * adjustment, bound and round.
         */
-       dtemp = sys_residual + now;
-       sys_residual = 0;
+       dtemp = adjtime_carry + sys_residual + now;
+       adjtime_carry = 0.;
+       sys_residual = 0.;
        if (dtemp < 0) {
                isneg = TRUE;
                dtemp = -dtemp;
@@ -435,13 +444,17 @@ adj_systime(
                isneg = FALSE;
        }
 
-       if (dtemp > NTP_MAXFREQ)
+       if (dtemp > NTP_MAXFREQ) {
+               adjtime_carry = dtemp - NTP_MAXFREQ;
                dtemp = NTP_MAXFREQ;
+       }
 
-       dtemp = dtemp * 1e6;
-
-       if (isneg)
+       if (isneg) {
                dtemp = -dtemp;
+               adjtime_carry = -adjtime_carry;
+       }
+
+       dtemp = dtemp * 1e6;
 
        /* 
         * dtemp is in micro seconds. NT uses 100 ns units,
@@ -545,11 +558,16 @@ adj_systime(
        }
 
 
+       sys_residual = dtemp / 1e6;
+       DPRINTF(3, ("adj_systime: %.9f -> %.9f residual %.9f adjtime %.9f\n", 
+                   now, 1e-6 * (TimeAdjustment * ppm_per_adjust_unit),
+                   sys_residual, adjtime_carry));
+
        /* only adjust the clock if adjustment changes */
        TimeAdjustment += wintickadj;
        if (last_Adj != TimeAdjustment) {
                last_Adj = TimeAdjustment;
-               DPRINTF(1, ("SetSystemTimeAdjustment(%+ld)\n", TimeAdjustment));
+               DPRINTF(2, ("SetSystemTimeAdjustment(%+ld)\n", TimeAdjustment));
                rc = !SetSystemTimeAdjustment(clockperiod + TimeAdjustment, FALSE);
        } else {
                rc = FALSE;
@@ -559,10 +577,6 @@ adj_systime(
                return FALSE;
        }
 
-       sys_residual = dtemp / 1e6;
-       DPRINTF(4, ("adj_systime: adj %.9f -> remaining residual %.9f\n", 
-                   now, sys_residual));
-
        return TRUE;
 }