]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: time: also provide a global, monotonic global_now_ms timer
authorWilly Tarreau <w@1wt.eu>
Tue, 23 Mar 2021 07:45:42 +0000 (08:45 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 23 Mar 2021 08:01:37 +0000 (09:01 +0100)
The period-based freq counters need the global date in milliseconds,
so better calculate it and expose it rather than letting all call
places incorrectly retrieve it.

Here what we do is that we maintain a new globally monotonic timer,
global_now_ms, which ought to be very close to the global_now one,
but maintains the monotonic approach of now_ms between all threads
in that global_now_ms is always ahead of any now_ms.

This patch is made simple to ease backporting (it will be needed for
a subsequent fix), but it also opens the way to some simplifications
on the time handling: instead of computing the local time and trying
to force it to the global one, we should soon be able to proceed in
the opposite way, that is computing the new global time an making the
local one just the latest snapshot of it. This will bring the benefit
of making sure that the global time is always ahead of the local one.

include/haproxy/time.h
src/time.c

index 87bc3655a44afa36c28fa3d0863e7f1a491cfe76..93dd840800dc7fe148e86840b75f90d66a5b3077 100644 (file)
@@ -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 *************************************************/
index d5344d26f62319220afdb6e740d439156c9d9d0c..0cfc9bf3c8ad6660c94927596588d505d1c0612e 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <haproxy/api.h>
 #include <haproxy/time.h>
+#include <haproxy/ticks.h>
 #include <haproxy/tools.h>
 
 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;
 }