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 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; 29 30 _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT { 31 return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m); 32 } 33 _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT { 34 return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m); 35 } 36 37 _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { 38 return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m); 39 } 40 _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT { 41 return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m); 42 } 43 _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { 44 __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m); 45 } 46 _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT { 47 __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m); 48 } 49 50 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const 51 volatile _NOEXCEPT { 52 __cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m); 53 } 54 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void 55 wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { 56 __cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m); 57 } 58 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { 59 __cxx_atomic_notify_one(&__a_); 60 } 61 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { __cxx_atomic_notify_one(&__a_); } 62 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { 63 __cxx_atomic_notify_all(&__a_); 64 } 65 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { __cxx_atomic_notify_all(&__a_); } 66 67 #if _LIBCPP_STD_VER >= 20 68 _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {} 69 #else 70 atomic_flag() _NOEXCEPT = default; 71 #endif 72 73 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION 74 75 atomic_flag(const atomic_flag&) = delete; 76 atomic_flag& operator=(const atomic_flag&) = delete; 77 atomic_flag& operator=(const atomic_flag&) volatile = delete; 78 }; 79 80 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); } 81 82 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); } 83 84 inline _LIBCPP_HIDE_FROM_ABI bool 85 atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { 86 return __o->test(__m); 87 } 88 89 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT { 90 return __o->test(__m); 91 } 92 93 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT { 94 return __o->test_and_set(); 95 } 96 97 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); } 98 99 inline _LIBCPP_HIDE_FROM_ABI bool 100 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { 101 return __o->test_and_set(__m); 102 } 103 104 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT { 105 return __o->test_and_set(__m); 106 } 107 108 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); } 109 110 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); } 111 112 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { 113 __o->clear(__m); 114 } 115 116 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT { 117 __o->clear(__m); 118 } 119 120 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void 121 atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT { 122 __o->wait(__v); 123 } 124 125 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void 126 atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT { 127 __o->wait(__v); 128 } 129 130 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void 131 atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT { 132 __o->wait(__v, __m); 133 } 134 135 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void 136 atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT { 137 __o->wait(__v, __m); 138 } 139 140 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void 141 atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT { 142 __o->notify_one(); 143 } 144 145 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT { 146 __o->notify_one(); 147 } 148 149 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void 150 atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT { 151 __o->notify_all(); 152 } 153 154 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { 155 __o->notify_all(); 156 } 157 158 _LIBCPP_END_NAMESPACE_STD 159 160 #endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H 161