]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Don't update local reference unnecessarily
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 16 Dec 2010 15:55:59 +0000 (16:55 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 17 Dec 2010 12:22:57 +0000 (13:22 +0100)
Local reference is now updated only when a new source is selected or
match_addr is equal to the selected source, match_addr 0 is no longer
treated specially.

sources.c
sources.h

index 0c0eb2c3002ea873f0b97e794807c66941aad485..af90aecf675dd8d6db68ed5d7eeebebd3ecbcce9 100644 (file)
--- a/sources.c
+++ b/sources.c
@@ -404,13 +404,13 @@ source_to_string(SRC_Instance inst)
 /* This function selects the current reference from amongst the pool
    of sources we are holding. 
    
-   Updates are only made to the local reference if match_addr is zero or is
-   equal to the selected reference source address */
+   Updates are only made to the local reference if a new source is selected
+   or match_addr is equal to the selected reference source address */
 
 void
 SRC_SelectSource(unsigned long match_addr)
 {
-  int i, j, index;
+  int i, j, index, old_selected_index;
   struct timeval now;
   double src_offset, src_offset_sd, src_frequency, src_skew;
   double src_accrued_dispersion;
@@ -425,14 +425,15 @@ SRC_SelectSource(unsigned long match_addr)
   double total_root_dispersion;
 
   NTP_Leap leap_status = LEAP_Normal;
+  old_selected_index = selected_source_index;
 
   if (n_sources == 0) {
     /* In this case, we clearly cannot synchronise to anything */
     if (selected_source_index != INVALID_SOURCE) {
       LOG(LOGS_INFO, LOGF_Sources, "Can't synchronise: no sources");
+      selected_source_index = INVALID_SOURCE;
+      REF_SetUnsynchronised();
     }
-    selected_source_index = INVALID_SOURCE;
-    REF_SetUnsynchronised();
     return;
   }
 
@@ -581,7 +582,6 @@ SRC_SelectSource(unsigned long match_addr)
         LOG(LOGS_INFO, LOGF_Sources, "Can't synchronise: no majority");
       }
       selected_source_index = INVALID_SOURCE;
-      REF_SetUnsynchronised();
 
       /* .. and mark all sources as falsetickers (so they appear thus
          on the outputs from the command client) */
@@ -750,21 +750,23 @@ SRC_SelectSource(unsigned long match_addr)
 
         sources[selected_source_index]->status = SRC_SYNC;
 
-        /* Now just use the statistics of the selected source for
-           trimming the local clock */
+        /* Update local reference only when a new source was selected or a new
+           sample was received (i.e. match_addr is equal to selected ref_id) */
+        if (selected_source_index != old_selected_index ||
+            match_addr == sources[selected_source_index]->ref_id) {
 
-        LCL_ReadCookedTime(&now, NULL);
+          /* Now just use the statistics of the selected source for
+             trimming the local clock */
 
-        SST_GetTrackingData(sources[selected_source_index]->stats, &now,
-                            &src_offset, &src_offset_sd,
-                            &src_accrued_dispersion,
-                            &src_frequency, &src_skew);
+          LCL_ReadCookedTime(&now, NULL);
 
-        total_root_dispersion = (src_accrued_dispersion +
-                                 sources[selected_source_index]->sel_info.root_dispersion);
+          SST_GetTrackingData(sources[selected_source_index]->stats, &now,
+                              &src_offset, &src_offset_sd,
+                              &src_accrued_dispersion,
+                              &src_frequency, &src_skew);
 
-        if ((match_addr == 0) ||
-            (match_addr == sources[selected_source_index]->ref_id)) {
+          total_root_dispersion = (src_accrued_dispersion +
+              sources[selected_source_index]->sel_info.root_dispersion);
 
           REF_SetReference(min_stratum, leap_status,
                            sources[selected_source_index]->ref_id,
@@ -782,11 +784,7 @@ SRC_SelectSource(unsigned long match_addr)
           LOG(LOGS_INFO, LOGF_Sources, "Can't synchronise: no selectable sources");
         }
         selected_source_index = INVALID_SOURCE;
-        REF_SetUnsynchronised();
-
       }
-
-
     }
 
   } else {
@@ -795,9 +793,12 @@ SRC_SelectSource(unsigned long match_addr)
       LOG(LOGS_INFO, LOGF_Sources, "Can't synchronise: no reachable sources");
     }
     selected_source_index = INVALID_SOURCE;
-    REF_SetUnsynchronised();
   }
 
+  if (selected_source_index == INVALID_SOURCE &&
+      selected_source_index != old_selected_index) {
+    REF_SetUnsynchronised();
+  }
 }
 
 /* ================================================== */
index ae7e3c72534eac9f7eb1b67168b1664cc8e4b46d..039f242ce5da31fb73d4534706cdeb529d2f49f6 100644 (file)
--- a/sources.h
+++ b/sources.h
@@ -134,12 +134,11 @@ extern void SRC_ResetReachability(SRC_Instance inst);
 
 /* This routine is used to select the best source from amongst those
    we currently have valid data on, and use it as the tracking base
-   for the local time.  If match_addr is zero it means we must start
-   tracking the (newly) selected reference unconditionally, otherwise
-   it is equal to the address we should track if it turns out to be
-   the best reference.  (This avoids updating the frequency tracking
-   for every sample from other sources - only the ones from the
-   selected reference make a difference) */
+   for the local time.  Updates are only made to the local reference
+   if a new source is selected or match_addr is equal to the selected
+   reference source address. (This avoids updating the frequency
+   tracking for every sample from other sources - only the ones from
+   the selected reference make a difference) */
 extern void SRC_SelectSource(unsigned long match_addr);
 
 /* Force reselecting the best source */