Я считаю, что нет портативного способа сделать это, в основном потому, что в C ++ atomic
s может быть реализован с блокировкой (или вообще sizeof(T)
! = sizeof(atomic<T>)
).
Как вы упомянули, вы можете использовать встроенные функции GCC. Они также используются libstdc++
для реализации std::atomic<Integral>
, поэтому, когда вам нужно реализовать эквивалент std::atomic
метода, вы можете взглянуть на bits/atomic_base.h
.
Для atomic::compare_exchange_strong
:
_GLIBCXX_ALWAYS_INLINE bool
compare_exchange_strong(__int_type& __i1, __int_type __i2,
memory_order __m1,
memory_order __m2) volatile noexcept
{
memory_order __b2 = __m2 & __memory_order_mask;
memory_order __b1 = __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
}
РЕДАКТИРОВАТЬ: Адаптация из предыдущего кода:
int atomicCAS(int* address, int *compare, int val)
{
return __atomic_compare_exchange_n(address, compare, val, 0,
__ATOMIC_SEQ_CST,
__ATOMIC_ACQUIRE);
}
Обратите внимание, что compare
является аргументом in-out, при сбое он будет перезаписан с текущим значением *address
.
Эта версия эквивалентна atomic<int>::compare_exchange_strong
с упорядочением памяти по умолчанию, см. godbolt .