Explain thread safety in Counter::inc

This commit is contained in:
2025-08-30 19:14:16 -04:00
parent f560ac1736
commit b52d6e5a13

View File

@@ -379,8 +379,20 @@ struct Metric {
Counter::Counter() = default;
void Counter::inc(double x) {
// DESIGN: Single writer, but render thread reads concurrently
// Need atomic store since render thread reads without writer's coordination
// THREAD-SAFETY: This method mixes a non-atomic read and an atomic store
// which is safe ONLY under the following conditions, which this system meets:
//
// 1. Single-Writer Guarantee: The underlying Counter::State is thread-local.
// Only one thread will ever call inc() on a given instance. All writes
// and the non-atomic read below are therefore *sequenced*, not concurrent,
// preventing torn reads within this thread.
//
// 2. Atomic Visibility: The render thread is the only other thread that
// accesses this value, and it does so via an atomic load. A concurrent
// non-atomic read (writer) and atomic read (renderer) is not a data race.
//
// This contrasts with Gauges, whose state can be shared by multiple threads
// and thus requires a fully atomic read-modify-write cycle (CAS loop).
auto new_value = p->value + x;
// Validate monotonic property (counter never decreases)