1 /* This file is derived from clang's stdatomic.h */
3 /*===---- stdatomic.h - Standard header for atomic types and operations -----===
5 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 * See https://llvm.org/LICENSE.txt for license information.
7 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 *===-----------------------------------------------------------------------===
19 #define __ATOMIC_RELAXED 0
20 #define __ATOMIC_CONSUME 1
21 #define __ATOMIC_ACQUIRE 2
22 #define __ATOMIC_RELEASE 3
23 #define __ATOMIC_ACQ_REL 4
24 #define __ATOMIC_SEQ_CST 5
28 memory_order_relaxed
= __ATOMIC_RELAXED
,
29 memory_order_consume
= __ATOMIC_CONSUME
,
30 memory_order_acquire
= __ATOMIC_ACQUIRE
,
31 memory_order_release
= __ATOMIC_RELEASE
,
32 memory_order_acq_rel
= __ATOMIC_ACQ_REL
,
33 memory_order_seq_cst
= __ATOMIC_SEQ_CST
,
37 typedef _Atomic(_Bool
) atomic_bool
;
38 typedef _Atomic(char) atomic_char
;
39 typedef _Atomic(signed char) atomic_schar
;
40 typedef _Atomic(unsigned char) atomic_uchar
;
41 typedef _Atomic(short) atomic_short
;
42 typedef _Atomic(unsigned short) atomic_ushort
;
43 typedef _Atomic(int) atomic_int
;
44 typedef _Atomic(unsigned int) atomic_uint
;
45 typedef _Atomic(long) atomic_long
;
46 typedef _Atomic(unsigned long) atomic_ulong
;
47 typedef _Atomic(long long) atomic_llong
;
48 typedef _Atomic(unsigned long long) atomic_ullong
;
49 typedef _Atomic(uint_least16_t) atomic_char16_t
;
50 typedef _Atomic(uint_least32_t) atomic_char32_t
;
51 typedef _Atomic(wchar_t) atomic_wchar_t
;
52 typedef _Atomic(int_least8_t) atomic_int_least8_t
;
53 typedef _Atomic(uint_least8_t) atomic_uint_least8_t
;
54 typedef _Atomic(int_least16_t) atomic_int_least16_t
;
55 typedef _Atomic(uint_least16_t) atomic_uint_least16_t
;
56 typedef _Atomic(int_least32_t) atomic_int_least32_t
;
57 typedef _Atomic(uint_least32_t) atomic_uint_least32_t
;
58 typedef _Atomic(int_least64_t) atomic_int_least64_t
;
59 typedef _Atomic(uint_least64_t) atomic_uint_least64_t
;
60 typedef _Atomic(int_fast8_t) atomic_int_fast8_t
;
61 typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t
;
62 typedef _Atomic(int_fast16_t) atomic_int_fast16_t
;
63 typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t
;
64 typedef _Atomic(int_fast32_t) atomic_int_fast32_t
;
65 typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t
;
66 typedef _Atomic(int_fast64_t) atomic_int_fast64_t
;
67 typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t
;
68 typedef _Atomic(intptr_t) atomic_intptr_t
;
69 typedef _Atomic(uintptr_t) atomic_uintptr_t
;
70 typedef _Atomic(size_t) atomic_size_t
;
71 typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t
;
72 typedef _Atomic(intmax_t) atomic_intmax_t
;
73 typedef _Atomic(uintmax_t) atomic_uintmax_t
;
80 #define ATOMIC_FLAG_INIT {0}
81 #define ATOMIC_VAR_INIT(value) (value)
83 #define atomic_flag_test_and_set_explicit(object, order) \
84 __atomic_test_and_set((void *)(&((object)->value)), order)
85 #define atomic_flag_test_and_set(object) \
86 atomic_flag_test_and_set_explicit(object, __ATOMIC_SEQ_CST)
88 #define atomic_flag_clear_explicit(object, order) \
89 __atomic_clear((bool *)(&((object)->value)), order)
90 #define atomic_flag_clear(object) \
91 atomic_flag_clear_explicit(object, __ATOMIC_SEQ_CST)
93 /* Generic routines */
94 #define atomic_init(object, desired) \
95 atomic_store_explicit(object, desired, __ATOMIC_RELAXED)
97 #define atomic_store_explicit(object, desired, order) \
98 ({ __typeof__ (object) ptr = (object); \
99 __typeof__ (*ptr) tmp = (desired); \
100 __atomic_store (ptr, &tmp, (order)); \
102 #define atomic_store(object, desired) \
103 atomic_store_explicit (object, desired, __ATOMIC_SEQ_CST)
105 #define atomic_load_explicit(object, order) \
106 ({ __typeof__ (object) ptr = (object); \
107 __typeof__ (*ptr) tmp; \
108 __atomic_load (ptr, &tmp, (order)); \
111 #define atomic_load(object) atomic_load_explicit (object, __ATOMIC_SEQ_CST)
113 #define atomic_exchange_explicit(object, desired, order) \
114 ({ __typeof__ (object) ptr = (object); \
115 __typeof__ (*ptr) val = (desired); \
116 __typeof__ (*ptr) tmp; \
117 __atomic_exchange (ptr, &val, &tmp, (order)); \
120 #define atomic_exchange(object, desired) \
121 atomic_exchange_explicit (object, desired, __ATOMIC_SEQ_CST)
123 #define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
124 ({ __typeof__ (object) ptr = (object); \
125 __typeof__ (*ptr) tmp = desired; \
126 __atomic_compare_exchange(ptr, expected, &tmp, 0, success, failure); \
128 #define atomic_compare_exchange_strong(object, expected, desired) \
129 atomic_compare_exchange_strong_explicit (object, expected, desired, \
130 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
132 #define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
133 ({ __typeof__ (object) ptr = (object); \
134 __typeof__ (*ptr) tmp = desired; \
135 __atomic_compare_exchange(ptr, expected, &tmp, 1, success, failure); \
137 #define atomic_compare_exchange_weak(object, expected, desired) \
138 atomic_compare_exchange_weak_explicit (object, expected, desired, \
139 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
141 #define atomic_fetch_add(object, operand) \
142 __atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
143 #define atomic_fetch_add_explicit __atomic_fetch_add
145 #define atomic_fetch_sub(object, operand) \
146 __atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
147 #define atomic_fetch_sub_explicit __atomic_fetch_sub
149 #define atomic_fetch_or(object, operand) \
150 __atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
151 #define atomic_fetch_or_explicit __atomic_fetch_or
153 #define atomic_fetch_xor(object, operand) \
154 __atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
155 #define atomic_fetch_xor_explicit __atomic_fetch_xor
157 #define atomic_fetch_and(object, operand) \
158 __atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
159 #define atomic_fetch_and_explicit __atomic_fetch_and
161 extern void atomic_thread_fence (memory_order
);
162 extern void __atomic_thread_fence (memory_order
);
163 #define atomic_thread_fence(order) __atomic_thread_fence (order)
164 extern void atomic_signal_fence (memory_order
);
165 extern void __atomic_signal_fence (memory_order
);
166 #define atomic_signal_fence(order) __atomic_signal_fence (order)
167 extern bool __atomic_is_lock_free(size_t size
, void *ptr
);
168 #define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ))
170 extern bool __atomic_test_and_set (void *, memory_order
);
171 extern void __atomic_clear (bool *, memory_order
);
173 #endif /* _STDATOMIC_H */