From 67ce6bd279b436b16dcb182ff3da631164ab829f Mon Sep 17 00:00:00 2001 From: Bryan Christianson Date: Fri, 28 Aug 2015 23:21:01 +1200 Subject: [PATCH] sys_macosx: reset drift removal timer after spike in offset_sd When a large spike occurs in offset_sd the drift removal interval can be set to an excessively long time, although what ever event caused the perturbation has passed. At the next set_sync_status() we now compare the expected drift removal interval with that currently in effect. If they are significantly different, the current timer is cancelled and new cycle started using the new drift removal interval. --- sys_macosx.c | 54 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/sys_macosx.c b/sys_macosx.c index 503f8f1..200b62c 100644 --- a/sys_macosx.c +++ b/sys_macosx.c @@ -79,6 +79,11 @@ static double adjustment_requested; #define DRIFT_REMOVAL_INTERVAL (4.0) #define DRIFT_REMOVAL_INTERVAL_MIN (0.5) +/* If current_drift_removal_interval / drift_removal_interval exceeds this + ratio, then restart the drift removal timer */ + +#define DRIFT_REMOVAL_RESTART_RATIO (8.0) + static double drift_removal_interval; static double current_drift_removal_interval; static struct timeval Tdrift; @@ -223,27 +228,6 @@ accrue_offset(double offset, double corr_rate) /* ================================================== */ -/* use est_error to calculate the drift_removal_interval */ - -static void -set_sync_status(int synchronised, double est_error, double max_error) -{ - double interval; - - if (!synchronised) { - drift_removal_interval = MAX(drift_removal_interval, DRIFT_REMOVAL_INTERVAL); - return; - } - - interval = ERROR_WEIGHT * est_error / (fabs(current_freq) + FREQUENCY_RES); - drift_removal_interval = MAX(interval, DRIFT_REMOVAL_INTERVAL_MIN); - - DEBUG_LOG(LOGF_SysMacOSX, "est_error: %.3f current_freq: %.3f est drift_removal_interval: %.3f act drift_removal_interval: %.3f", - est_error * 1.0e6, current_freq * 1.0e6, interval, drift_removal_interval); -} - -/* ================================================== */ - /* Positive offset means system clock is fast of true time, therefore step backwards */ @@ -340,6 +324,34 @@ drift_removal_timeout(SCH_ArbitraryArgument not_used) drift_removal_id = SCH_AddTimeoutByDelay(drift_removal_interval, drift_removal_timeout, NULL); } +/* ================================================== */ + +/* use est_error to calculate the drift_removal_interval */ + +static void +set_sync_status(int synchronised, double est_error, double max_error) +{ + double interval; + + if (!synchronised) { + drift_removal_interval = MAX(drift_removal_interval, DRIFT_REMOVAL_INTERVAL); + } else { + interval = ERROR_WEIGHT * est_error / (fabs(current_freq) + FREQUENCY_RES); + drift_removal_interval = MAX(interval, DRIFT_REMOVAL_INTERVAL_MIN); + + DEBUG_LOG(LOGF_SysMacOSX, "est_error: %.3f current_freq: %.3f est drift_removal_interval: %.3f act drift_removal_interval: %.3f", + est_error * 1.0e6, current_freq * 1.0e6, interval, drift_removal_interval); + } + + if (current_drift_removal_interval / drift_removal_interval > DRIFT_REMOVAL_RESTART_RATIO) { + /* recover from a large est_error by resetting the timer */ + SCH_ArbitraryArgument unused; + SCH_RemoveTimeout(drift_removal_id); + unused = NULL; + drift_removal_timeout(unused); + } +} + /* ================================================== */ /* Give chronyd real time priority so that time critical calculations