]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libcxxrt/atomic.h
simd(7): add missing aarch64 SIMD functions
[FreeBSD/FreeBSD.git] / contrib / libcxxrt / atomic.h
1
2 #ifndef __has_builtin
3 #       define __has_builtin(x) 0
4 #endif
5 #ifndef __has_feature
6 #       define __has_feature(x) 0
7 #endif
8 #ifndef __has_extension
9 #       define __has_extension(x) 0
10 #endif
11
12 #if !__has_extension(c_atomic)
13 #       define _Atomic(T) T
14 #endif
15 #if __has_builtin(__c11_atomic_exchange)
16 #       define ATOMIC_BUILTIN(name) __c11_atomic_##name
17 #else
18 #       define ATOMIC_BUILTIN(name) __atomic_##name##_n
19 #endif
20
21 namespace
22 {
23         /**
24          * C++11 memory orders.  We only need a subset of them.
25          */
26         enum memory_order
27         {
28                 /**
29                  * Acquire order.
30                  */
31                 acquire = __ATOMIC_ACQUIRE,
32
33                 /**
34                  * Release order.
35                  */
36                 release = __ATOMIC_RELEASE,
37
38                 /**
39                  * Sequentially consistent memory ordering.
40                  */
41                 seqcst = __ATOMIC_SEQ_CST
42         };
43
44         /**
45          * Atomic, implements a subset of `std::atomic`.
46          */
47         template<typename T>
48         class atomic
49         {
50                 /**
51                  * The underlying value.  Use C11 atomic qualification if available.
52                  */
53                 _Atomic(T) val;
54
55                 public:
56                 /**
57                  * Constructor, takes a value.
58                  */
59                 atomic(T init) : val(init) {}
60
61                 /**
62                  * Atomically load with the specified memory order.
63                  */
64                 T load(memory_order order = memory_order::seqcst)
65                 {
66                         return ATOMIC_BUILTIN(load)(&val, order);
67                 }
68
69                 /**
70                  * Atomically store with the specified memory order.
71                  */
72                 void store(T v, memory_order order = memory_order::seqcst)
73                 {
74                         return ATOMIC_BUILTIN(store)(&val, v, order);
75                 }
76
77                 /**
78                  * Atomically exchange with the specified memory order.
79                  */
80                 T exchange(T v, memory_order order = memory_order::seqcst)
81                 {
82                         return ATOMIC_BUILTIN(exchange)(&val, v, order);
83                 }
84
85                 /**
86                  * Atomically exchange with the specified memory order.
87                  */
88                 bool compare_exchange(T &          expected,
89                                       T            desired,
90                                       memory_order order = memory_order::seqcst)
91                 {
92 #if __has_builtin(__c11_atomic_compare_exchange_strong)
93                         return __c11_atomic_compare_exchange_strong(
94                           &val, &expected, desired, order, order);
95 #else
96                         return __atomic_compare_exchange_n(
97                           &val, &expected, desired, true, order, order);
98 #endif
99                 }
100         };
101 } // namespace
102 #undef ATOMIC_BUILTIN