/* ================================================== */
-/* 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;
}
/* ================================================== */
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;