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)
|
double offset, double dispersion)
|
||||||
{
|
{
|
||||||
/* Dispatch to all handlers */
|
/* 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);
|
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 {
|
typedef enum {
|
||||||
LCL_ChangeAdjust,
|
LCL_ChangeAdjust,
|
||||||
LCL_ChangeStep
|
LCL_ChangeStep,
|
||||||
|
LCL_ChangeUnknownStep
|
||||||
} LCL_ChangeType;
|
} LCL_ChangeType;
|
||||||
|
|
||||||
typedef void (*LCL_ParameterChangeHandler)
|
typedef void (*LCL_ParameterChangeHandler)
|
||||||
|
|
5
manual.c
5
manual.c
|
@ -221,6 +221,11 @@ slew_samples(struct timeval *raw,
|
||||||
{
|
{
|
||||||
double delta_time;
|
double delta_time;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (change_type == LCL_ChangeUnknownStep) {
|
||||||
|
MNL_Reset();
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<n_samples; i++) {
|
for (i=0; i<n_samples; i++) {
|
||||||
UTI_AdjustTimeval(&samples[i].when, cooked, &samples[i].when, &delta_time,
|
UTI_AdjustTimeval(&samples[i].when, cooked, &samples[i].when, &delta_time,
|
||||||
dfreq, doffset);
|
dfreq, doffset);
|
||||||
|
|
|
@ -491,7 +491,11 @@ slew_sources(struct timeval *raw,
|
||||||
UTI_IPToString(&records[i].remote_addr->ip_addr), dfreq, doffset);
|
UTI_IPToString(&records[i].remote_addr->ip_addr), dfreq, doffset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NCR_SlewTimes(records[i].data, cooked, dfreq, doffset);
|
if (change_type == LCL_ChangeUnknownStep) {
|
||||||
|
NCR_ResetInstance(records[i].data);
|
||||||
|
} else {
|
||||||
|
NCR_SlewTimes(records[i].data, cooked, dfreq, doffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -581,8 +581,12 @@ slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < n_sources; i++)
|
for (i = 0; i < n_sources; i++) {
|
||||||
filter_slew_samples(&refclocks[i].filter, cooked, dfreq, doffset);
|
if (change_type == LCL_ChangeUnknownStep)
|
||||||
|
filter_reset(&refclocks[i].filter);
|
||||||
|
else
|
||||||
|
filter_slew_samples(&refclocks[i].filter, cooked, dfreq, doffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -147,7 +147,10 @@ handle_slew(struct timeval *raw,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
void *anything)
|
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);
|
UTI_AddDoubleToTimeval(&last_ref_update, -doffset, &last_ref_update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,6 +273,11 @@ slew_samples
|
||||||
double delta_time;
|
double delta_time;
|
||||||
double old_seconds_fast, old_gain_rate;
|
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++) {
|
for (i=0; i<n_samples; i++) {
|
||||||
UTI_AdjustTimeval(system_times + i, cooked, system_times + i, &delta_time,
|
UTI_AdjustTimeval(system_times + i, cooked, system_times + i, &delta_time,
|
||||||
dfreq, doffset);
|
dfreq, doffset);
|
||||||
|
|
12
sources.c
12
sources.c
|
@ -1093,9 +1093,17 @@ slew_sources(struct timeval *raw,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<n_sources; i++) {
|
for (i=0; i<n_sources; i++) {
|
||||||
SST_SlewSamples(sources[i]->stats, cooked, dfreq, doffset);
|
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 handle_end_of_slew(void *anything);
|
||||||
|
static void update_slew(void);
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Adjust slew_start on clock step */
|
/* Adjust slew_start on clock step */
|
||||||
|
@ -95,8 +96,14 @@ static void
|
||||||
handle_step(struct timeval *raw, struct timeval *cooked, double dfreq,
|
handle_step(struct timeval *raw, struct timeval *cooked, double dfreq,
|
||||||
double doffset, LCL_ChangeType change_type, void *anything)
|
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);
|
UTI_AddDoubleToTimeval(&slew_start, -doffset, &slew_start);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
test_start "external time step"
|
test_start "external time step"
|
||||||
|
|
||||||
min_sync_time=1300
|
min_sync_time=1500
|
||||||
max_sync_time=1500
|
max_sync_time=1550
|
||||||
|
|
||||||
for step in -1e2 1e2; do
|
for step in -1e2 1e2; do
|
||||||
# Make one step in 150th second
|
# Make one step in 150th second
|
||||||
|
|
Loading…
Reference in a new issue