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.
This commit is contained in:
Miroslav Lichvar 2015-08-12 15:48:13 +02:00
parent 18d514d552
commit b6a27df5b9
3 changed files with 12 additions and 9 deletions

View file

@ -108,7 +108,7 @@ start_adjust(void)
{ {
struct timeval newadj, oldadj; struct timeval newadj, oldadj;
struct timeval T1; struct timeval T1;
double elapsed, accrued_error; double elapsed, accrued_error, predicted_error;
double adjust_required; double adjust_required;
double rounding_error; double rounding_error;
double old_adjust_remaining; double old_adjust_remaining;
@ -120,8 +120,9 @@ start_adjust(void)
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
accrued_error = elapsed * current_freq; 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_DoubleToTimeval(adjust_required, &newadj);
UTI_TimevalToDouble(&newadj, &adjustment_requested); UTI_TimevalToDouble(&newadj, &adjustment_requested);
@ -133,7 +134,7 @@ start_adjust(void)
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining); UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
offset_register = rounding_error - old_adjust_remaining; offset_register = rounding_error - old_adjust_remaining - predicted_error;
T0 = T1; T0 = T1;
} }

View file

@ -127,7 +127,7 @@ start_adjust(void)
{ {
struct timeval newadj, oldadj; struct timeval newadj, oldadj;
struct timeval T1; struct timeval T1;
double elapsed, accrued_error; double elapsed, accrued_error, predicted_error;
double adjust_required; double adjust_required;
struct timeval exact_newadj; struct timeval exact_newadj;
double rounding_error; double rounding_error;
@ -140,8 +140,9 @@ start_adjust(void)
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
accrued_error = elapsed * current_freq; 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); UTI_DoubleToTimeval(adjust_required, &exact_newadj);
@ -160,7 +161,7 @@ start_adjust(void)
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining); UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
offset_register = rounding_error - old_adjust_remaining; offset_register = rounding_error - old_adjust_remaining - predicted_error;
T0 = T1; T0 = T1;
UTI_TimevalToDouble(&newadj, &adjustment_requested); UTI_TimevalToDouble(&newadj, &adjustment_requested);

View file

@ -118,7 +118,7 @@ start_adjust(void)
{ {
struct timeval newadj, oldadj; struct timeval newadj, oldadj;
struct timeval T1; struct timeval T1;
double elapsed, accrued_error; double elapsed, accrued_error, predicted_error;
double adjust_required; double adjust_required;
struct timeval exact_newadj; struct timeval exact_newadj;
double rounding_error; double rounding_error;
@ -132,8 +132,9 @@ start_adjust(void)
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0); UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
accrued_error = elapsed * current_freq; 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); UTI_DoubleToTimeval(adjust_required, &exact_newadj);
@ -163,7 +164,7 @@ start_adjust(void)
UTI_TimevalToDouble(&oldadj, &old_adjust_remaining); UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
offset_register = rounding_error - old_adjust_remaining; offset_register = rounding_error - old_adjust_remaining - predicted_error;
T0 = T1; T0 = T1;
UTI_TimevalToDouble(&newadj, &adjustment_requested); UTI_TimevalToDouble(&newadj, &adjustment_requested);