diff --git a/ntp_core.c b/ntp_core.c index 2717297..8fede91 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -585,7 +585,8 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, params->sel_options, &result->remote_addr.ip_addr, - params->min_samples, params->max_samples); + params->min_samples, params->max_samples, + 0.0); result->rx_timeout_id = 0; result->tx_timeout_id = 0; diff --git a/refclock.c b/refclock.c index 6959e5b..754fee6 100644 --- a/refclock.c +++ b/refclock.c @@ -260,7 +260,7 @@ RCL_AddRefclock(RefclockParameters *params) filter_init(&inst->filter, params->filter_length, params->max_dispersion); inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, params->sel_options, NULL, - params->min_samples, params->max_samples); + params->min_samples, params->max_samples, 0.0); DEBUG_LOG("refclock %s refid=%s poll=%d dpoll=%d filter=%d", params->driver_name, UTI_RefidToString(inst->ref_id), diff --git a/sources.c b/sources.c index a72b1fb..120bb9c 100644 --- a/sources.c +++ b/sources.c @@ -213,7 +213,8 @@ void SRC_Finalise(void) /* Function to create a new instance. This would be called by one of the individual source-type instance creation routines. */ -SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options, IPAddr *addr, int min_samples, int max_samples) +SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options, IPAddr *addr, + int min_samples, int max_samples, double min_delay) { SRC_Instance result; @@ -225,7 +226,7 @@ SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_optio max_samples = CNF_GetMaxSamples(); result = MallocNew(struct SRC_Instance_Record); - result->stats = SST_CreateInstance(ref_id, addr, min_samples, max_samples); + result->stats = SST_CreateInstance(ref_id, addr, min_samples, max_samples, min_delay); if (n_sources == max_n_sources) { /* Reallocate memory */ diff --git a/sources.h b/sources.h index 9acf98b..118d8bd 100644 --- a/sources.h +++ b/sources.h @@ -59,7 +59,8 @@ typedef enum { /* Function to create a new instance. This would be called by one of the individual source-type instance creation routines. */ -extern SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options, IPAddr *addr, int min_samples, int max_samples); +extern SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options, IPAddr *addr, + int min_samples, int max_samples, double min_delay); /* Function to get rid of a source when it is being unconfigured. This may cause the current reference source to be reselected, if this diff --git a/sourcestats.c b/sourcestats.c index 3e8926d..512648d 100644 --- a/sourcestats.c +++ b/sourcestats.c @@ -82,6 +82,9 @@ struct SST_Stats_Record { int min_samples; int max_samples; + /* User defined minimum delay */ + double fixed_min_delay; + /* Number of samples currently stored. The samples are stored in circular buffer. */ int n_samples; @@ -197,13 +200,14 @@ SST_Finalise(void) /* This function creates a new instance of the statistics handler */ SST_Stats -SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_samples) +SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_samples, double min_delay) { SST_Stats inst; inst = MallocNew(struct SST_Stats_Record); inst->min_samples = min_samples; inst->max_samples = max_samples; + inst->fixed_min_delay = min_delay; SST_SetRefid(inst, refid, addr); SST_ResetInstance(inst); @@ -310,6 +314,9 @@ SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time, inst->root_dispersions[m] = root_dispersion; inst->strata[m] = stratum; + if (inst->peer_delays[n] < inst->fixed_min_delay) + inst->peer_delays[n] = 2.0 * inst->fixed_min_delay - inst->peer_delays[n]; + if (!inst->n_samples || inst->peer_delays[n] < inst->peer_delays[inst->min_delay_sample]) inst->min_delay_sample = n; @@ -418,18 +425,19 @@ find_min_delay_sample(SST_Stats inst) static void correct_asymmetry(SST_Stats inst, double *times_back, double *offsets) { - double asymmetry, delays[MAX_SAMPLES * REGRESS_RUNS_RATIO]; + double asymmetry, min_delay, delays[MAX_SAMPLES * REGRESS_RUNS_RATIO]; int i, n; /* Don't try to estimate the asymmetry with reference clocks */ if (!inst->ip_addr) return; + min_delay = SST_MinRoundTripDelay(inst); n = inst->runs_samples + inst->n_samples; for (i = 0; i < n; i++) delays[i] = inst->peer_delays[get_runsbuf_index(inst, i - inst->runs_samples)] - - inst->peer_delays[inst->min_delay_sample]; + min_delay; /* Reset the counter when the regression fails or the sign changes */ if (!RGR_MultipleRegress(times_back, delays, offsets, n, &asymmetry) || @@ -771,8 +779,12 @@ SST_PredictOffset(SST_Stats inst, struct timespec *when) double SST_MinRoundTripDelay(SST_Stats inst) { + if (inst->fixed_min_delay > 0.0) + return inst->fixed_min_delay; + if (!inst->n_samples) return DBL_MAX; + return inst->peer_delays[inst->min_delay_sample]; } diff --git a/sourcestats.h b/sourcestats.h index 48f73b3..dfd93a3 100644 --- a/sourcestats.h +++ b/sourcestats.h @@ -38,7 +38,8 @@ extern void SST_Initialise(void); extern void SST_Finalise(void); /* This function creates a new instance of the statistics handler */ -extern SST_Stats SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_samples); +extern SST_Stats SST_CreateInstance(uint32_t refid, IPAddr *addr, + int min_samples, int max_samples, double min_delay); /* This function deletes an instance of the statistics handler. */ extern void SST_DeleteInstance(SST_Stats inst); diff --git a/test/unit/sources.c b/test/unit/sources.c index 4b1aa72..31a1c03 100644 --- a/test/unit/sources.c +++ b/test/unit/sources.c @@ -53,7 +53,7 @@ test_unit(void) DEBUG_LOG("added source %d options %d", j, sel_options); srcs[j] = SRC_CreateNewInstance(UTI_IPToRefid(&addr), SRC_NTP, sel_options, &addr, - SRC_DEFAULT_MINSAMPLES, SRC_DEFAULT_MAXSAMPLES); + SRC_DEFAULT_MINSAMPLES, SRC_DEFAULT_MAXSAMPLES, 0.0); SRC_UpdateReachability(srcs[j], 1); samples = (i + j) % 5 + 3;