An atomic value carries a visibility guarantee
Start with `_Atomic(unsigned) x = 11`. Suppose one thread executes `++x; x = 31;` and another executes `unsigned y = x;`. If that read obtains the 31 written by the first thread, it synchronizes with the write. Effects that happened before the write are then visible to evaluations after the read—not merely the new value of `x`. section 21.1
Release semantics belong to the writer side of a synchronization; acquire semantics belong to the reader side. An operation that reads and writes can have acquire-release semantics. The direction matters: a release does not, by itself, make another thread observe anything. section 21.1
TAKEAWAY: establish the synchronization before relying on visibility.
- An acquire operation synchronizes with a release operation when it reads the value written by that release. section 21.1
- When that synchronization occurs, effects before the release must be visible at evaluations after the acquire. section 21.1
- A mutex provides another route: a newly acquired lock makes effects of previous critical sections protected by that mutex visible. section 21.2
Table 21.1 C library functions that form synchronization pairs
| Release | Acquire |
thrd_create(.., f, x) |
Entry to f(x) |
thrd_exit by thread id or return from f |
Start of tss_t destructors for id |
End of tss_t destructors for id |
thrd_join(id) or atexit/at_quick_exit handlers |
call_once(&obj, g), first call |
call_once(&obj, h), all subsequent calls |
| Mutex release | Mutex acquisition |
Synchronization is not confined to atomic expressions. The table pairs release and acquire events supplied by C library operations, including mutexes and thread lifecycle calls. section 21.2
Do not mistake a wake-up for visibility. A condition-variable wait releases its mutex before suspending and acquires it again on return; synchronization goes through the mutex, not the condition variable. Protect a signal and the associated non-atomic changes with the same mutex used by waiters. Explicit acquire-release consistency may cost less than the default sequential consistency of atomics, but choosing arguments for `_explicit` atomic functions requires a careful synchronization design. section 21.2 section 21.5



