diff options
Diffstat (limited to 'ports/winnt/ntpd/nt_clockstuff.c')
-rw-r--r-- | ports/winnt/ntpd/nt_clockstuff.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/ports/winnt/ntpd/nt_clockstuff.c b/ports/winnt/ntpd/nt_clockstuff.c index 052bfcd..dc2f150 100644 --- a/ports/winnt/ntpd/nt_clockstuff.c +++ b/ports/winnt/ntpd/nt_clockstuff.c @@ -68,8 +68,8 @@ BOOL init_randfile(); static long last_Adj = 0; #define LS_CORR_INTV_SECS 2 /* seconds to apply leap second correction */ -#define LS_CORR_INTV ( (LONGLONG) HECTONANOSECONDS * LS_CORR_INTV_SECS ) -#define LS_CORR_LIMIT ( (LONGLONG) HECTONANOSECONDS / 2 ) // half a second +#define LS_CORR_INTV ( 1000ul * LS_CORR_INTV_SECS ) +#define LS_CORR_LIMIT ( 250ul ) // quarter second typedef union ft_ull { FILETIME ft; @@ -81,8 +81,6 @@ typedef union ft_ull { /* leap second stuff */ static FT_ULL ls_ft; static DWORD ls_time_adjustment; -static ULONGLONG ls_ref_perf_cnt; -static LONGLONG ls_elapsed; static BOOL winnt_time_initialized = FALSE; static BOOL winnt_use_interpolation = FALSE; @@ -469,13 +467,15 @@ adj_systime( /* ntp time scale origin as ticks since 1601-01-01 */ static const ULONGLONG HNS_JAN_1900 = 94354848000000000ull; + static DWORD ls_start_tick; /* start of slew in 1ms ticks */ + static double adjtime_carry; double dtemp; u_char isneg; BOOL rc; long TimeAdjustment; SYSTEMTIME st; - ULONGLONG this_perf_count; + DWORD ls_elapsed; FT_ULL curr_ft; leap_result_t lsi; @@ -542,7 +542,8 @@ adj_systime( /* A leap second insert is scheduled at the end * of the day. Since we have not yet computed the * time stamp, do it now. Signal electric mode - * for this insert. + * for this insert. We start processing 1 second early + * because we want to slew over 2 seconds. */ ls_ft.ull = lsi.ttime.Q_s * HECTONANOSECONDS + HNS_JAN_1900; @@ -552,6 +553,10 @@ adj_systime( "for %04d-%02d-%02d %02d:%02d:%02d UTC", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + /* slew starts with last second before insertion! + * And we have to tell the core that we deal with it. + */ + ls_ft.ull -= (HECTONANOSECONDS + HECTONANOSECONDS/2); leapsec_electric(TRUE); } else if (lsi.tai_diff < 0) { /* Do not handle negative leap seconds here. If this @@ -574,29 +579,29 @@ adj_systime( /* * If the time stamp for the next leap second has been set - * then check if the leap second must be handled + * then check if the leap second must be handled. We use + * free-running milliseconds from 'GetTickCount()', which + * is documented as not affected by clock and/or speed + * adjustments. */ if (ls_ft.ull != 0) { - this_perf_count = perf_ctr(); - if (0 == ls_time_adjustment) { /* has not yet been scheduled */ - GetSystemTimeAsFileTime(&curr_ft.ft); if (curr_ft.ull >= ls_ft.ull) { + ls_ft.ull = _UI64_MAX; /* guard against second schedule */ ls_time_adjustment = clockperiod / LS_CORR_INTV_SECS; - ls_ref_perf_cnt = this_perf_count; - ls_elapsed = 0; - msyslog(LOG_NOTICE, "Inserting positive leap second."); + ls_start_tick = GetTickCount(); + msyslog(LOG_NOTICE, "Started leap second insertion."); } + ls_elapsed = 0; } else { /* leap sec adjustment has been scheduled previously */ - ls_elapsed = (this_perf_count - ls_ref_perf_cnt) - * HECTONANOSECONDS / PerfCtrFreq; + ls_elapsed = GetTickCount() - ls_start_tick; } if (ls_time_adjustment != 0) { /* leap second adjustment is currently active */ if (ls_elapsed > (LS_CORR_INTV - LS_CORR_LIMIT)) { ls_time_adjustment = 0; /* leap second adjustment done */ - ls_ft.ull = 0; + msyslog(LOG_NOTICE, "Finished leap second insertion."); } /* @@ -819,6 +824,10 @@ init_winnt_time(void) msyslog(LOG_INFO, "MM timer resolution: %u..%u msec, set to %u msec", tc.wPeriodMin, tc.wPeriodMax, wTimerRes ); + + /* Pause briefly before measuring the clock precision, see [Bug 2790] */ + Sleep( 33 ); + } else { msyslog(LOG_ERR, "Multimedia timer unavailable"); } |