atomic_compare_exchange_strong(), atomic_compare_exchange_strong_explicit(), atomic_compare_exchange_weak(), atomic_compare_exchange_weak_explicit()

Updated: April 19, 2023

Compare and potentially exchange the value of an atomic object (C11)

Synopsis:

#include <stdatomic.h>

_Bool atomic_compare_exchange_strong(
         volatile A* obj,
         C* expected,
         C desired );

_Bool atomic_compare_exchange_strong_explicit(
         volatile A* obj,
         C* expected,
         C desired,
         memory_order succ );
         memory_order fail );

_Bool atomic_compare_exchange_weak(
         volatile A* obj,
         C* expected,
         C desired );

_Bool atomic_compare_exchange_weak_explicit(
         volatile A* obj,
         C* expected,
         C desired,
         memory_order succ );
         memory_order fail );

Arguments:

obj
A pointer to the atomic object (see the atomic_* types) whose value you want to compare.
expected
A pointer to the expected value for the object. The “C” represents the non-atomic data type that corresponds to the atomic object.
desired
The desired value for the object. The “C” represents the non-atomic data type that corresponds to the atomic object.
succ, fail
(atomic_compare_exchange_strong_explicit() and atomic_compare_exchange_weak_explicit() only) The memory_order to use for the read-modify-write and load operations, respectively.

Library:

Description:

The atomic_compare_exchange_*() functions are generic functions that atomically compare the value pointed to by obj with the value pointed to by expected, and if they're equal, replaces the former with desired (performing a read-modify-write operation). Otherwise, these function load the actual value pointed to by obj into *expected (performing a load operation).

The memory models for the read-modify-write and load operations are succ and fail, respectively. The atomic_compare_exchange_strong() and atomic_compare_exchange_weak() versions use memory_order_seq_cst.

The atomic_compare_exchange_weak() and atomic_compare_exchange_weak_explicit() functions are allowed to fail spuriously, that is, to act as if *obj != *expected, and set *expected to *obj, even if they're equal. When a compare-and-exchange is in a loop, the weak version yields better performance on some platforms. When a weak compare-and-exchange would require a loop and a strong one wouldn't, the strong one is preferable.

The implementation of atomic functions may depend on the architecture. For more information, see LL/SC vs LSE atomic operations in the description in Building Embedded Systems of the cpuinfo area of the system page.

Returns:

The result of the comparison: true if *obj was equal to *exp, false otherwise.

Classification:

C11

Safety:  
Cancellation point No
Interrupt handler Read the Caveats
Signal handler Read the Caveats
Thread Yes

Caveats:

If this function is lock-free (see atomic_is_lock_free()), it's safe to call it from an ISR or signal handler.