Warning: This file is not a C or C++ file. It does not have highlighting.
1 | /*===---- stdatomic.h - Standard header for atomic types and operations -----=== |
---|---|
2 | * |
3 | * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | * See https://llvm.org/LICENSE.txt for license information. |
5 | * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | * |
7 | *===-----------------------------------------------------------------------=== |
8 | */ |
9 | |
10 | #ifndef __CLANG_STDATOMIC_H |
11 | #define __CLANG_STDATOMIC_H |
12 | |
13 | /* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for |
14 | * example, already has a Clang-compatible stdatomic.h header. |
15 | * |
16 | * Exclude the MSVC path as well as the MSVC header as of the 14.31.30818 |
17 | * explicitly disallows `stdatomic.h` in the C mode via an `#error`. Fallback |
18 | * to the clang resource header until that is fully supported. The |
19 | * `stdatomic.h` header requires C++23 or newer. |
20 | */ |
21 | #if __STDC_HOSTED__ && \ |
22 | __has_include_next(<stdatomic.h>) && \ |
23 | (!defined(_MSC_VER) || (defined(__cplusplus) && __cplusplus >= 202002L)) |
24 | # include_next <stdatomic.h> |
25 | #else |
26 | |
27 | #include <stddef.h> |
28 | #include <stdint.h> |
29 | |
30 | #ifdef __cplusplus |
31 | extern "C" { |
32 | #endif |
33 | |
34 | /* 7.17.1 Introduction */ |
35 | |
36 | #define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE |
37 | #define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE |
38 | #define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE |
39 | #define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE |
40 | #define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE |
41 | #define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE |
42 | #define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE |
43 | #define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE |
44 | #define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE |
45 | #define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE |
46 | |
47 | /* 7.17.2 Initialization */ |
48 | #if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 202311L) || \ |
49 | defined(__cplusplus) |
50 | /* ATOMIC_VAR_INIT was removed in C23, but still remains in C++23. */ |
51 | #define ATOMIC_VAR_INIT(value) (value) |
52 | #endif |
53 | |
54 | #if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L && \ |
55 | __STDC_VERSION__ < 202311L) || \ |
56 | (defined(__cplusplus) && __cplusplus >= 202002L)) && \ |
57 | !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS) |
58 | /* ATOMIC_VAR_INIT was deprecated in C17 and C++20. */ |
59 | #pragma clang deprecated(ATOMIC_VAR_INIT) |
60 | #endif |
61 | #define atomic_init __c11_atomic_init |
62 | |
63 | /* 7.17.3 Order and consistency */ |
64 | |
65 | typedef enum memory_order { |
66 | memory_order_relaxed = __ATOMIC_RELAXED, |
67 | memory_order_consume = __ATOMIC_CONSUME, |
68 | memory_order_acquire = __ATOMIC_ACQUIRE, |
69 | memory_order_release = __ATOMIC_RELEASE, |
70 | memory_order_acq_rel = __ATOMIC_ACQ_REL, |
71 | memory_order_seq_cst = __ATOMIC_SEQ_CST |
72 | } memory_order; |
73 | |
74 | #define kill_dependency(y) (y) |
75 | |
76 | /* 7.17.4 Fences */ |
77 | |
78 | /* These should be provided by the libc implementation. */ |
79 | void atomic_thread_fence(memory_order); |
80 | void atomic_signal_fence(memory_order); |
81 | |
82 | #define atomic_thread_fence(order) __c11_atomic_thread_fence(order) |
83 | #define atomic_signal_fence(order) __c11_atomic_signal_fence(order) |
84 | |
85 | /* 7.17.5 Lock-free property */ |
86 | |
87 | #define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) |
88 | |
89 | /* 7.17.6 Atomic integer types */ |
90 | |
91 | #ifdef __cplusplus |
92 | typedef _Atomic(bool) atomic_bool; |
93 | #else |
94 | typedef _Atomic(_Bool) atomic_bool; |
95 | #endif |
96 | typedef _Atomic(char) atomic_char; |
97 | typedef _Atomic(signed char) atomic_schar; |
98 | typedef _Atomic(unsigned char) atomic_uchar; |
99 | typedef _Atomic(short) atomic_short; |
100 | typedef _Atomic(unsigned short) atomic_ushort; |
101 | typedef _Atomic(int) atomic_int; |
102 | typedef _Atomic(unsigned int) atomic_uint; |
103 | typedef _Atomic(long) atomic_long; |
104 | typedef _Atomic(unsigned long) atomic_ulong; |
105 | typedef _Atomic(long long) atomic_llong; |
106 | typedef _Atomic(unsigned long long) atomic_ullong; |
107 | typedef _Atomic(uint_least16_t) atomic_char16_t; |
108 | typedef _Atomic(uint_least32_t) atomic_char32_t; |
109 | typedef _Atomic(wchar_t) atomic_wchar_t; |
110 | typedef _Atomic(int_least8_t) atomic_int_least8_t; |
111 | typedef _Atomic(uint_least8_t) atomic_uint_least8_t; |
112 | typedef _Atomic(int_least16_t) atomic_int_least16_t; |
113 | typedef _Atomic(uint_least16_t) atomic_uint_least16_t; |
114 | typedef _Atomic(int_least32_t) atomic_int_least32_t; |
115 | typedef _Atomic(uint_least32_t) atomic_uint_least32_t; |
116 | typedef _Atomic(int_least64_t) atomic_int_least64_t; |
117 | typedef _Atomic(uint_least64_t) atomic_uint_least64_t; |
118 | typedef _Atomic(int_fast8_t) atomic_int_fast8_t; |
119 | typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; |
120 | typedef _Atomic(int_fast16_t) atomic_int_fast16_t; |
121 | typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; |
122 | typedef _Atomic(int_fast32_t) atomic_int_fast32_t; |
123 | typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; |
124 | typedef _Atomic(int_fast64_t) atomic_int_fast64_t; |
125 | typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; |
126 | typedef _Atomic(intptr_t) atomic_intptr_t; |
127 | typedef _Atomic(uintptr_t) atomic_uintptr_t; |
128 | typedef _Atomic(size_t) atomic_size_t; |
129 | typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; |
130 | typedef _Atomic(intmax_t) atomic_intmax_t; |
131 | typedef _Atomic(uintmax_t) atomic_uintmax_t; |
132 | |
133 | /* 7.17.7 Operations on atomic types */ |
134 | |
135 | #define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST) |
136 | #define atomic_store_explicit __c11_atomic_store |
137 | |
138 | #define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST) |
139 | #define atomic_load_explicit __c11_atomic_load |
140 | |
141 | #define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST) |
142 | #define atomic_exchange_explicit __c11_atomic_exchange |
143 | |
144 | #define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) |
145 | #define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong |
146 | |
147 | #define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) |
148 | #define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak |
149 | |
150 | #define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST) |
151 | #define atomic_fetch_add_explicit __c11_atomic_fetch_add |
152 | |
153 | #define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST) |
154 | #define atomic_fetch_sub_explicit __c11_atomic_fetch_sub |
155 | |
156 | #define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST) |
157 | #define atomic_fetch_or_explicit __c11_atomic_fetch_or |
158 | |
159 | #define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST) |
160 | #define atomic_fetch_xor_explicit __c11_atomic_fetch_xor |
161 | |
162 | #define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST) |
163 | #define atomic_fetch_and_explicit __c11_atomic_fetch_and |
164 | |
165 | /* 7.17.8 Atomic flag type and operations */ |
166 | |
167 | typedef struct atomic_flag { atomic_bool _Value; } atomic_flag; |
168 | |
169 | #define ATOMIC_FLAG_INIT { 0 } |
170 | |
171 | /* These should be provided by the libc implementation. */ |
172 | #ifdef __cplusplus |
173 | bool atomic_flag_test_and_set(volatile atomic_flag *); |
174 | bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order); |
175 | #else |
176 | _Bool atomic_flag_test_and_set(volatile atomic_flag *); |
177 | _Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order); |
178 | #endif |
179 | void atomic_flag_clear(volatile atomic_flag *); |
180 | void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order); |
181 | |
182 | #define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST) |
183 | #define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order) |
184 | |
185 | #define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST) |
186 | #define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order) |
187 | |
188 | #ifdef __cplusplus |
189 | } |
190 | #endif |
191 | |
192 | #endif /* __STDC_HOSTED__ */ |
193 | #endif /* __CLANG_STDATOMIC_H */ |
194 | |
195 |
Warning: This file is not a C or C++ file. It does not have highlighting.