EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
env_atomic.h
1/*
2 * Copyright (c) 2013-2026, Nokia Solutions and Networks
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of the copyright holder nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/*
32 * env helper include file - don't include this file directly,
33 * instead #include "environment.h"
34 */
35
36#ifndef _ENV_ATOMIC_H_
37#define _ENV_ATOMIC_H_
38
39#pragma GCC visibility push(default)
40
41#include <stdint.h>
42
43#include <event_machine/platform/env/env_conf.h>
44#include <event_machine/platform/env/env_macros.h>
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50#if ENV_DEPRECATED_API
51
52/*
53 * Atomic operations - types & functions
54 */
55struct _env_atomic32 {
56 uint32_t a32; /**< Storage for the atomic variable */
57} ENV_ALIGNED(sizeof(uint32_t)); /* Enforce alignment! */
58
59struct _env_atomic64 {
60 uint64_t a64; /**< Storage for the atomic variable */
61} ENV_ALIGNED(sizeof(uint64_t)); /* Enforce alignment! */
62
63typedef struct _env_atomic32 env_atomic32_t;
64typedef struct _env_atomic64 env_atomic64_t;
65
66/*
67 * 32 bit functions
68 */
69static inline void
70env_atomic32_init(env_atomic32_t *atom)
71{
72 __atomic_store_n(&atom->a32, 0, __ATOMIC_SEQ_CST);
73}
74
75static inline void
76env_atomic32_set(env_atomic32_t *atom, uint32_t new_val)
77{
78 __atomic_store_n(&atom->a32, new_val, __ATOMIC_SEQ_CST);
79}
80
81static inline uint32_t
82env_atomic32_get(const env_atomic32_t *atom)
83{
84 return __atomic_load_n(&atom->a32, __ATOMIC_SEQ_CST);
85}
86
87static inline void
88env_atomic32_dec(env_atomic32_t *atom)
89{
90 (void)__atomic_fetch_sub(&atom->a32, 1, __ATOMIC_SEQ_CST);
91}
92
93static inline void
94env_atomic32_inc(env_atomic32_t *atom)
95{
96 (void)__atomic_fetch_add(&atom->a32, 1, __ATOMIC_SEQ_CST);
97}
98
99static inline void
100env_atomic32_add(env_atomic32_t *atom, uint32_t add_val)
101{
102 (void)__atomic_fetch_add(&atom->a32, add_val, __ATOMIC_SEQ_CST);
103}
104
105static inline void
106env_atomic32_sub(env_atomic32_t *atom, uint32_t sub_val)
107{
108 (void)__atomic_fetch_sub(&atom->a32, sub_val, __ATOMIC_SEQ_CST);
109}
110
111static inline uint32_t
112env_atomic32_add_return(env_atomic32_t *atom, uint32_t add_val)
113{
114 return __atomic_add_fetch(&atom->a32, add_val, __ATOMIC_SEQ_CST);
115}
116
117static inline uint32_t
118env_atomic32_return_add(env_atomic32_t *atom, uint32_t add_val)
119{
120 return __atomic_fetch_add(&atom->a32, add_val, __ATOMIC_SEQ_CST);
121}
122
123static inline uint32_t
124env_atomic32_sub_return(env_atomic32_t *atom, uint32_t sub_val)
125{
126 return __atomic_sub_fetch(&atom->a32, sub_val, __ATOMIC_SEQ_CST);
127}
128
129static inline uint32_t
130env_atomic32_return_sub(env_atomic32_t *atom, uint32_t sub_val)
131{
132 return __atomic_fetch_sub(&atom->a32, sub_val, __ATOMIC_SEQ_CST);
133}
134
135static inline int
136env_atomic32_cmpset(env_atomic32_t *atom, uint32_t expected, uint32_t desired)
137{
138 return __atomic_compare_exchange_n(&atom->a32, &expected, desired,
139 0 /*strong*/, __ATOMIC_SEQ_CST,
140 __ATOMIC_SEQ_CST);
141}
142
143static inline uint32_t
144env_atomic32_exchange(env_atomic32_t *atom, uint32_t new_val)
145{
146 return __atomic_exchange_n(&atom->a32, new_val, __ATOMIC_SEQ_CST);
147}
148
149static inline void
150env_atomic32_set_bits(env_atomic32_t *atom, uint32_t bit_mask)
151{
152 uint32_t old_val;
153 uint32_t new_val;
154 int ret;
155
156 do {
157 old_val = env_atomic32_get(atom);
158 new_val = old_val | bit_mask;
159 ret = env_atomic32_cmpset(atom, old_val, new_val);
160 } while (ret == 0);
161}
162
163static inline void
164env_atomic32_clr_bits(env_atomic32_t *atom, uint32_t bit_mask)
165{
166 uint32_t old_val;
167 uint32_t new_val;
168 int ret;
169
170 do {
171 old_val = env_atomic32_get(atom);
172 new_val = old_val & (~bit_mask);
173 ret = env_atomic32_cmpset(atom, old_val, new_val);
174 } while (ret == 0);
175}
176
177static inline int
178env_atomic32_cnt_bits(const env_atomic32_t *atom)
179{
180 return __builtin_popcount(env_atomic32_get(atom));
181}
182
183/*
184 * 64 bit functions
185 */
186static inline void
187env_atomic64_init(env_atomic64_t *atom)
188{
189 __atomic_store_n(&atom->a64, 0, __ATOMIC_SEQ_CST);
190}
191
192static inline void
193env_atomic64_set(env_atomic64_t *atom, uint64_t new_val)
194{
195 __atomic_store_n(&atom->a64, new_val, __ATOMIC_SEQ_CST);
196}
197
198static inline uint64_t
199env_atomic64_get(const env_atomic64_t *atom)
200{
201 return __atomic_load_n(&atom->a64, __ATOMIC_SEQ_CST);
202}
203
204static inline void
205env_atomic64_dec(env_atomic64_t *atom)
206{
207 (void)__atomic_fetch_sub(&atom->a64, 1, __ATOMIC_SEQ_CST);
208}
209
210static inline void
211env_atomic64_inc(env_atomic64_t *atom)
212{
213 (void)__atomic_fetch_add(&atom->a64, 1, __ATOMIC_SEQ_CST);
214}
215
216static inline void
217env_atomic64_add(env_atomic64_t *atom, uint64_t add_val)
218{
219 (void)__atomic_fetch_add(&atom->a64, add_val, __ATOMIC_SEQ_CST);
220}
221
222static inline void
223env_atomic64_sub(env_atomic64_t *atom, uint64_t sub_val)
224{
225 (void)__atomic_fetch_sub(&atom->a64, sub_val, __ATOMIC_SEQ_CST);
226}
227
228static inline uint64_t
229env_atomic64_add_return(env_atomic64_t *atom, uint64_t add_val)
230{
231 return __atomic_add_fetch(&atom->a64, add_val, __ATOMIC_SEQ_CST);
232}
233
234static inline uint64_t
235env_atomic64_return_add(env_atomic64_t *atom, uint64_t add_val)
236{
237 return __atomic_fetch_add(&atom->a64, add_val, __ATOMIC_SEQ_CST);
238}
239
240static inline uint64_t
241env_atomic64_sub_return(env_atomic64_t *atom, uint64_t sub_val)
242{
243 return __atomic_sub_fetch(&atom->a64, sub_val, __ATOMIC_SEQ_CST);
244}
245
246static inline uint64_t
247env_atomic64_return_sub(env_atomic64_t *atom, uint64_t sub_val)
248{
249 return __atomic_fetch_sub(&atom->a64, sub_val, __ATOMIC_SEQ_CST);
250}
251
252static inline int
253env_atomic64_cmpset(env_atomic64_t *atom, uint64_t expected, uint64_t desired)
254{
255 return __atomic_compare_exchange_n(&atom->a64, &expected, desired,
256 0 /*strong*/, __ATOMIC_SEQ_CST,
257 __ATOMIC_SEQ_CST);
258}
259
260static inline uint64_t
261env_atomic64_exchange(env_atomic64_t *atom, uint64_t new_val)
262{
263 return __atomic_exchange_n(&atom->a64, new_val, __ATOMIC_SEQ_CST);
264}
265
266static inline void
267env_atomic64_set_bits(env_atomic64_t *atom, uint64_t bit_mask)
268{
269 uint64_t old_val;
270 uint64_t new_val;
271 int ret;
272
273 do {
274 old_val = env_atomic64_get(atom);
275 new_val = old_val | bit_mask;
276 ret = env_atomic64_cmpset(atom, old_val, new_val);
277 } while (ret == 0);
278}
279
280static inline void
281env_atomic64_clr_bits(env_atomic64_t *atom, uint64_t bit_mask)
282{
283 uint64_t old_val;
284 uint64_t new_val;
285 int ret;
286
287 do {
288 old_val = env_atomic64_get(atom);
289 new_val = old_val & (~bit_mask);
290 ret = env_atomic64_cmpset(atom, old_val, new_val);
291 } while (ret == 0);
292}
293
294static inline int
295env_atomic64_cnt_bits(const env_atomic64_t *atom)
296{
297 return __builtin_popcountll(env_atomic64_get(atom));
298}
299
300#endif
301
302#ifdef __cplusplus
303}
304#endif
305#pragma GCC visibility pop
306#endif /* _ENV_ATOMIC_H_ */