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
58     void notify_one() volatile _NOEXCEPT
59         {__cxx_atomic_notify_one(&__a_);}
60     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
61     void notify_one() _NOEXCEPT
62         {__cxx_atomic_notify_one(&__a_);}
63     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
64     void notify_all() volatile _NOEXCEPT
65         {__cxx_atomic_notify_all(&__a_);}
66     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
67     void notify_all() _NOEXCEPT
68         {__cxx_atomic_notify_all(&__a_);}
69 
70 #if _LIBCPP_STD_VER >= 20
71     _LIBCPP_HIDE_FROM_ABI constexpr
72     atomic_flag() _NOEXCEPT : __a_(false) {}
73 #else
74     atomic_flag() _NOEXCEPT = default;
75 #endif
76 
77     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
78     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
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
95 atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
96 {
97     return __o->test();
98 }
99 
100 inline _LIBCPP_HIDE_FROM_ABI
101 bool
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
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
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
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
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
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
144 atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
145 {
146     __o->clear();
147 }
148 
149 inline _LIBCPP_HIDE_FROM_ABI
150 void
151 atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
152 {
153     __o->clear();
154 }
155 
156 inline _LIBCPP_HIDE_FROM_ABI
157 void
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
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
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
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
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
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
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
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
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
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