Memory Models & Atomics

a read-modify-write operation (fetch_add, compare_exchange)

/ RMW -> ar-em-DUB-uhl-yoo /

A read-modify-write is an atomic operation that reads the current value, computes a new one from it, and writes it back — all as one indivisible step that no other thread can split. This is strictly more powerful than a plain atomic load or a plain atomic store, because those two alone cannot safely express 'increment' or 'swap if unchanged': between your load and your store some other thread could sneak in. The RMW fuses the gap shut.

The everyday RMWs are: fetch_add / fetch_sub / fetch_or / fetch_and (read the old value, apply the operation, store the result, and return the OLD value atomically); exchange (atomically write a new value and return the old one); and the crown jewel, compare_exchange. A compare-exchange (CAS) takes an expected value and a desired value: atomically, IF the location currently equals expected, it stores desired and reports success; otherwise it loads the actual current value into expected and reports failure. There are two forms — compare_exchange_strong never fails spuriously, while compare_exchange_weak is allowed to fail even when the values matched, which is cheaper on load-linked/store-conditional hardware (ARM, POWER) and so is the right choice inside a retry loop.

RMWs are the atomic muscle behind almost every lock and lock-free structure: a mutex is built from an exchange or CAS, a reference count from fetch_add/fetch_sub, a lock-free stack push from a CAS loop. Each RMW carries its own memory_order (often acq_rel so it both consumes prior publishes and publishes its own result). One sharp hazard appears here: a CAS can succeed because the value looks unchanged even though it was changed and changed back — the ABA problem (treated fully in the lock-free field).

int expected = atomic_load(&top); int desired; do { desired = expected + 1; } while (!atomic_compare_exchange_weak(&top, &expected, desired)); /* on failure, 'expected' is auto-refreshed with the current value, so we just retry */

The CAS retry loop: weak CAS auto-reloads expected on failure, making the do/while the idiomatic shape.

Use compare_exchange_weak inside a loop (its spurious failures cost nothing there) and compare_exchange_strong for a one-shot check; and never read 'CAS succeeded' as 'nothing touched this in between' — that is exactly the ABA trap.

Also called
RMWatomic CAS讀改寫操作