From: Dave Hart Date: Tue, 20 Sep 2011 01:32:36 +0000 (+0000) Subject: [Bug 2009] EVNT_NSET adj_systime() mishandled by Windows ntpd. X-Git-Tag: NTP_4_2_7P214~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=02ea9cfd446d88555bd4449841eb2d821610dc16;p=thirdparty%2Fntp.git [Bug 2009] EVNT_NSET adj_systime() mishandled by Windows ntpd. bk: 4e77ed340mOubTK4uXdZNY3RlM_Gaw --- diff --git a/ChangeLog b/ChangeLog index 2aa951266..5d99da973 100644 --- 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 * [Bug 1999] NMEA does not send PMOTG messages any more. (4.2.7p212) 2011/09/07 Released by Harlan Stenn diff --git a/ports/winnt/ntpd/nt_clockstuff.c b/ports/winnt/ntpd/nt_clockstuff.c index 3036e835e..e1c93dabf 100644 --- a/ports/winnt/ntpd/nt_clockstuff.c +++ b/ports/winnt/ntpd/nt_clockstuff.c @@ -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; }