]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sourcestats: add fixed asymmetry
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 22 Aug 2017 14:26:40 +0000 (16:26 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 23 Aug 2017 12:33:23 +0000 (14:33 +0200)
Rework the code to allow the jitter asymmetry to be specified.

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

index 8fede9175db02c586c69651c4b76199445447e03..f981953acca29e0483c79e73186465e47f4a4794 100644 (file)
@@ -586,7 +586,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
                                          SRC_NTP, params->sel_options,
                                          &result->remote_addr.ip_addr,
                                          params->min_samples, params->max_samples,
-                                         0.0);
+                                         0.0, 1.0);
 
   result->rx_timeout_id = 0;
   result->tx_timeout_id = 0;
index 754fee633c9520c5f558b3ffac06e8f38cfa64fe..01e877c76e5a449037f89775603f930612f8ad89 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, 0.0);
+                                       params->min_samples, params->max_samples, 0.0, 0.0);
 
   DEBUG_LOG("refclock %s refid=%s poll=%d dpoll=%d filter=%d",
       params->driver_name, UTI_RefidToString(inst->ref_id),
index 120bb9c7ef098ab41940c4d78ef93b332ad58c09..67b61e739fc0c5f411515d76ce93f505e0a907a1 100644 (file)
--- a/sources.c
+++ b/sources.c
@@ -213,8 +213,9 @@ 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, double min_delay)
+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, double asymmetry)
 {
   SRC_Instance result;
 
@@ -226,7 +227,8 @@ 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, min_delay);
+  result->stats = SST_CreateInstance(ref_id, addr, min_samples, max_samples,
+                                     min_delay, asymmetry);
 
   if (n_sources == max_n_sources) {
     /* Reallocate memory */
index 118d8bddb129436bcb7774e71091fe512307a46d..60d28fde26ad4dcba0eafa5ef3bd23df76fe7751 100644 (file)
--- a/sources.h
+++ b/sources.h
@@ -59,8 +59,9 @@ 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, double min_delay);
+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, double asymmetry);
 
 /* 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 512648d6b547df84a31f877e8dcd62fb6dbf3441..a4a98022b2615a794e88e30b93e450dc65415adc 100644 (file)
@@ -85,6 +85,9 @@ struct SST_Stats_Record {
   /* User defined minimum delay */
   double fixed_min_delay;
 
+  /* User defined asymmetry of network jitter */
+  double fixed_asymmetry;
+
   /* Number of samples currently stored.  The samples are stored in circular
      buffer. */
   int n_samples;
@@ -200,7 +203,8 @@ 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, double min_delay)
+SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_samples,
+                   double min_delay, double asymmetry)
 {
   SST_Stats inst;
   inst = MallocNew(struct SST_Stats_Record);
@@ -208,6 +212,7 @@ SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_sample
   inst->min_samples = min_samples;
   inst->max_samples = max_samples;
   inst->fixed_min_delay = min_delay;
+  inst->fixed_asymmetry = asymmetry;
 
   SST_SetRefid(inst, refid, addr);
   SST_ResetInstance(inst);
@@ -422,14 +427,43 @@ find_min_delay_sample(SST_Stats inst)
    minimum network delay.  This can significantly improve the accuracy and
    stability of the estimated offset and frequency. */
 
+static int
+estimate_asymmetry(double *times_back, double *offsets, double *delays, int n,
+                   double *asymmetry, int *asymmetry_run)
+{
+  double a;
+
+  /* Reset the counter when the regression fails or the sign changes */
+  if (!RGR_MultipleRegress(times_back, delays, offsets, n, &a) ||
+      a * *asymmetry_run < 0.0) {
+    *asymmetry = 0;
+    *asymmetry_run = 0.0;
+    return 0;
+  }
+
+  if (a <= -MIN_ASYMMETRY && *asymmetry_run > -MAX_ASYMMETRY_RUN)
+    (*asymmetry_run)--;
+  else if (a >= MIN_ASYMMETRY && *asymmetry_run < MAX_ASYMMETRY_RUN)
+    (*asymmetry_run)++;
+
+  if (abs(*asymmetry_run) < MIN_ASYMMETRY_RUN)
+    return 0;
+
+  *asymmetry = CLAMP(-MAX_ASYMMETRY, a, MAX_ASYMMETRY);
+
+  return 1;
+}
+
+/* ================================================== */
+
 static void
 correct_asymmetry(SST_Stats inst, double *times_back, double *offsets)
 {
-  double asymmetry, min_delay, delays[MAX_SAMPLES * REGRESS_RUNS_RATIO];
+  double 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)
+  /* Check if the asymmetry was not specified to be zero */
+  if (inst->fixed_asymmetry == 0.0)
     return;
 
   min_delay = SST_MinRoundTripDelay(inst);
@@ -439,29 +473,17 @@ correct_asymmetry(SST_Stats inst, double *times_back, double *offsets)
     delays[i] = inst->peer_delays[get_runsbuf_index(inst, i - inst->runs_samples)] -
                 min_delay;
 
-  /* Reset the counter when the regression fails or the sign changes */
-  if (!RGR_MultipleRegress(times_back, delays, offsets, n, &asymmetry) ||
-      asymmetry * inst->asymmetry_run < 0.0) {
-    inst->asymmetry_run = 0;
-    inst->asymmetry = 0.0;
-    return;
+  if (fabs(inst->fixed_asymmetry) <= MAX_ASYMMETRY) {
+    inst->asymmetry = inst->fixed_asymmetry;
+  } else {
+    if (!estimate_asymmetry(times_back, offsets, delays, n,
+                            &inst->asymmetry, &inst->asymmetry_run))
+      return;
   }
 
-  asymmetry = CLAMP(-MAX_ASYMMETRY, asymmetry, MAX_ASYMMETRY);
-
-  if (asymmetry <= -MIN_ASYMMETRY && inst->asymmetry_run > -MAX_ASYMMETRY_RUN)
-    inst->asymmetry_run--;
-  else if (asymmetry >= MIN_ASYMMETRY && inst->asymmetry_run < MAX_ASYMMETRY_RUN)
-    inst->asymmetry_run++;
-
-  if (abs(inst->asymmetry_run) < MIN_ASYMMETRY_RUN)
-    return;
-
   /* Correct the offsets */
   for (i = 0; i < n; i++)
-    offsets[i] -= asymmetry * delays[i];
-
-  inst->asymmetry = asymmetry;
+    offsets[i] -= inst->asymmetry * delays[i];
 }
 
 /* ================================================== */
index dfd93a3f4b2dfd0349b543f2f23cc7d6b88d7199..9b34cc6cbd7eb9c156cd8e533a047ebd97e0d953 100644 (file)
@@ -39,7 +39,8 @@ 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, double min_delay);
+                                    int min_samples, int max_samples,
+                                    double min_delay, double asymmetry);
 
 /* This function deletes an instance of the statistics handler. */
 extern void SST_DeleteInstance(SST_Stats inst);
index 31a1c03d38e97210fbc8fa676511a8b94b6bd313..341e22e1bcbf2fe58dd7ea2153cd2d1666c81790 100644 (file)
@@ -53,7 +53,8 @@ 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, 0.0);
+                                      SRC_DEFAULT_MINSAMPLES, SRC_DEFAULT_MAXSAMPLES,
+                                      0.0, 1.0);
       SRC_UpdateReachability(srcs[j], 1);
 
       samples = (i + j) % 5 + 3;