The note gives a clue, referring to LL/SC architectures. From the Wikipedia article:
If any updates have occurred, the store-conditional is guaranteed to fail, even if the value read by the load-link has since been restored. As such, an LL/SC pair is stronger than a read followed by a compare-and-swap (CAS), which will not detect updates if the old value has been restored (see ABA problem).
Real implementations of LL/SC do not always succeed if there are no concurrent updates to the memory location in question. Any exceptional events between the two operations, such as a context switch, another load-link, or even (on many platforms) another load or store operation, will cause the store-conditional to spuriously fail.
On LL/SC chips the compare_exchange
will be implemented in terms of LL/SC, which can spuriously fail, so compare_exchange_strong
needs extra overhead to retry in the case of failure. Providing both compare_exchange_strong
and compare_exchange_weak
allows the programmer to decide whether they want the library to handle spurious failures (in which case they’d use compare_exchange_strong
) or if they want to handle it in their own code (in which case they’d use compare_exchange_weak
)