xref: /freebsd/contrib/llvm-project/libcxx/include/__atomic/atomic_flag.h (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 <__memory/addressof.h>
19 #include <__thread/support.h>
20 #include <cstdint>
21 
22 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23 #  pragma GCC system_header
24 #endif
25 
26 _LIBCPP_BEGIN_NAMESPACE_STD
27 
28 struct atomic_flag {
29   __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
30 
31   _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
32     return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
33   }
34   _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
35     return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
36   }
37 
38   _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
39     return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
40   }
41   _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
42     return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
43   }
44   _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
45     __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
46   }
47   _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
48     __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
49   }
50 
51   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
52   wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
53     std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
54   }
55   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
56   wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
57     std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
58   }
59   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
60     std::__atomic_notify_one(*this);
61   }
62   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
63     std::__atomic_notify_one(*this);
64   }
65   _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
66     std::__atomic_notify_all(*this);
67   }
68   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
69     std::__atomic_notify_all(*this);
70   }
71 
72 #if _LIBCPP_STD_VER >= 20
73   _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
74 #else
75   atomic_flag() _NOEXCEPT = default;
76 #endif
77 
78   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 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 template <>
86 struct __atomic_waitable_traits<atomic_flag> {
87   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
88     return std::__cxx_atomic_load(&__a.__a_, __order);
89   }
90 
91   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE
92   __atomic_load(const volatile atomic_flag& __a, memory_order __order) {
93     return std::__cxx_atomic_load(&__a.__a_, __order);
94   }
95 
96   static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
97   __atomic_contention_address(const atomic_flag& __a) {
98     return std::addressof(__a.__a_);
99   }
100 
101   static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
102   __atomic_contention_address(const volatile atomic_flag& __a) {
103     return std::addressof(__a.__a_);
104   }
105 };
106 
107 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
108 
109 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); }
110 
111 inline _LIBCPP_HIDE_FROM_ABI bool
112 atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
113   return __o->test(__m);
114 }
115 
116 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT {
117   return __o->test(__m);
118 }
119 
120 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT {
121   return __o->test_and_set();
122 }
123 
124 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); }
125 
126 inline _LIBCPP_HIDE_FROM_ABI bool
127 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
128   return __o->test_and_set(__m);
129 }
130 
131 inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
132   return __o->test_and_set(__m);
133 }
134 
135 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }
136 
137 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }
138 
139 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
140   __o->clear(__m);
141 }
142 
143 inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
144   __o->clear(__m);
145 }
146 
147 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
148 atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
149   __o->wait(__v);
150 }
151 
152 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
153 atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
154   __o->wait(__v);
155 }
156 
157 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
158 atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
159   __o->wait(__v, __m);
160 }
161 
162 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
163 atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
164   __o->wait(__v, __m);
165 }
166 
167 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
168 atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
169   __o->notify_one();
170 }
171 
172 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
173 atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
174   __o->notify_one();
175 }
176 
177 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
178 atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
179   __o->notify_all();
180 }
181 
182 inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
183 atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
184   __o->notify_all();
185 }
186 
187 _LIBCPP_END_NAMESPACE_STD
188 
189 #endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H
190