]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sched: try to detect also forward time jumps
authorMiroslav Lichvar <mlichvar@redhat.com>
Fri, 30 May 2014 15:30:02 +0000 (17:30 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Mon, 2 Jun 2014 14:48:57 +0000 (16:48 +0200)
sched.c

diff --git a/sched.c b/sched.c
index 2204f96dece25a8711405c24f9a7d151717bb4b7..8de2fd53e185b468b57eefcdb607af9b0837cf70 100644 (file)
--- a/sched.c
+++ b/sched.c
@@ -529,30 +529,33 @@ handle_slew(struct timeval *raw,
 
 /* ================================================== */
 
-/* Try to handle unexpected backward time jump */
+#define JUMP_DETECT_THRESHOLD 10
 
-static void
-recover_backjump(struct timeval *raw, struct timeval *cooked, int timeout)
+static int
+check_current_time(struct timeval *raw, int timeout)
 {
-      double diff, err;
-
-      UTI_DiffTimevalsToDouble(&diff, &last_select_ts_raw, raw);
-
-      if (n_timer_queue_entries > 0) {
-        UTI_DiffTimevalsToDouble(&err, &(timer_queue.next->tv), &last_select_ts_raw);
-      } else {
-        err = 0.0;
-      }
-
-      diff += err;
+  double diff;
+
+  if (last_select_ts_raw.tv_sec > raw->tv_sec + JUMP_DETECT_THRESHOLD) {
+    LOG(LOGS_WARN, LOGF_Scheduler, "Backward time jump detected!");
+  } else if (n_timer_queue_entries > 0 &&
+      timer_queue.next->tv.tv_sec + JUMP_DETECT_THRESHOLD < raw->tv_sec) {
+    LOG(LOGS_WARN, LOGF_Scheduler, "Forward time jump detected!");
+  } else {
+    return 1;
+  }
 
-      if (timeout) {
-        err = 1.0;
-      }
+  if (timeout) {
+    assert(n_timer_queue_entries > 0);
+    UTI_DiffTimevalsToDouble(&diff, &timer_queue.next->tv, raw);
+  } else {
+    UTI_DiffTimevalsToDouble(&diff, &last_select_ts_raw, raw);
+  }
 
-      LOG(LOGS_WARN, LOGF_Scheduler, "Backward time jump detected! (correction %.1f +- %.1f seconds)", diff, err);
+  /* Cooked time may no longer be valid after dispatching the handlers */
+  LCL_NotifyExternalTimeStep(raw, raw, diff, fabs(diff));
 
-      LCL_NotifyExternalTimeStep(raw, cooked, diff, err);
+  return 0;
 }
 
 /* ================================================== */
@@ -600,9 +603,10 @@ SCH_MainLoop(void)
     LCL_ReadRawTime(&now);
     LCL_CookTime(&now, &cooked, &err);
 
-    /* Check if time didn't jump backwards */
-    if (last_select_ts_raw.tv_sec > now.tv_sec + 1) {
-      recover_backjump(&now, &cooked, status == 0);
+    /* Check if the time didn't jump unexpectedly */
+    if (!check_current_time(&now, status == 0)) {
+      /* Cook the time again after handling the step */
+      LCL_CookTime(&now, &cooked, &err);
     }
 
     last_select_ts_raw = now;