diff --git a/refclock.c b/refclock.c index 1a99f53..cd09ebc 100644 --- a/refclock.c +++ b/refclock.c @@ -91,6 +91,7 @@ static int pps_stratum(RCL_Instance instance, struct timeval *tv); static void poll_timeout(void *arg); static void slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq, double afreq, double doffset, int is_step_change, void *anything); +static void add_dispersion(double dispersion, void *anything); static void log_sample(RCL_Instance instance, struct timeval *sample_time, int pulse, double raw_offset, double cooked_offset, double dispersion); static void filter_init(struct MedianFilter *filter, int length); @@ -100,6 +101,7 @@ static void filter_add_sample(struct MedianFilter *filter, struct timeval *sampl static int filter_get_last_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion); static int filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion); static void filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset); +static void filter_add_dispersion(struct MedianFilter *filter, double dispersion); void RCL_Initialise(void) @@ -134,8 +136,10 @@ RCL_Finalise(void) Free(inst->driver_parameter); } - if (n_sources > 0) + if (n_sources > 0) { LCL_RemoveParameterChangeHandler(slew_samples, NULL); + LCL_RemoveDispersionNotifyHandler(add_dispersion, NULL); + } if (logfile) fclose(logfile); @@ -250,8 +254,10 @@ RCL_StartRefclocks(void) inst->lock_ref = -1; } - if (n_sources > 0) + if (n_sources > 0) { LCL_AddParameterChangeHandler(slew_samples, NULL); + LCL_AddDispersionNotifyHandler(add_dispersion, NULL); + } } void @@ -548,6 +554,15 @@ slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq, double a filter_slew_samples(&refclocks[i].filter, cooked, dfreq, doffset); } +static void +add_dispersion(double dispersion, void *anything) +{ + int i; + + for (i = 0; i < n_sources; i++) + filter_add_dispersion(&refclocks[i].filter, dispersion); +} + static void log_sample(RCL_Instance instance, struct timeval *sample_time, int pulse, double raw_offset, double cooked_offset, double dispersion) { @@ -752,3 +767,13 @@ filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double df #endif } } + +static void +filter_add_dispersion(struct MedianFilter *filter, double dispersion) +{ + int i; + + for (i = 0; i < filter->used; i++) { + filter->samples[i].dispersion += dispersion; + } +} diff --git a/sources.c b/sources.c index f27583b..f1674f2 100644 --- a/sources.c +++ b/sources.c @@ -130,6 +130,8 @@ static int selected_source_index; /* Which source index is currently static void slew_sources(struct timeval *raw, struct timeval *cooked, double dfreq, double afreq, double doffset, int is_step_change, void *anything); +static void +add_dispersion(double dispersion, void *anything); static char * source_to_string(SRC_Instance inst); @@ -144,6 +146,7 @@ void SRC_Initialise(void) { initialised = 1; LCL_AddParameterChangeHandler(slew_sources, NULL); + LCL_AddDispersionNotifyHandler(add_dispersion, NULL); return; } @@ -153,6 +156,7 @@ void SRC_Initialise(void) { void SRC_Finalise(void) { LCL_RemoveParameterChangeHandler(slew_sources, NULL); + LCL_RemoveDispersionNotifyHandler(add_dispersion, NULL); initialised = 0; return; } @@ -807,6 +811,20 @@ slew_sources(struct timeval *raw, } +/* ================================================== */ +/* This routine is called when an indeterminate offset is introduced + into the local time. */ + +static void +add_dispersion(double dispersion, void *anything) +{ + int i; + + for (i = 0; i < n_sources; i++) { + SST_AddDispersion(sources[i]->stats, dispersion); + } +} + /* ================================================== */ /* This is called to dump out the source measurement registers */ diff --git a/sourcestats.c b/sourcestats.c index 3dc61e0..2ecae89 100644 --- a/sourcestats.c +++ b/sourcestats.c @@ -717,6 +717,19 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs /* ================================================== */ +void +SST_AddDispersion(SST_Stats inst, double dispersion) +{ + int i; + + for (i=0; i < inst->n_samples; i++) { + inst->root_dispersions[i] += dispersion; + inst->peer_dispersions[i] += dispersion; + } +} + +/* ================================================== */ + double SST_PredictOffset(SST_Stats inst, struct timeval *when) { diff --git a/sourcestats.h b/sourcestats.h index 0a5a82b..5e787d8 100644 --- a/sourcestats.h +++ b/sourcestats.h @@ -125,6 +125,9 @@ SST_GetReferenceData(SST_Stats inst, struct timeval *now, extern void SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffset); +/* This routine is called when an indeterminate offset is introduced + into the local time. */ +extern void SST_AddDispersion(SST_Stats inst, double dispersion); /* Predict the offset of the local clock relative to a given source at a given local cooked time. Positive indicates local clock is FAST