MEDIUM: clock: replace timeval "now" with integer "now_ns"
This puts an end to the occasional confusion between the "now" date
that is internal, monotonic and not synchronized with the system's
date, and "date" which is the system's date and not necessarily
monotonic. Variable "now" was removed and replaced with a 64-bit
integer "now_ns" which is a counter of nanoseconds. It wraps every
585 years, so if all goes well (i.e. if humanity does not need
haproxy anymore in 500 years), it will just never wrap. This implies
that now_ns is never nul and that the zero value can reliably be used
as "not set yet" for a timestamp if needed. This will also simplify
date checks where it becomes possible again to do "date1<date2".
All occurrences of "tv_to_ns(&now)" were simply replaced by "now_ns".
Due to the intricacies between now, global_now and now_offset, all 3
had to be turned to nanoseconds at once. It's not a problem since all
of them were solely used in 3 functions in clock.c, but they make the
patch look bigger than it really is.
The clock_update_local_date() and clock_update_global_date() functions
are now much simpler as there's no need anymore to perform conversions
nor to round the timeval up or down.
The wrapping continues to happen by presetting the internal offset in
the short future so that the 32-bit now_ms continues to wrap 20 seconds
after boot.
The start_time used to calculate uptime can still be turned to
nanoseconds now. One interrogation concerns global_now_ms which is used
only for the freq counters. It's unclear whether there's more value in
using two variables that need to be synchronized sequentially like today
or to just use global_now_ns divided by 1 million. Both approaches will
work equally well on modern systems, the difference might come from
smaller ones. Better not change anyhting for now.
One benefit of the new approach is that we now have an internal date
with a resolution of the nanosecond and the precision of the microsecond,
which can be useful to extend some measurements given that timestamps
also have this resolution.
diff --git a/src/check.c b/src/check.c
index 5dd3b89..d894c3c 100644
--- a/src/check.c
+++ b/src/check.c
@@ -471,7 +471,7 @@
if (status == HCHK_STATUS_START) {
check->result = CHK_RES_UNKNOWN; /* no result yet */
check->desc[0] = '\0';
- check->start = tv_to_ns(&now);
+ check->start = now_ns;
return;
}
@@ -492,7 +492,7 @@
check->duration = -1;
else if (check->start) {
/* set_server_check_status() may be called more than once */
- check->duration = ns_to_ms(tv_to_ns(&now) - check->start);
+ check->duration = ns_to_ms(now_ns - check->start);
check->start = 0;
}
@@ -1029,9 +1029,9 @@
s->queue.length);
if ((s->cur_state == SRV_ST_STARTING) &&
- ns_to_sec(tv_to_ns(&now)) < s->last_change + s->slowstart &&
- ns_to_sec(tv_to_ns(&now)) >= s->last_change) {
- ratio = MAX(1, 100 * (ns_to_sec(tv_to_ns(&now)) - s->last_change) / s->slowstart);
+ ns_to_sec(now_ns) < s->last_change + s->slowstart &&
+ ns_to_sec(now_ns) >= s->last_change) {
+ ratio = MAX(1, 100 * (ns_to_sec(now_ns) - s->last_change) / s->slowstart);
chunk_appendf(buf, "; throttle=%d%%", ratio);
}
@@ -1499,7 +1499,7 @@
/* check this every ms */
t->expire = tick_add(now_ms, MS_TO_TICKS(mininter * srvpos / nbcheck));
- check->start = tv_to_ns(&now);
+ check->start = now_ns;
task_queue(t);
return 1;