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 }
notify_oneatomic_flag58 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
59 __cxx_atomic_notify_one(&__a_);
60 }
notify_oneatomic_flag61 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { __cxx_atomic_notify_one(&__a_); }
notify_allatomic_flag62 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
63 __cxx_atomic_notify_all(&__a_);
64 }
notify_allatomic_flag65 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { __cxx_atomic_notify_all(&__a_); }
66
67 #if _LIBCPP_STD_VER >= 20
atomic_flagatomic_flag68 _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
69 #else
70 atomic_flag() _NOEXCEPT = default;
71 #endif
72
atomic_flagatomic_flag73 _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
atomic_flag_test(const volatile atomic_flag * __o)80 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
81
atomic_flag_test(const atomic_flag * __o)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
atomic_flag_test_explicit(const volatile atomic_flag * __o,memory_order __m)85 atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
86 return __o->test(__m);
87 }
88
atomic_flag_test_explicit(const atomic_flag * __o,memory_order __m)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
atomic_flag_test_and_set(volatile atomic_flag * __o)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
atomic_flag_test_and_set(atomic_flag * __o)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
atomic_flag_test_and_set_explicit(volatile atomic_flag * __o,memory_order __m)100 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
101 return __o->test_and_set(__m);
102 }
103
atomic_flag_test_and_set_explicit(atomic_flag * __o,memory_order __m)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
atomic_flag_clear(volatile atomic_flag * __o)108 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }
109
atomic_flag_clear(atomic_flag * __o)110 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }
111
atomic_flag_clear_explicit(volatile atomic_flag * __o,memory_order __m)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
atomic_flag_clear_explicit(atomic_flag * __o,memory_order __m)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
atomic_flag_wait(const volatile atomic_flag * __o,bool __v)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
atomic_flag_wait(const atomic_flag * __o,bool __v)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
atomic_flag_wait_explicit(const volatile atomic_flag * __o,bool __v,memory_order __m)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
atomic_flag_wait_explicit(const atomic_flag * __o,bool __v,memory_order __m)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
atomic_flag_notify_one(volatile atomic_flag * __o)141 atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
142 __o->notify_one();
143 }
144
atomic_flag_notify_one(atomic_flag * __o)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
atomic_flag_notify_all(volatile atomic_flag * __o)150 atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
151 __o->notify_all();
152 }
153
atomic_flag_notify_all(atomic_flag * __o)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