eal: emit warning for unused trylock return value
[dpdk.git] / lib / eal / include / rte_bitops.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Arm Limited
3  */
4
5 #ifndef _RTE_BITOPS_H_
6 #define _RTE_BITOPS_H_
7
8 /**
9  * @file
10  * Bit Operations
11  *
12  * This file defines a family of APIs for bit operations
13  * without enforcing memory ordering.
14  */
15
16 #include <stdint.h>
17 #include <rte_debug.h>
18 #include <rte_compat.h>
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /**
25  * Get the uint64_t value for a specified bit set.
26  *
27  * @param nr
28  *   The bit number in range of 0 to 63.
29  */
30 #define RTE_BIT64(nr) (UINT64_C(1) << (nr))
31
32 /**
33  * Get the uint32_t value for a specified bit set.
34  *
35  * @param nr
36  *   The bit number in range of 0 to 31.
37  */
38 #define RTE_BIT32(nr) (UINT32_C(1) << (nr))
39
40 /*------------------------ 32-bit relaxed operations ------------------------*/
41
42 /**
43  * @warning
44  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
45  *
46  * Get the target bit from a 32-bit value without memory ordering.
47  *
48  * @param nr
49  *   The target bit to get.
50  * @param addr
51  *   The address holding the bit.
52  * @return
53  *   The target bit.
54  */
55 __rte_experimental
56 static inline uint32_t
57 rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr)
58 {
59         RTE_ASSERT(nr < 32);
60
61         uint32_t mask = UINT32_C(1) << nr;
62         return (*addr) & mask;
63 }
64
65 /**
66  * @warning
67  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
68  *
69  * Set the target bit in a 32-bit value to 1 without memory ordering.
70  *
71  * @param nr
72  *   The target bit to set.
73  * @param addr
74  *   The address holding the bit.
75  */
76 __rte_experimental
77 static inline void
78 rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr)
79 {
80         RTE_ASSERT(nr < 32);
81
82         uint32_t mask = RTE_BIT32(nr);
83         *addr = (*addr) | mask;
84 }
85
86 /**
87  * @warning
88  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
89  *
90  * Clear the target bit in a 32-bit value to 0 without memory ordering.
91  *
92  * @param nr
93  *   The target bit to clear.
94  * @param addr
95  *   The address holding the bit.
96  */
97 __rte_experimental
98 static inline void
99 rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr)
100 {
101         RTE_ASSERT(nr < 32);
102
103         uint32_t mask = RTE_BIT32(nr);
104         *addr = (*addr) & (~mask);
105 }
106
107 /**
108  * @warning
109  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
110  *
111  * Return the original bit from a 32-bit value, then set it to 1 without
112  * memory ordering.
113  *
114  * @param nr
115  *   The target bit to get and set.
116  * @param addr
117  *   The address holding the bit.
118  * @return
119  *   The original bit.
120  */
121 __rte_experimental
122 static inline uint32_t
123 rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr)
124 {
125         RTE_ASSERT(nr < 32);
126
127         uint32_t mask = RTE_BIT32(nr);
128         uint32_t val = *addr;
129         *addr = val | mask;
130         return val & mask;
131 }
132
133 /**
134  * @warning
135  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
136  *
137  * Return the original bit from a 32-bit value, then clear it to 0 without
138  * memory ordering.
139  *
140  * @param nr
141  *   The target bit to get and clear.
142  * @param addr
143  *   The address holding the bit.
144  * @return
145  *   The original bit.
146  */
147 __rte_experimental
148 static inline uint32_t
149 rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr)
150 {
151         RTE_ASSERT(nr < 32);
152
153         uint32_t mask = RTE_BIT32(nr);
154         uint32_t val = *addr;
155         *addr = val & (~mask);
156         return val & mask;
157 }
158
159 /*------------------------ 64-bit relaxed operations ------------------------*/
160
161 /**
162  * @warning
163  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
164  *
165  * Get the target bit from a 64-bit value without memory ordering.
166  *
167  * @param nr
168  *   The target bit to get.
169  * @param addr
170  *   The address holding the bit.
171  * @return
172  *   The target bit.
173  */
174 __rte_experimental
175 static inline uint64_t
176 rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr)
177 {
178         RTE_ASSERT(nr < 64);
179
180         uint64_t mask = RTE_BIT64(nr);
181         return (*addr) & mask;
182 }
183
184 /**
185  * @warning
186  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
187  *
188  * Set the target bit in a 64-bit value to 1 without memory ordering.
189  *
190  * @param nr
191  *   The target bit to set.
192  * @param addr
193  *   The address holding the bit.
194  */
195 __rte_experimental
196 static inline void
197 rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr)
198 {
199         RTE_ASSERT(nr < 64);
200
201         uint64_t mask = RTE_BIT64(nr);
202         (*addr) = (*addr) | mask;
203 }
204
205 /**
206  * @warning
207  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
208  *
209  * Clear the target bit in a 64-bit value to 0 without memory ordering.
210  *
211  * @param nr
212  *   The target bit to clear.
213  * @param addr
214  *   The address holding the bit.
215  */
216 __rte_experimental
217 static inline void
218 rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr)
219 {
220         RTE_ASSERT(nr < 64);
221
222         uint64_t mask = RTE_BIT64(nr);
223         *addr = (*addr) & (~mask);
224 }
225
226 /**
227  * @warning
228  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
229  *
230  * Return the original bit from a 64-bit value, then set it to 1 without
231  * memory ordering.
232  *
233  * @param nr
234  *   The target bit to get and set.
235  * @param addr
236  *   The address holding the bit.
237  * @return
238  *   The original bit.
239  */
240 __rte_experimental
241 static inline uint64_t
242 rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr)
243 {
244         RTE_ASSERT(nr < 64);
245
246         uint64_t mask = RTE_BIT64(nr);
247         uint64_t val = *addr;
248         *addr = val | mask;
249         return val;
250 }
251
252 /**
253  * @warning
254  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
255  *
256  * Return the original bit from a 64-bit value, then clear it to 0 without
257  * memory ordering.
258  *
259  * @param nr
260  *   The target bit to get and clear.
261  * @param addr
262  *   The address holding the bit.
263  * @return
264  *   The original bit.
265  */
266 __rte_experimental
267 static inline uint64_t
268 rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr)
269 {
270         RTE_ASSERT(nr < 64);
271
272         uint64_t mask = RTE_BIT64(nr);
273         uint64_t val = *addr;
274         *addr = val & (~mask);
275         return val & mask;
276 }
277
278 #ifdef __cplusplus
279 }
280 #endif
281
282 #endif /* _RTE_BITOPS_H_ */