diff --git a/include/haproxy/time.h b/include/haproxy/time.h index 87bc3655a..93dd84080 100644 --- a/include/haproxy/time.h +++ b/include/haproxy/time.h @@ -61,6 +61,7 @@ extern struct timeval start_date; /* the process's start date */ extern THREAD_LOCAL struct timeval before_poll; /* system date before calling poll() */ extern THREAD_LOCAL struct timeval after_poll; /* system date after leaving poll() */ extern volatile unsigned long long global_now; +extern volatile unsigned int global_now_ms; /**** exported functions *************************************************/ diff --git a/src/time.c b/src/time.c index d5344d26f..0cfc9bf3c 100644 --- a/src/time.c +++ b/src/time.c @@ -15,6 +15,7 @@ #include #include +#include #include THREAD_LOCAL unsigned int ms_left_scaled; /* milliseconds left for current second (0..2^32-1) */ @@ -29,6 +30,7 @@ THREAD_LOCAL struct timeval after_poll; /* system date after leaving poll() static THREAD_LOCAL struct timeval tv_offset; /* per-thread time ofsset relative to global time */ volatile unsigned long long global_now; /* common date between all threads (32:32) */ +volatile unsigned int global_now_ms; /* common date in milliseconds (may wrap) */ static THREAD_LOCAL unsigned int iso_time_sec; /* last iso time value for this thread */ static THREAD_LOCAL char iso_time_str[34]; /* ISO time representation of gettimeofday() */ @@ -177,6 +179,7 @@ void tv_update_date(int max_wait, int interrupted) { struct timeval adjusted, deadline, tmp_now, tmp_adj; unsigned int curr_sec_ms; /* millisecond of current second (0..999) */ + unsigned int old_now_ms, new_now_ms; unsigned long long old_now; unsigned long long new_now; @@ -260,6 +263,15 @@ void tv_update_date(int max_wait, int interrupted) */ ms_left_scaled = (999U - curr_sec_ms) * 4294967U; now_ms = now.tv_sec * 1000 + curr_sec_ms; + + /* update the global current millisecond */ + old_now_ms = global_now_ms; + do { + new_now_ms = old_now_ms; + if (tick_is_lt(new_now_ms, now_ms)) + new_now_ms = now_ms; + } while (!_HA_ATOMIC_CAS(&global_now_ms, &old_now_ms, new_now_ms)); + return; }