1 /* atomic operations */
2
3 /*
4 * Copyright (c) 1997-2015, Wind River Systems, Inc.
5 * Copyright (c) 2023 Nordic Semiconductor ASA
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #ifndef ZEPHYR_INCLUDE_SYS_ATOMIC_BUILTIN_H_
11 #define ZEPHYR_INCLUDE_SYS_ATOMIC_BUILTIN_H_
12
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <zephyr/sys/atomic_types.h>
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 /* Included from <atomic.h> */
22
atomic_cas(atomic_t * target,atomic_val_t old_value,atomic_val_t new_value)23 static inline bool atomic_cas(atomic_t *target, atomic_val_t old_value,
24 atomic_val_t new_value)
25 {
26 return __atomic_compare_exchange_n(target, &old_value, new_value,
27 0, __ATOMIC_SEQ_CST,
28 __ATOMIC_SEQ_CST);
29 }
30
atomic_ptr_cas(atomic_ptr_t * target,atomic_ptr_val_t old_value,atomic_ptr_val_t new_value)31 static inline bool atomic_ptr_cas(atomic_ptr_t *target, atomic_ptr_val_t old_value,
32 atomic_ptr_val_t new_value)
33 {
34 return __atomic_compare_exchange_n(target, &old_value, new_value,
35 0, __ATOMIC_SEQ_CST,
36 __ATOMIC_SEQ_CST);
37 }
38
atomic_add(atomic_t * target,atomic_val_t value)39 static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value)
40 {
41 return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST);
42 }
43
atomic_sub(atomic_t * target,atomic_val_t value)44 static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value)
45 {
46 return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST);
47 }
48
atomic_inc(atomic_t * target)49 static inline atomic_val_t atomic_inc(atomic_t *target)
50 {
51 return atomic_add(target, 1);
52 }
53
atomic_dec(atomic_t * target)54 static inline atomic_val_t atomic_dec(atomic_t *target)
55 {
56 return atomic_sub(target, 1);
57 }
58
atomic_get(const atomic_t * target)59 static inline atomic_val_t atomic_get(const atomic_t *target)
60 {
61 return __atomic_load_n(target, __ATOMIC_SEQ_CST);
62 }
63
atomic_ptr_get(const atomic_ptr_t * target)64 static inline atomic_ptr_val_t atomic_ptr_get(const atomic_ptr_t *target)
65 {
66 return __atomic_load_n(target, __ATOMIC_SEQ_CST);
67 }
68
atomic_set(atomic_t * target,atomic_val_t value)69 static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
70 {
71 /* This builtin, as described by Intel, is not a traditional
72 * test-and-set operation, but rather an atomic exchange operation. It
73 * writes value into *ptr, and returns the previous contents of *ptr.
74 */
75 return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST);
76 }
77
atomic_ptr_set(atomic_ptr_t * target,atomic_ptr_val_t value)78 static inline atomic_ptr_val_t atomic_ptr_set(atomic_ptr_t *target, atomic_ptr_val_t value)
79 {
80 return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST);
81 }
82
atomic_clear(atomic_t * target)83 static inline atomic_val_t atomic_clear(atomic_t *target)
84 {
85 return atomic_set(target, 0);
86 }
87
atomic_ptr_clear(atomic_ptr_t * target)88 static inline atomic_ptr_val_t atomic_ptr_clear(atomic_ptr_t *target)
89 {
90 return atomic_ptr_set(target, NULL);
91 }
92
atomic_or(atomic_t * target,atomic_val_t value)93 static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value)
94 {
95 return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST);
96 }
97
atomic_xor(atomic_t * target,atomic_val_t value)98 static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value)
99 {
100 return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST);
101 }
102
atomic_and(atomic_t * target,atomic_val_t value)103 static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value)
104 {
105 return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST);
106 }
107
atomic_nand(atomic_t * target,atomic_val_t value)108 static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value)
109 {
110 return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST);
111 }
112
113 #ifdef __cplusplus
114 }
115 #endif
116
117 #endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_BUILTIN_H_ */
118