]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sourcestats: add fixed minimum delay
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 17 Aug 2017 14:44:18 +0000 (16:44 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 23 Aug 2017 12:14:06 +0000 (14:14 +0200)
If the minimum delay is known (in a static network configuration), it
can replace the measured minimum from the register. This should improve
the stability of corrections for asymmetric jitter, sample weighting and
maxdelay* tests.

ntp_core.c
refclock.c
sources.c
sources.h
sourcestats.c
sourcestats.h
test/unit/sources.c

index 2717297e2cbddba77953f0ff305a3d4ae478f77d..8fede9175db02c586c69651c4b76199445447e03 100644 (file)
@@ -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;
index 6959e5b82fb4e5218658143e6c0caa9584d8fec8..754fee633c9520c5f558b3ffac06e8f38cfa64fe 100644 (file)
@@ -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),
index a72b1fbc65482f5672c0a8dd9e0ae419b38a5ef8..120bb9c7ef098ab41940c4d78ef93b332ad58c09 100644 (file)
--- 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 */
index 9acf98b33c785ebbdc58413c87cdcf351dde0e7b..118d8bddb129436bcb7774e71091fe512307a46d 100644 (file)
--- 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
index 3e8926dee5e151de73d93fd3e48477e93931f203..512648d6b547df84a31f877e8dcd62fb6dbf3441 100644 (file)
@@ -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];
 }
 
index 48f73b3b26feea2125a9ba7fe3136eb00483ee68..dfd93a3f4b2dfd0349b543f2f23cc7d6b88d7199 100644 (file)
@@ -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);
index 4b1aa721bd91dfd0affb1b5debdc3b16b3c50ec8..31a1c03d38e97210fbc8fa676511a8b94b6bd313 100644 (file)
@@ -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;