From b6a27df5b9be0f07f151c8fba311cb7eadb2b13e Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 12 Aug 2015 15:48:13 +0200 Subject: [PATCH] sys: include predicted drift in adjtime() offset In drivers with periodic drift removal include in the adjustment also a prediction of the error gained in half of the interval to move the mean offset of the clock closer to zero. E.g. offset of a stable clock drifting by 10 ppm should now be closer to 0 +/- 5 microseconds instead of 5 +/- 5 microseconds. --- sys_macosx.c | 7 ++++--- sys_solaris.c | 7 ++++--- sys_sunos.c | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/sys_macosx.c b/sys_macosx.c index 4db6a0c..5d7c1d5 100644 --- a/sys_macosx.c +++ b/sys_macosx.c @@ -108,7 +108,7 @@ start_adjust(void) { struct timeval newadj, oldadj; struct timeval T1; - double elapsed, accrued_error; + double elapsed, accrued_error, predicted_error; double adjust_required; double rounding_error; double old_adjust_remaining; @@ -120,8 +120,9 @@ start_adjust(void) UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); accrued_error = elapsed * current_freq; + predicted_error = DRIFT_REMOVAL_INTERVAL / 2.0 * current_freq; - adjust_required = - (accrued_error + offset_register); + adjust_required = - (accrued_error + offset_register + predicted_error); UTI_DoubleToTimeval(adjust_required, &newadj); UTI_TimevalToDouble(&newadj, &adjustment_requested); @@ -133,7 +134,7 @@ start_adjust(void) UTI_TimevalToDouble(&oldadj, &old_adjust_remaining); - offset_register = rounding_error - old_adjust_remaining; + offset_register = rounding_error - old_adjust_remaining - predicted_error; T0 = T1; } diff --git a/sys_solaris.c b/sys_solaris.c index fe8b63a..6c018ee 100644 --- a/sys_solaris.c +++ b/sys_solaris.c @@ -127,7 +127,7 @@ start_adjust(void) { struct timeval newadj, oldadj; struct timeval T1; - double elapsed, accrued_error; + double elapsed, accrued_error, predicted_error; double adjust_required; struct timeval exact_newadj; double rounding_error; @@ -140,8 +140,9 @@ start_adjust(void) UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); accrued_error = elapsed * current_freq; + predicted_error = DRIFT_REMOVAL_INTERVAL / 2.0 * current_freq; - adjust_required = - (accrued_error + offset_register); + adjust_required = - (accrued_error + offset_register + predicted_error); UTI_DoubleToTimeval(adjust_required, &exact_newadj); @@ -160,7 +161,7 @@ start_adjust(void) UTI_TimevalToDouble(&oldadj, &old_adjust_remaining); - offset_register = rounding_error - old_adjust_remaining; + offset_register = rounding_error - old_adjust_remaining - predicted_error; T0 = T1; UTI_TimevalToDouble(&newadj, &adjustment_requested); diff --git a/sys_sunos.c b/sys_sunos.c index 7d0737e..1e7f3ab 100644 --- a/sys_sunos.c +++ b/sys_sunos.c @@ -118,7 +118,7 @@ start_adjust(void) { struct timeval newadj, oldadj; struct timeval T1; - double elapsed, accrued_error; + double elapsed, accrued_error, predicted_error; double adjust_required; struct timeval exact_newadj; double rounding_error; @@ -132,8 +132,9 @@ start_adjust(void) UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); accrued_error = elapsed * current_freq; + predicted_error = DRIFT_REMOVAL_INTERVAL / 2.0 * current_freq; - adjust_required = - (accrued_error + offset_register); + adjust_required = - (accrued_error + offset_register + predicted_error); UTI_DoubleToTimeval(adjust_required, &exact_newadj); @@ -163,7 +164,7 @@ start_adjust(void) UTI_TimevalToDouble(&oldadj, &old_adjust_remaining); - offset_register = rounding_error - old_adjust_remaining; + offset_register = rounding_error - old_adjust_remaining - predicted_error; T0 = T1; UTI_TimevalToDouble(&newadj, &adjustment_requested);