The store-buffer litmus test showed a second axis exists: whether writes become visible and in order to other threads. We need a precise rule for this — not “eventually, probably”, but an exact statement of when one thread’s memory effects are guaranteed seen by another.

That rule is the happens-before relation. If action happens-before action , then ‘s memory effects are guaranteed visible to and is guaranteed ordered before . Visibility and ordering are not two separate guarantees — they are the two observable effects of this one relation.

You get a happens-before edge in exactly two ways, closed under transitivity:

  1. Program order — within a single thread, if is written before , then . (This is why single-threaded code always behaves.)
  2. Synchronizes-with — a synchronizing action in one thread creates an edge into a matching action in another. This is the only way to get an edge that crosses thread boundaries.
  3. Transitivity — if and then . Program-order edges chain through a cross-thread synchronizes-with edge to reach into the other thread.

The key insight: the litmus test had no synchronizes-with edge — only program-order edges, which say nothing across threads. No cross-thread edge → no visibility guarantee → both-read-0 is legal. To make one thread’s write visible to another you must manufacture a synchronizes-with edge. Happens-before is a causal, not literal-temporal, guarantee: it constrains what effects must appear, not the wall-clock order the CPU actually executes in.

See also

References

Questions

flashcards/stem/os

What does “A happens-before B” guarantee?::A’s memory effects are visible to B and A is ordered before B — visibility and ordering are the two observable effects of the one relation

What are the two kinds of happens-before edge, and which crosses threads?::Program order (within one thread) and synchronizes-with (across threads); only synchronizes-with crosses thread boundaries. Both are closed under transitivity

To make one thread’s write visible to another, you must manufacture a synchronizes-with edge; program order alone never crosses threads.

Happens-before is a causal guarantee, not a literal-temporal one — it constrains which effects must appear, not the CPU’s actual execution order.