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