xref: /dpdk/lib/eal/include/rte_stdatomic.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2023 Microsoft Corporation
3  */
4 
5 #ifndef RTE_STDATOMIC_H
6 #define RTE_STDATOMIC_H
7 
8 #include <assert.h>
9 
10 #ifdef RTE_ENABLE_STDATOMIC
11 #ifndef _MSC_VER
12 #ifdef __STDC_NO_ATOMICS__
13 #error enable_stdatomic=true but atomics not supported by toolchain
14 #endif
15 #endif
16 
17 #include <stdatomic.h>
18 
19 /* RTE_ATOMIC(type) is provided for use as a type specifier
20  * permitting designation of an rte atomic type.
21  */
22 #define RTE_ATOMIC(type) _Atomic(type)
23 
24 /* __rte_atomic is provided for type qualification permitting
25  * designation of an rte atomic qualified type-name.
26  */
27 #define __rte_atomic _Atomic
28 
29 /* The memory order is an enumerated type in C11. */
30 typedef memory_order rte_memory_order;
31 
32 #define rte_memory_order_relaxed memory_order_relaxed
33 #ifdef __ATOMIC_RELAXED
34 static_assert(rte_memory_order_relaxed == __ATOMIC_RELAXED,
35 	"rte_memory_order_relaxed == __ATOMIC_RELAXED");
36 #endif
37 
38 #define rte_memory_order_consume memory_order_consume
39 #ifdef __ATOMIC_CONSUME
40 static_assert(rte_memory_order_consume == __ATOMIC_CONSUME,
41 	"rte_memory_order_consume == __ATOMIC_CONSUME");
42 #endif
43 
44 #define rte_memory_order_acquire memory_order_acquire
45 #ifdef __ATOMIC_ACQUIRE
46 static_assert(rte_memory_order_acquire == __ATOMIC_ACQUIRE,
47 	"rte_memory_order_acquire == __ATOMIC_ACQUIRE");
48 #endif
49 
50 #define rte_memory_order_release memory_order_release
51 #ifdef __ATOMIC_RELEASE
52 static_assert(rte_memory_order_release == __ATOMIC_RELEASE,
53 	"rte_memory_order_release == __ATOMIC_RELEASE");
54 #endif
55 
56 #define rte_memory_order_acq_rel memory_order_acq_rel
57 #ifdef __ATOMIC_ACQ_REL
58 static_assert(rte_memory_order_acq_rel == __ATOMIC_ACQ_REL,
59 	"rte_memory_order_acq_rel == __ATOMIC_ACQ_REL");
60 #endif
61 
62 #define rte_memory_order_seq_cst memory_order_seq_cst
63 #ifdef __ATOMIC_SEQ_CST
64 static_assert(rte_memory_order_seq_cst == __ATOMIC_SEQ_CST,
65 	"rte_memory_order_seq_cst == __ATOMIC_SEQ_CST");
66 #endif
67 
68 #define rte_atomic_load_explicit(ptr, memorder) \
69 	atomic_load_explicit(ptr, memorder)
70 
71 #define rte_atomic_store_explicit(ptr, val, memorder) \
72 	atomic_store_explicit(ptr, val, memorder)
73 
74 #define rte_atomic_exchange_explicit(ptr, val, memorder) \
75 	atomic_exchange_explicit(ptr, val, memorder)
76 
77 #define rte_atomic_compare_exchange_strong_explicit(ptr, expected, desired, \
78 		succ_memorder, fail_memorder) \
79 	atomic_compare_exchange_strong_explicit(ptr, expected, desired, \
80 		succ_memorder, fail_memorder)
81 
82 #define rte_atomic_compare_exchange_weak_explicit(ptr, expected, desired, \
83 		succ_memorder, fail_memorder) \
84 	atomic_compare_exchange_weak_explicit(ptr, expected, desired, \
85 		succ_memorder, fail_memorder)
86 
87 #define rte_atomic_fetch_add_explicit(ptr, val, memorder) \
88 	atomic_fetch_add_explicit(ptr, val, memorder)
89 
90 #define rte_atomic_fetch_sub_explicit(ptr, val, memorder) \
91 	atomic_fetch_sub_explicit(ptr, val, memorder)
92 
93 #define rte_atomic_fetch_and_explicit(ptr, val, memorder) \
94 	atomic_fetch_and_explicit(ptr, val, memorder)
95 
96 #define rte_atomic_fetch_xor_explicit(ptr, val, memorder) \
97 	atomic_fetch_xor_explicit(ptr, val, memorder)
98 
99 #define rte_atomic_fetch_or_explicit(ptr, val, memorder) \
100 	atomic_fetch_or_explicit(ptr, val, memorder)
101 
102 #define rte_atomic_fetch_nand_explicit(ptr, val, memorder) \
103 	atomic_fetch_nand_explicit(ptr, val, memorder)
104 
105 #define rte_atomic_flag_test_and_set_explicit(ptr, memorder) \
106 	atomic_flag_test_and_set_explicit(ptr, memorder)
107 
108 #define rte_atomic_flag_clear_explicit(ptr, memorder) \
109 	atomic_flag_clear_explicit(ptr, memorder)
110 
111 /* We provide internal macro here to allow conditional expansion
112  * in the body of the per-arch rte_atomic_thread_fence inline functions.
113  */
114 #define __rte_atomic_thread_fence(memorder) \
115 	atomic_thread_fence(memorder)
116 
117 #else /* !RTE_ENABLE_STDATOMIC */
118 
119 #define RTE_ATOMIC(type) type
120 
121 #define __rte_atomic
122 
123 /* The memory order is an integer type in GCC built-ins,
124  * not an enumerated type like in C11.
125  */
126 typedef int rte_memory_order;
127 
128 #define rte_memory_order_relaxed __ATOMIC_RELAXED
129 #define rte_memory_order_consume __ATOMIC_CONSUME
130 #define rte_memory_order_acquire __ATOMIC_ACQUIRE
131 #define rte_memory_order_release __ATOMIC_RELEASE
132 #define rte_memory_order_acq_rel __ATOMIC_ACQ_REL
133 #define rte_memory_order_seq_cst __ATOMIC_SEQ_CST
134 
135 #define rte_atomic_load_explicit(ptr, memorder) \
136 	__atomic_load_n(ptr, memorder)
137 
138 #define rte_atomic_store_explicit(ptr, val, memorder) \
139 	__atomic_store_n(ptr, val, memorder)
140 
141 #define rte_atomic_exchange_explicit(ptr, val, memorder) \
142 	__atomic_exchange_n(ptr, val, memorder)
143 
144 #define rte_atomic_compare_exchange_strong_explicit(ptr, expected, desired, \
145 		succ_memorder, fail_memorder) \
146 	__atomic_compare_exchange_n(ptr, expected, desired, 0, \
147 		succ_memorder, fail_memorder)
148 
149 #define rte_atomic_compare_exchange_weak_explicit(ptr, expected, desired, \
150 		succ_memorder, fail_memorder) \
151 	__atomic_compare_exchange_n(ptr, expected, desired, 1, \
152 		succ_memorder, fail_memorder)
153 
154 #define rte_atomic_fetch_add_explicit(ptr, val, memorder) \
155 	__atomic_fetch_add(ptr, val, memorder)
156 
157 #define rte_atomic_fetch_sub_explicit(ptr, val, memorder) \
158 	__atomic_fetch_sub(ptr, val, memorder)
159 
160 #define rte_atomic_fetch_and_explicit(ptr, val, memorder) \
161 	__atomic_fetch_and(ptr, val, memorder)
162 
163 #define rte_atomic_fetch_xor_explicit(ptr, val, memorder) \
164 	__atomic_fetch_xor(ptr, val, memorder)
165 
166 #define rte_atomic_fetch_or_explicit(ptr, val, memorder) \
167 	__atomic_fetch_or(ptr, val, memorder)
168 
169 #define rte_atomic_fetch_nand_explicit(ptr, val, memorder) \
170 	__atomic_fetch_nand(ptr, val, memorder)
171 
172 #define rte_atomic_flag_test_and_set_explicit(ptr, memorder) \
173 	__atomic_test_and_set(ptr, memorder)
174 
175 #define rte_atomic_flag_clear_explicit(ptr, memorder) \
176 	__atomic_clear(ptr, memorder)
177 
178 /* We provide internal macro here to allow conditional expansion
179  * in the body of the per-arch rte_atomic_thread_fence inline functions.
180  */
181 #define __rte_atomic_thread_fence(memorder) \
182 	__atomic_thread_fence(memorder)
183 
184 #endif
185 
186 #endif /* RTE_STDATOMIC_H */
187