]> git.kaiwu.me - haproxy.git/commit
MEDIUM: time: make the clock offset global and no per-thread
authorWilly Tarreau <w@1wt.eu>
Sun, 11 Apr 2021 16:53:58 +0000 (18:53 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 11 Apr 2021 21:59:37 +0000 (23:59 +0200)
commit44982715ba74623ade9ff96f7b2fd95245af25ab
tree2e4d66159c544de7ece0bea1b7127e8622951212
parent7e4a557f64544876b185705c29529939d00fffbb
MEDIUM: time: make the clock offset global and no per-thread

Since 1.8 for simplicity the time offset used to compensate for time
drift and jumps had been stored per thread. But with a global time,
the complexit has significantly increased.

What this patch does in order to address this is to get back to the
origins of the pre-thread time drift correction, and keep a single
offset between the system's date and the current global date.

The thread first verifies from the before_poll date if the time jumped
backwards or forward, then either fixes it by computing the new most
likely date, or applies the current offset to this latest system date.
In the first case, if the date is out of range, the old one is reused
with the max_wait offset or not depending on the interrupted flag.
Then it compares its date to the global date and updates both so that
both remain monotonic and that the local date always reflects the
latest known global date.

In order to support atomic updates to the offset, it's saved as a
ullong which contains both the tv_sec and tv_usec parts in its high
and low words. Note that a part of the patch comes from the inlining
of the equivalent of tv_add applied to the offset to make sure that
signed ints are permitted (otherwise it depends on how timeval is
defined).

This is significantly more reliable than the previous model as the
global time should move in a much smoother way, and not according
to what thread last updated it, and the thread-local time should
always be very close to the global one.

Note that (at least for debugging) a cheap way to measure processing
lag would consist in measuring the difference between global_now_ms
and now_ms, as long as other threads keep it up-to-date.
src/time.c