File indexing completed on 2026-05-03 08:13:13
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H
0010 #define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
0011
0012 #include <__atomic/atomic_sync.h>
0013 #include <__atomic/contention_t.h>
0014 #include <__atomic/memory_order.h>
0015 #include <__atomic/support.h>
0016 #include <__chrono/duration.h>
0017 #include <__config>
0018 #include <__memory/addressof.h>
0019 #include <__thread/support.h>
0020 #include <cstdint>
0021
0022 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0023 # pragma GCC system_header
0024 #endif
0025
0026 _LIBCPP_BEGIN_NAMESPACE_STD
0027
0028 struct atomic_flag {
0029 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
0030
0031 _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
0032 return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
0033 }
0034 _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
0035 return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
0036 }
0037
0038 _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
0039 return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
0040 }
0041 _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
0042 return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
0043 }
0044 _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
0045 __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
0046 }
0047 _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
0048 __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
0049 }
0050
0051 #if _LIBCPP_STD_VER >= 20
0052 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const
0053 volatile _NOEXCEPT {
0054 std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
0055 }
0056 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0057 wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
0058 std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
0059 }
0060 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
0061 std::__atomic_notify_one(*this);
0062 }
0063 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
0064 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
0065 std::__atomic_notify_all(*this);
0066 }
0067 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
0068 #endif
0069
0070 #if _LIBCPP_STD_VER >= 20
0071 _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
0072 #else
0073 atomic_flag() _NOEXCEPT = default;
0074 #endif
0075
0076 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
0077
0078 atomic_flag(const atomic_flag&) = delete;
0079 atomic_flag& operator=(const atomic_flag&) = delete;
0080 atomic_flag& operator=(const atomic_flag&) volatile = delete;
0081 };
0082
0083 template <>
0084 struct __atomic_waitable_traits<atomic_flag> {
0085 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
0086 return std::__cxx_atomic_load(&__a.__a_, __order);
0087 }
0088
0089 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE
0090 __atomic_load(const volatile atomic_flag& __a, memory_order __order) {
0091 return std::__cxx_atomic_load(&__a.__a_, __order);
0092 }
0093
0094 static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
0095 __atomic_contention_address(const atomic_flag& __a) {
0096 return std::addressof(__a.__a_);
0097 }
0098
0099 static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
0100 __atomic_contention_address(const volatile atomic_flag& __a) {
0101 return std::addressof(__a.__a_);
0102 }
0103 };
0104
0105 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
0106
0107 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); }
0108
0109 inline _LIBCPP_HIDE_FROM_ABI bool
0110 atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
0111 return __o->test(__m);
0112 }
0113
0114 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT {
0115 return __o->test(__m);
0116 }
0117
0118 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT {
0119 return __o->test_and_set();
0120 }
0121
0122 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); }
0123
0124 inline _LIBCPP_HIDE_FROM_ABI bool
0125 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
0126 return __o->test_and_set(__m);
0127 }
0128
0129 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
0130 return __o->test_and_set(__m);
0131 }
0132
0133 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }
0134
0135 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }
0136
0137 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
0138 __o->clear(__m);
0139 }
0140
0141 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
0142 __o->clear(__m);
0143 }
0144
0145 #if _LIBCPP_STD_VER >= 20
0146 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
0147 atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
0148 __o->wait(__v);
0149 }
0150
0151 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
0152 atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
0153 __o->wait(__v);
0154 }
0155
0156 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
0157 atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
0158 __o->wait(__v, __m);
0159 }
0160
0161 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
0162 atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
0163 __o->wait(__v, __m);
0164 }
0165
0166 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
0167 atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
0168 __o->notify_one();
0169 }
0170
0171 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
0172 __o->notify_one();
0173 }
0174
0175 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
0176 atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
0177 __o->notify_all();
0178 }
0179
0180 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
0181 __o->notify_all();
0182 }
0183 #endif
0184
0185 _LIBCPP_END_NAMESPACE_STD
0186
0187 #endif