Memory Order Consume
§classic acq-rel pairing for inter-thread data sharing
One common pattern in concurrent programming is that a producer prepares some data, sets the signal; then, the consumer sees the signal and reads the data. The code looks like:
The recommended memory order to use here is
release for writing the
acquire for reading the
flag needs to be of atomic type as well, because it’s read/write concurrently. In contrast,
data needs not to be
Next we look at a variant of the above scenario, where
data is shared via a pointer.
One can continue use acq-rel pair as before. However, the use of dependent-load to retrieve data offers a lighter
synchronization. The only ordering we actually care is that
data is written before
data_ptr is updated. Nonetheless,
using acq-rel means all writes in T0 before
release are visible to T1 after
acquire; an overkill for this scenario.
consume is meant to resolve this, providing the minimal enough synchronization: only memory reads depending on the
release can see the writes from T0.
The following is an example to illustrate the difference between acq-rel and rel-consume.
x is read through a pointer
(dependent load), while
y is read directly. Therefore, rel-consume only guarantees
read_x gets the updated value,
but not necessarily
read_x == 1,
read_y == 1
read_x == 1,
read_y == 0 or 1