local: reset daemon after unexpected time jump
Add a new change type and use it when an unexpected time jump is detected in the scheduler to reset reference times, offset and slewing, NCR instances (with their polling interval), synchronization status, and drop all sourcestats, manual, refclock and RTC samples. This should make the recovery more graceful if the estimated jump has a large error (e.g. select didn't timeout, or after system suspend).
This commit is contained in:
parent
a3e60c93da
commit
a33a955163
10 changed files with 48 additions and 11 deletions
2
local.c
2
local.c
|
@ -479,7 +479,7 @@ LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
|
|||
double offset, double dispersion)
|
||||
{
|
||||
/* Dispatch to all handlers */
|
||||
invoke_parameter_change_handlers(raw, cooked, 0.0, offset, LCL_ChangeStep);
|
||||
invoke_parameter_change_handlers(raw, cooked, 0.0, offset, LCL_ChangeUnknownStep);
|
||||
|
||||
lcl_InvokeDispersionNotifyHandlers(dispersion);
|
||||
}
|
||||
|
|
3
local.h
3
local.h
|
@ -74,7 +74,8 @@ extern void LCL_GetOffsetCorrection(struct timeval *raw, double *correction, dou
|
|||
|
||||
typedef enum {
|
||||
LCL_ChangeAdjust,
|
||||
LCL_ChangeStep
|
||||
LCL_ChangeStep,
|
||||
LCL_ChangeUnknownStep
|
||||
} LCL_ChangeType;
|
||||
|
||||
typedef void (*LCL_ParameterChangeHandler)
|
||||
|
|
5
manual.c
5
manual.c
|
@ -221,6 +221,11 @@ slew_samples(struct timeval *raw,
|
|||
{
|
||||
double delta_time;
|
||||
int i;
|
||||
|
||||
if (change_type == LCL_ChangeUnknownStep) {
|
||||
MNL_Reset();
|
||||
}
|
||||
|
||||
for (i=0; i<n_samples; i++) {
|
||||
UTI_AdjustTimeval(&samples[i].when, cooked, &samples[i].when, &delta_time,
|
||||
dfreq, doffset);
|
||||
|
|
|
@ -491,9 +491,13 @@ slew_sources(struct timeval *raw,
|
|||
UTI_IPToString(&records[i].remote_addr->ip_addr), dfreq, doffset);
|
||||
#endif
|
||||
|
||||
if (change_type == LCL_ChangeUnknownStep) {
|
||||
NCR_ResetInstance(records[i].data);
|
||||
} else {
|
||||
NCR_SlewTimes(records[i].data, cooked, dfreq, doffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -581,9 +581,13 @@ slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq,
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_sources; i++)
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
if (change_type == LCL_ChangeUnknownStep)
|
||||
filter_reset(&refclocks[i].filter);
|
||||
else
|
||||
filter_slew_samples(&refclocks[i].filter, cooked, dfreq, doffset);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_dispersion(double dispersion, void *anything)
|
||||
|
|
|
@ -147,7 +147,10 @@ handle_slew(struct timeval *raw,
|
|||
LCL_ChangeType change_type,
|
||||
void *anything)
|
||||
{
|
||||
if (change_type == LCL_ChangeStep) {
|
||||
if (change_type == LCL_ChangeUnknownStep) {
|
||||
last_ref_update.tv_sec = 0;
|
||||
last_ref_update.tv_usec = 0;
|
||||
} else if (change_type == LCL_ChangeStep) {
|
||||
UTI_AddDoubleToTimeval(&last_ref_update, -doffset, &last_ref_update);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,6 +273,11 @@ slew_samples
|
|||
double delta_time;
|
||||
double old_seconds_fast, old_gain_rate;
|
||||
|
||||
if (change_type == LCL_ChangeUnknownStep) {
|
||||
/* Drop all samples. */
|
||||
n_samples = 0;
|
||||
}
|
||||
|
||||
for (i=0; i<n_samples; i++) {
|
||||
UTI_AdjustTimeval(system_times + i, cooked, system_times + i, &delta_time,
|
||||
dfreq, doffset);
|
||||
|
|
|
@ -1093,9 +1093,17 @@ slew_sources(struct timeval *raw,
|
|||
int i;
|
||||
|
||||
for (i=0; i<n_sources; i++) {
|
||||
if (change_type == LCL_ChangeUnknownStep) {
|
||||
SST_ResetInstance(sources[i]->stats);
|
||||
} else {
|
||||
SST_SlewSamples(sources[i]->stats, cooked, dfreq, doffset);
|
||||
}
|
||||
}
|
||||
|
||||
if (change_type == LCL_ChangeUnknownStep) {
|
||||
/* After resetting no source is selectable, set reference unsynchronised */
|
||||
SRC_SelectSource(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -87,6 +87,7 @@ static double slew_error;
|
|||
/* ================================================== */
|
||||
|
||||
static void handle_end_of_slew(void *anything);
|
||||
static void update_slew(void);
|
||||
|
||||
/* ================================================== */
|
||||
/* Adjust slew_start on clock step */
|
||||
|
@ -95,9 +96,15 @@ static void
|
|||
handle_step(struct timeval *raw, struct timeval *cooked, double dfreq,
|
||||
double doffset, LCL_ChangeType change_type, void *anything)
|
||||
{
|
||||
if (change_type == LCL_ChangeStep)
|
||||
if (change_type == LCL_ChangeUnknownStep) {
|
||||
/* Reset offset and slewing */
|
||||
slew_start = *raw;
|
||||
offset_register = 0.0;
|
||||
update_slew();
|
||||
} else if (change_type == LCL_ChangeStep) {
|
||||
UTI_AddDoubleToTimeval(&slew_start, -doffset, &slew_start);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* End currently running slew and start a new one */
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
test_start "external time step"
|
||||
|
||||
min_sync_time=1300
|
||||
max_sync_time=1500
|
||||
min_sync_time=1500
|
||||
max_sync_time=1550
|
||||
|
||||
for step in -1e2 1e2; do
|
||||
# Make one step in 150th second
|
||||
|
|
Loading…
Reference in a new issue