atomic_compare_exchange_strong(), atomic_compare_exchange_strong_explicit(), atomic_compare_exchange_weak(), atomic_compare_exchange_weak_explicit()
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:
- If the atomic function is lock-free (see atomic_is_lock_free()), no extra library is required.
- If the function isn't lock-free, you need to link against libatomic. Use the -l atomic option to qcc to link against this 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:
Safety: | |
---|---|
Cancellation point | No |
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 a signal handler.