1 //===----------------------------------------------------------------------===//
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 #ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H
10 #define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
11
12 #include <__atomic/atomic_sync.h>
13 #include <__atomic/contention_t.h>
14 #include <__atomic/cxx_atomic_impl.h>
15 #include <__atomic/memory_order.h>
16 #include <__chrono/duration.h>
17 #include <__config>
18 #include <__threading_support>
19 #include <cstdint>
20
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 # pragma GCC system_header
23 #endif
24
25 _LIBCPP_BEGIN_NAMESPACE_STD
26
27 struct atomic_flag
28 {
29 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
30
31 _LIBCPP_HIDE_FROM_ABI
32 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
33 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
34 _LIBCPP_HIDE_FROM_ABI
35 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
36 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
37
38 _LIBCPP_HIDE_FROM_ABI
39 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
40 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
41 _LIBCPP_HIDE_FROM_ABI
42 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
43 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
44 _LIBCPP_HIDE_FROM_ABI
45 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
46 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
47 _LIBCPP_HIDE_FROM_ABI
48 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
49 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
50
51 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
52 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
53 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
54 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
55 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
56 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
57 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
notify_oneatomic_flag58 void notify_one() volatile _NOEXCEPT
59 {__cxx_atomic_notify_one(&__a_);}
60 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
notify_oneatomic_flag61 void notify_one() _NOEXCEPT
62 {__cxx_atomic_notify_one(&__a_);}
63 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
notify_allatomic_flag64 void notify_all() volatile _NOEXCEPT
65 {__cxx_atomic_notify_all(&__a_);}
66 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
notify_allatomic_flag67 void notify_all() _NOEXCEPT
68 {__cxx_atomic_notify_all(&__a_);}
69
70 #if _LIBCPP_STD_VER >= 20
71 _LIBCPP_HIDE_FROM_ABI constexpr
atomic_flagatomic_flag72 atomic_flag() _NOEXCEPT : __a_(false) {}
73 #else
74 atomic_flag() _NOEXCEPT = default;
75 #endif
76
77 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
atomic_flagatomic_flag78 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
79
80 atomic_flag(const atomic_flag&) = delete;
81 atomic_flag& operator=(const atomic_flag&) = delete;
82 atomic_flag& operator=(const atomic_flag&) volatile = delete;
83
84 };
85
86 inline _LIBCPP_HIDE_FROM_ABI
87 bool
atomic_flag_test(const volatile atomic_flag * __o)88 atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
89 {
90 return __o->test();
91 }
92
93 inline _LIBCPP_HIDE_FROM_ABI
94 bool
atomic_flag_test(const atomic_flag * __o)95 atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
96 {
97 return __o->test();
98 }
99
100 inline _LIBCPP_HIDE_FROM_ABI
101 bool
atomic_flag_test_explicit(const volatile atomic_flag * __o,memory_order __m)102 atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
103 {
104 return __o->test(__m);
105 }
106
107 inline _LIBCPP_HIDE_FROM_ABI
108 bool
atomic_flag_test_explicit(const atomic_flag * __o,memory_order __m)109 atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
110 {
111 return __o->test(__m);
112 }
113
114 inline _LIBCPP_HIDE_FROM_ABI
115 bool
atomic_flag_test_and_set(volatile atomic_flag * __o)116 atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
117 {
118 return __o->test_and_set();
119 }
120
121 inline _LIBCPP_HIDE_FROM_ABI
122 bool
atomic_flag_test_and_set(atomic_flag * __o)123 atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
124 {
125 return __o->test_and_set();
126 }
127
128 inline _LIBCPP_HIDE_FROM_ABI
129 bool
atomic_flag_test_and_set_explicit(volatile atomic_flag * __o,memory_order __m)130 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
131 {
132 return __o->test_and_set(__m);
133 }
134
135 inline _LIBCPP_HIDE_FROM_ABI
136 bool
atomic_flag_test_and_set_explicit(atomic_flag * __o,memory_order __m)137 atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
138 {
139 return __o->test_and_set(__m);
140 }
141
142 inline _LIBCPP_HIDE_FROM_ABI
143 void
atomic_flag_clear(volatile atomic_flag * __o)144 atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
145 {
146 __o->clear();
147 }
148
149 inline _LIBCPP_HIDE_FROM_ABI
150 void
atomic_flag_clear(atomic_flag * __o)151 atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
152 {
153 __o->clear();
154 }
155
156 inline _LIBCPP_HIDE_FROM_ABI
157 void
atomic_flag_clear_explicit(volatile atomic_flag * __o,memory_order __m)158 atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
159 {
160 __o->clear(__m);
161 }
162
163 inline _LIBCPP_HIDE_FROM_ABI
164 void
atomic_flag_clear_explicit(atomic_flag * __o,memory_order __m)165 atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
166 {
167 __o->clear(__m);
168 }
169
170 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
171 void
atomic_flag_wait(const volatile atomic_flag * __o,bool __v)172 atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
173 {
174 __o->wait(__v);
175 }
176
177 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
178 void
atomic_flag_wait(const atomic_flag * __o,bool __v)179 atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
180 {
181 __o->wait(__v);
182 }
183
184 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
185 void
atomic_flag_wait_explicit(const volatile atomic_flag * __o,bool __v,memory_order __m)186 atomic_flag_wait_explicit(const volatile atomic_flag* __o,
187 bool __v, memory_order __m) _NOEXCEPT
188 {
189 __o->wait(__v, __m);
190 }
191
192 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
193 void
atomic_flag_wait_explicit(const atomic_flag * __o,bool __v,memory_order __m)194 atomic_flag_wait_explicit(const atomic_flag* __o,
195 bool __v, memory_order __m) _NOEXCEPT
196 {
197 __o->wait(__v, __m);
198 }
199
200 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
201 void
atomic_flag_notify_one(volatile atomic_flag * __o)202 atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
203 {
204 __o->notify_one();
205 }
206
207 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
208 void
atomic_flag_notify_one(atomic_flag * __o)209 atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
210 {
211 __o->notify_one();
212 }
213
214 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
215 void
atomic_flag_notify_all(volatile atomic_flag * __o)216 atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
217 {
218 __o->notify_all();
219 }
220
221 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
222 void
atomic_flag_notify_all(atomic_flag * __o)223 atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
224 {
225 __o->notify_all();
226 }
227
228 _LIBCPP_END_NAMESPACE_STD
229
230 #endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H
231