From 385754c2d00ba3f4c74a22f55d4756e101f215b1 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Wed, 30 Sep 2026 03:17:59 +0100 Subject: Wait on the monotonic clock everywhere a deadline is waited for Review 004's timer fix (103) counted the deadlines on the monotonic clock, but the owner still slept until a wall-clock time: with the clock set back an hour a node's timers would stop for that hour. So would a wire's pause between tries, and a lone commit after a group would wait an hour for the others to join it. The test's LD_PRELOAD moves only what the process reads, so there each wait ended at once instead, and the timers went on ticking while the owner spun a core. core/wait.h makes conditions that wait on the monotonic clock (pthread_condattr_setclock; macOS keeps the wall clock) and deadlines on it. The owner's waits, the wire's pauses and the group commit's gathering use them. clock-back.so can now move the clock forward too (CLOCK_SHIFT_S), and check.py server_clocks moves it an hour each way under a node with a timer and a wire to a port no one listens on, and under a document server whose three threads commit together, then one alone. Before: back, 159 % CPU and 50,886 tries in 1.2 s; forward, 1 tick, 1 try, and a lone commit that never ended. After: 59 ticks, 0 % CPU, 4 tries and a lone commit of 2.6 ms, both ways. --- tests/clock-back.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'tests/clock-back.c') diff --git a/tests/clock-back.c b/tests/clock-back.c index 50870ca..2ab83e0 100644 --- a/tests/clock-back.c +++ b/tests/clock-back.c @@ -1,8 +1,12 @@ #define _GNU_SOURCE -/* LD_PRELOAD: the wall clock (CLOCK_REALTIME) set back an hour from - * CLOCK_BACK_MS milliseconds (200 unless given) after the process first - * asks for it, as a person or NTP may set it. A program's timers must go on - * all the same: they wait on the monotonic clock (tests/check.py). */ +/* LD_PRELOAD: the wall clock (CLOCK_REALTIME) set back an hour (moved + * CLOCK_SHIFT_S seconds: -3600 unless given) from CLOCK_BACK_MS milliseconds + * (200 unless given) after the process first asks for it, as a person or NTP + * may set it. Only what the process reads moves, so a wait until a deadline + * read from the wall clock ends at once (set back) or lasts an hour (set + * forward), as one would with the clock set the other way after it was read. + * A program's timers and waits must go on all the same: they count on the + * monotonic clock (tests/check.py). */ #include #include #include @@ -17,7 +21,7 @@ int clock_gettime(clockid_t id, struct timespec *t) { real(CLOCK_MONOTONIC, &now); long long ms = (long long)now.tv_sec * 1000 + now.tv_nsec / 1000000; if (began < 0) began = ms; - const char *after = getenv("CLOCK_BACK_MS"); - if (ms - began >= (after ? atoll(after) : 200)) t->tv_sec -= 3600; + const char *after = getenv("CLOCK_BACK_MS"), *shift = getenv("CLOCK_SHIFT_S"); + if (ms - began >= (after ? atoll(after) : 200)) t->tv_sec += shift ? atoll(shift) : -3600; return result; } -- cgit v1.2.3