DPDK  24.11.2
rte_stdatomic.h
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 */