A producer fills a buffer then sets a ready flag with a release store. A consumer spins on the flag with an acquire load and then reads the buffer. State exactly what this guarantees and what it does not, and say what breaks if both operations are made relaxed.

A producer fills a buffer then sets a ready flag with a release store. A consumer spins on the flag with an acquire load and then reads the buffer. State exactly what this guarantees and what it does not, and say what breaks if both operations are made relaxed.

Approach: Write down the synchronises-with relation the release store and the acquire load create, then ask which writes it orders and which it says nothing about.

When the acquire load reads the value written by the release store the two synchronise, so every write the producer performed before its release store is visible to the consumer after its acquire load, which covers the buffer contents and says nothing about writes the producer makes afterwards or about the ordering seen by any third thread. The guarantee is pairwise and one directional, ordering the producer earlier writes against the consumer later reads, and it gives no single total order across all threads the way sequential consistency does. Under relaxed ordering on both, the compiler or the processor may sink the buffer writes below the flag store or hoist the buffer reads above the flag load, so the consumer can see the flag set and read stale or half written data. On x86 the hardware would usually preserve those store orders while the compiler still would not, which is how the bug appears only after an optimisation level changes.

Follow-up: How does the answer change if a third thread also writes the flag with a release store?

Key concepts: release store, acquire load, synchronises-with, relaxed ordering.