summaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxxrt/atomic.h
diff options
context:
space:
mode:
authorAlexander Smirnov <[email protected]>2024-01-31 17:22:33 +0300
committerAlexander Smirnov <[email protected]>2024-01-31 17:22:33 +0300
commit52be5dbdd420165c68e7e90ba8f1d2f00da041f6 (patch)
tree5d47f5b2ff4e6a7c8e75d33931a1e683949b7229 /contrib/libs/cxxsupp/libcxxrt/atomic.h
parentea57c8867ceca391357c3c5ffcc5ba6738b49adc (diff)
parent809f0cf2fdfddfbeacc2256ffdbaaf5808ce5ed4 (diff)
Merge branch 'mergelibs12' into main
Diffstat (limited to 'contrib/libs/cxxsupp/libcxxrt/atomic.h')
-rw-r--r--contrib/libs/cxxsupp/libcxxrt/atomic.h110
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