diff options
author | Alexander Smirnov <[email protected]> | 2024-01-31 17:22:33 +0300 |
---|---|---|
committer | Alexander Smirnov <[email protected]> | 2024-01-31 17:22:33 +0300 |
commit | 52be5dbdd420165c68e7e90ba8f1d2f00da041f6 (patch) | |
tree | 5d47f5b2ff4e6a7c8e75d33931a1e683949b7229 /contrib/libs/cxxsupp/libcxxrt/atomic.h | |
parent | ea57c8867ceca391357c3c5ffcc5ba6738b49adc (diff) | |
parent | 809f0cf2fdfddfbeacc2256ffdbaaf5808ce5ed4 (diff) |
Merge branch 'mergelibs12' into main
Diffstat (limited to 'contrib/libs/cxxsupp/libcxxrt/atomic.h')
-rw-r--r-- | contrib/libs/cxxsupp/libcxxrt/atomic.h | 110 |
1 files changed, 92 insertions, 18 deletions
diff --git a/contrib/libs/cxxsupp/libcxxrt/atomic.h b/contrib/libs/cxxsupp/libcxxrt/atomic.h index afdbdd04d5d..701d05337cf 100644 --- a/contrib/libs/cxxsupp/libcxxrt/atomic.h +++ b/contrib/libs/cxxsupp/libcxxrt/atomic.h @@ -1,28 +1,102 @@ + #ifndef __has_builtin -#define __has_builtin(x) 0 +# define __has_builtin(x) 0 #endif #ifndef __has_feature -#define __has_feature(x) 0 +# define __has_feature(x) 0 +#endif +#ifndef __has_extension +# define __has_extension(x) 0 +#endif + +#if !__has_extension(c_atomic) +# define _Atomic(T) T #endif -/** - * Swap macro that enforces a happens-before relationship with a corresponding - * ATOMIC_LOAD. - */ #if __has_builtin(__c11_atomic_exchange) -#define ATOMIC_SWAP(addr, val)\ - __c11_atomic_exchange(reinterpret_cast<_Atomic(__typeof__(val))*>(addr), val, __ATOMIC_ACQ_REL) -#elif __has_builtin(__sync_swap) -#define ATOMIC_SWAP(addr, val)\ - __sync_swap(addr, val) +# define ATOMIC_BUILTIN(name) __c11_atomic_##name #else -#define ATOMIC_SWAP(addr, val)\ - __sync_lock_test_and_set(addr, val) +# define ATOMIC_BUILTIN(name) __atomic_##name##_n #endif -#if __has_builtin(__c11_atomic_load) -#define ATOMIC_LOAD(addr)\ - __c11_atomic_load(reinterpret_cast<_Atomic(__typeof__(*addr))*>(addr), __ATOMIC_ACQUIRE) +namespace +{ + /** + * C++11 memory orders. We only need a subset of them. + */ + enum memory_order + { + /** + * Acquire order. + */ + acquire = __ATOMIC_ACQUIRE, + + /** + * Release order. + */ + release = __ATOMIC_RELEASE, + + /** + * Sequentially consistent memory ordering. + */ + seqcst = __ATOMIC_SEQ_CST + }; + + /** + * Atomic, implements a subset of `std::atomic`. + */ + template<typename T> + class atomic + { + /** + * The underlying value. Use C11 atomic qualification if available. + */ + _Atomic(T) val; + + public: + /** + * Constructor, takes a value. + */ + atomic(T init) : val(init) {} + + /** + * Atomically load with the specified memory order. + */ + T load(memory_order order = memory_order::seqcst) + { + return ATOMIC_BUILTIN(load)(&val, order); + } + + /** + * Atomically store with the specified memory order. + */ + void store(T v, memory_order order = memory_order::seqcst) + { + return ATOMIC_BUILTIN(store)(&val, v, order); + } + + /** + * Atomically exchange with the specified memory order. + */ + T exchange(T v, memory_order order = memory_order::seqcst) + { + return ATOMIC_BUILTIN(exchange)(&val, v, order); + } + + /** + * Atomically exchange with the specified memory order. + */ + bool compare_exchange(T & expected, + T desired, + memory_order order = memory_order::seqcst) + { +#if __has_builtin(__c11_atomic_compare_exchange_strong) + return __c11_atomic_compare_exchange_strong( + &val, &expected, desired, order, order); #else -#define ATOMIC_LOAD(addr)\ - (__sync_synchronize(), *addr) + return __atomic_compare_exchange_n( + &val, &expected, desired, true, order, order); #endif + } + }; +} // namespace +#undef ATOMIC_BUILTIN |