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