275. fetch_max — Track a High-Water Mark Without the Race
“Check if it’s bigger, then store it” is two operations — and another thread can sneak between them. fetch_max is the whole thing in one atomic call.
Tracking peak latency across worker threads looks harmless:
| |
Thread A reads 10, decides its 31 is a new peak. Thread B reads 10, decides its 50 is too. B stores 50, then A stores 31 — your peak just went down. Classic check-then-act race, and it’ll pass every test on your laptop.
The fix is one line:
| |
fetch_max compares and stores as a single atomic operation — no window for another thread to slip through. Like every fetch_* method it returns the previous value, which gives you new-record detection for free:
| |
fetch_min is the mirror image for low-water marks. One gotcha: initialize it to the identity for min — u64::MAX, not 0 — or nothing will ever be smaller than your starting value:
| |
This morning’s bite 274 covered fetch_update for arbitrary update rules — but check the shelf first: if your rule is just “keep the bigger one”, fetch_max is a single hardware-friendly call with no closure and no retry loop.
Available on all integer Atomic* types, stable since Rust 1.45.