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);
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)
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);
inst->lock_ref = -1;
}
- if (n_sources > 0)
+ if (n_sources > 0) {
LCL_AddParameterChangeHandler(slew_samples, NULL);
+ LCL_AddDispersionNotifyHandler(add_dispersion, NULL);
+ }
}
void
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)
{
#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;
+ }
+}
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);
initialised = 1;
LCL_AddParameterChangeHandler(slew_sources, NULL);
+ LCL_AddDispersionNotifyHandler(add_dispersion, NULL);
return;
}
void SRC_Finalise(void)
{
LCL_RemoveParameterChangeHandler(slew_sources, NULL);
+ LCL_RemoveDispersionNotifyHandler(add_dispersion, NULL);
initialised = 0;
return;
}
}
+/* ================================================== */
+/* 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 */
/* ================================================== */
+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)
{
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