xref: /freebsd/contrib/llvm-project/libcxx/include/__atomic/atomic_flag.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
106c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric 
906c3fb27SDimitry Andric #ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H
1006c3fb27SDimitry Andric #define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
1106c3fb27SDimitry Andric 
1206c3fb27SDimitry Andric #include <__atomic/atomic_sync.h>
1306c3fb27SDimitry Andric #include <__atomic/contention_t.h>
1406c3fb27SDimitry Andric #include <__atomic/cxx_atomic_impl.h>
1506c3fb27SDimitry Andric #include <__atomic/memory_order.h>
1606c3fb27SDimitry Andric #include <__chrono/duration.h>
1706c3fb27SDimitry Andric #include <__config>
18*0fca6ea1SDimitry Andric #include <__memory/addressof.h>
19*0fca6ea1SDimitry Andric #include <__thread/support.h>
2006c3fb27SDimitry Andric #include <cstdint>
2106c3fb27SDimitry Andric 
2206c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2306c3fb27SDimitry Andric #  pragma GCC system_header
2406c3fb27SDimitry Andric #endif
2506c3fb27SDimitry Andric 
2606c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
2706c3fb27SDimitry Andric 
28cb14a3feSDimitry Andric struct atomic_flag {
2906c3fb27SDimitry Andric   __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
3006c3fb27SDimitry Andric 
31cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
32cb14a3feSDimitry Andric     return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
33cb14a3feSDimitry Andric   }
34cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
35cb14a3feSDimitry Andric     return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
36cb14a3feSDimitry Andric   }
3706c3fb27SDimitry Andric 
38cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
39cb14a3feSDimitry Andric     return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
40cb14a3feSDimitry Andric   }
41cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
42cb14a3feSDimitry Andric     return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
43cb14a3feSDimitry Andric   }
44cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
45cb14a3feSDimitry Andric     __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
46cb14a3feSDimitry Andric   }
47cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
48cb14a3feSDimitry Andric     __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
49cb14a3feSDimitry Andric   }
5006c3fb27SDimitry Andric 
51*0fca6ea1SDimitry Andric   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
52*0fca6ea1SDimitry Andric   wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
53*0fca6ea1SDimitry Andric     std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
54cb14a3feSDimitry Andric   }
55*0fca6ea1SDimitry Andric   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
56cb14a3feSDimitry Andric   wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
57*0fca6ea1SDimitry Andric     std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
58cb14a3feSDimitry Andric   }
notify_oneatomic_flag59*0fca6ea1SDimitry Andric   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
60*0fca6ea1SDimitry Andric     std::__atomic_notify_one(*this);
61cb14a3feSDimitry Andric   }
notify_oneatomic_flag62*0fca6ea1SDimitry Andric   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
63*0fca6ea1SDimitry Andric     std::__atomic_notify_one(*this);
64*0fca6ea1SDimitry Andric   }
notify_allatomic_flag65cb14a3feSDimitry Andric   _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
66*0fca6ea1SDimitry Andric     std::__atomic_notify_all(*this);
67cb14a3feSDimitry Andric   }
notify_allatomic_flag68*0fca6ea1SDimitry Andric   _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
69*0fca6ea1SDimitry Andric     std::__atomic_notify_all(*this);
70*0fca6ea1SDimitry Andric   }
7106c3fb27SDimitry Andric 
7206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
atomic_flagatomic_flag73cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
7406c3fb27SDimitry Andric #else
7506c3fb27SDimitry Andric   atomic_flag() _NOEXCEPT = default;
7606c3fb27SDimitry Andric #endif
7706c3fb27SDimitry Andric 
atomic_flagatomic_flag78cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
7906c3fb27SDimitry Andric 
8006c3fb27SDimitry Andric   atomic_flag(const atomic_flag&)                     = delete;
8106c3fb27SDimitry Andric   atomic_flag& operator=(const atomic_flag&)          = delete;
8206c3fb27SDimitry Andric   atomic_flag& operator=(const atomic_flag&) volatile = delete;
8306c3fb27SDimitry Andric };
8406c3fb27SDimitry Andric 
85*0fca6ea1SDimitry Andric template <>
86*0fca6ea1SDimitry Andric struct __atomic_waitable_traits<atomic_flag> {
87*0fca6ea1SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
88*0fca6ea1SDimitry Andric     return std::__cxx_atomic_load(&__a.__a_, __order);
89*0fca6ea1SDimitry Andric   }
90*0fca6ea1SDimitry Andric 
91*0fca6ea1SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE
92*0fca6ea1SDimitry Andric   __atomic_load(const volatile atomic_flag& __a, memory_order __order) {
93*0fca6ea1SDimitry Andric     return std::__cxx_atomic_load(&__a.__a_, __order);
94*0fca6ea1SDimitry Andric   }
95*0fca6ea1SDimitry Andric 
96*0fca6ea1SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
97*0fca6ea1SDimitry Andric   __atomic_contention_address(const atomic_flag& __a) {
98*0fca6ea1SDimitry Andric     return std::addressof(__a.__a_);
99*0fca6ea1SDimitry Andric   }
100*0fca6ea1SDimitry Andric 
101*0fca6ea1SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
102*0fca6ea1SDimitry Andric   __atomic_contention_address(const volatile atomic_flag& __a) {
103*0fca6ea1SDimitry Andric     return std::addressof(__a.__a_);
104*0fca6ea1SDimitry Andric   }
105*0fca6ea1SDimitry Andric };
106*0fca6ea1SDimitry Andric 
107cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
10806c3fb27SDimitry Andric 
109cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); }
11006c3fb27SDimitry Andric 
111cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool
112cb14a3feSDimitry Andric atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
11306c3fb27SDimitry Andric   return __o->test(__m);
11406c3fb27SDimitry Andric }
11506c3fb27SDimitry Andric 
116cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT {
11706c3fb27SDimitry Andric   return __o->test(__m);
11806c3fb27SDimitry Andric }
11906c3fb27SDimitry Andric 
120cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT {
12106c3fb27SDimitry Andric   return __o->test_and_set();
12206c3fb27SDimitry Andric }
12306c3fb27SDimitry Andric 
124cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); }
12506c3fb27SDimitry Andric 
126cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool
127cb14a3feSDimitry Andric atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
12806c3fb27SDimitry Andric   return __o->test_and_set(__m);
12906c3fb27SDimitry Andric }
13006c3fb27SDimitry Andric 
131cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
13206c3fb27SDimitry Andric   return __o->test_and_set(__m);
13306c3fb27SDimitry Andric }
13406c3fb27SDimitry Andric 
135cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }
13606c3fb27SDimitry Andric 
137cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }
13806c3fb27SDimitry Andric 
139cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
14006c3fb27SDimitry Andric   __o->clear(__m);
14106c3fb27SDimitry Andric }
14206c3fb27SDimitry Andric 
143cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
14406c3fb27SDimitry Andric   __o->clear(__m);
14506c3fb27SDimitry Andric }
14606c3fb27SDimitry Andric 
147*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
148cb14a3feSDimitry Andric atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
14906c3fb27SDimitry Andric   __o->wait(__v);
15006c3fb27SDimitry Andric }
15106c3fb27SDimitry Andric 
152*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
153cb14a3feSDimitry Andric atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
15406c3fb27SDimitry Andric   __o->wait(__v);
15506c3fb27SDimitry Andric }
15606c3fb27SDimitry Andric 
157*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
158cb14a3feSDimitry Andric atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
15906c3fb27SDimitry Andric   __o->wait(__v, __m);
16006c3fb27SDimitry Andric }
16106c3fb27SDimitry Andric 
162*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
163cb14a3feSDimitry Andric atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
16406c3fb27SDimitry Andric   __o->wait(__v, __m);
16506c3fb27SDimitry Andric }
16606c3fb27SDimitry Andric 
167*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
168cb14a3feSDimitry Andric atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
16906c3fb27SDimitry Andric   __o->notify_one();
17006c3fb27SDimitry Andric }
17106c3fb27SDimitry Andric 
172*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
173*0fca6ea1SDimitry Andric atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
17406c3fb27SDimitry Andric   __o->notify_one();
17506c3fb27SDimitry Andric }
17606c3fb27SDimitry Andric 
177*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
178cb14a3feSDimitry Andric atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
17906c3fb27SDimitry Andric   __o->notify_all();
18006c3fb27SDimitry Andric }
18106c3fb27SDimitry Andric 
182*0fca6ea1SDimitry Andric inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
183*0fca6ea1SDimitry Andric atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
18406c3fb27SDimitry Andric   __o->notify_all();
18506c3fb27SDimitry Andric }
18606c3fb27SDimitry Andric 
18706c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD
18806c3fb27SDimitry Andric 
18906c3fb27SDimitry Andric #endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H
190