YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
atomic.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <utility>
6
8
9template <typename T>
10class AtomicBase : public AtomicWait<T> {
11 using Base = AtomicWait<T>;
12
13 public:
14 using Base::Base;
17
18 void store(T desired, std::memory_order) noexcept {
20 }
21 void store(T desired, std::memory_order) volatile noexcept {
23 }
24
25 T load(std::memory_order) const noexcept {
26 return _value;
27 }
28 T load(std::memory_order) const volatile noexcept {
29 return _value;
30 }
31
32 operator T() const noexcept {
33 return load();
34 }
35 operator T() const volatile noexcept {
36 return load();
37 }
38
39 T exchange(T desired, std::memory_order) noexcept {
40 return std::exchange(_value, desired);
41 }
42 T exchange(T desired, std::memory_order) volatile noexcept {
43 return std::exchange(_value, desired);
44 }
45
46 bool compare_exchange_weak(T& expected, T desired, std::memory_order, std::memory_order) noexcept {
48 }
49 bool compare_exchange_weak(T& expected, T desired, std::memory_order, std::memory_order) volatile noexcept {
51 }
52 bool compare_exchange_weak(T& expected, T desired, std::memory_order) noexcept {
54 }
55 bool compare_exchange_weak(T& expected, T desired, std::memory_order) volatile noexcept {
57 }
58 bool compare_exchange_strong(T& expected, T desired, std::memory_order, std::memory_order) noexcept {
60 }
61 bool compare_exchange_strong(T& expected, T desired, std::memory_order, std::memory_order) volatile noexcept {
63 }
64 bool compare_exchange_strong(T& expected, T desired, std::memory_order) noexcept {
66 }
67 bool compare_exchange_strong(T& expected, T desired, std::memory_order) volatile noexcept {
69 }
70
71 protected:
73 if (this->_value == expected) {
74 this->_value = desired;
75 return true;
76 } else {
77 expected = this->_value;
78 return false;
79 }
80 }
81 using Base::_value;
82};
83
84template <typename T, bool IsFloating = std::is_floating_point_v<T>>
85class AtomicFloatingBase : public AtomicBase<T> {
86 using Base = AtomicBase<T>;
87
88 public:
89 using Base::Base;
90};
91
92template <typename T>
93class AtomicFloatingBase<T, true> : public AtomicBase<T> {
94 using Base = AtomicBase<T>;
95
96 public:
97 using Base::Base;
98
99 T fetch_add(T arg, std::memory_order) noexcept {
100 auto val = _value;
101 _value += arg;
102 return val;
103 }
104 T fetch_add(T arg, std::memory_order) volatile noexcept {
105 auto val = _value;
106 _value += arg;
107 return val;
108 }
109
110 T fetch_sub(T arg, std::memory_order) noexcept {
111 auto val = _value;
112 _value -= arg;
113 return val;
114 }
115 T fetch_sub(T arg, std::memory_order) volatile noexcept {
116 auto val = _value;
117 _value -= arg;
118 return val;
119 }
120
121 T operator+=(T arg) noexcept {
122 return _value += arg;
123 }
124 T operator+=(T arg) volatile noexcept {
125 return _value += arg;
126 }
127
128 T operator-=(T arg) noexcept {
129 return _value -= arg;
130 }
131 T operator-=(T arg) volatile noexcept {
132 return _value -= arg;
133 }
134
135 protected:
136 using Base::_value;
137};
138
139template <typename T, bool IsIntegral = std::is_integral_v<T> && !std::is_same_v<T, bool>>
142
143 public:
144 using Base::Base;
145};
146
147template <typename T>
148class AtomicIntegralBase<T, true> : public AtomicFloatingBase<T, true> {
150
151 public:
152 using Base::Base;
153
154 T fetch_and(T arg, std::memory_order) noexcept {
155 auto val = _value;
156 _value += arg;
157 return val;
158 }
159 T fetch_and(T arg, std::memory_order) volatile noexcept {
160 auto val = _value;
161 _value += arg;
162 return val;
163 }
164
165 T fetch_or(T arg, std::memory_order) noexcept {
166 auto val = _value;
167 _value |= arg;
168 return val;
169 }
170 T fetch_or(T arg, std::memory_order) volatile noexcept {
171 auto val = _value;
172 _value |= arg;
173 return val;
174 }
175
176 T fetch_xor(T arg, std::memory_order) noexcept {
177 auto val = _value;
178 _value ^= arg;
179 return val;
180 }
181 T fetch_xor(T arg, std::memory_order) volatile noexcept {
182 auto val = _value;
183 _value ^= arg;
184 return val;
185 }
186
188 return _value++;
189 }
191 return _value++;
192 }
193
194 T operator++(int) noexcept {
195 return ++_value;
196 }
197 T operator++(int) volatile noexcept {
198 return ++_value;
199 }
200
202 return _value--;
203 }
205 return _value--;
206 }
207
208 T operator--(int) noexcept {
209 return --_value;
210 }
211 T operator--(int) volatile noexcept {
212 return --_value;
213 }
214
215 T operator&=(T arg) noexcept {
216 return _value &= arg;
217 }
218 T operator&=(T arg) volatile noexcept {
219 return _value &= arg;
220 }
221
222 T operator|=(T arg) noexcept {
223 return _value |= arg;
224 }
225 T operator|=(T arg) volatile noexcept {
226 return _value |= arg;
227 }
228
229 T operator^=(T arg) noexcept {
230 return _value ^= arg;
231 }
232 T operator^=(T arg) volatile noexcept {
233 return _value ^= arg;
234 }
235
236 protected:
237 using Base::_value;
238};
239
240template <typename T>
241class Atomic : public AtomicIntegralBase<T> {
243
244 public:
245 using Base::Base;
246};
247
248template <typename U>
249class Atomic<U*> : public AtomicBase<U*> {
250 using Base = AtomicBase<U*>;
251
252 public:
253 using Base::Base;
254
255 U* fetch_add(std::ptrdiff_t arg, std::memory_order) noexcept {
256 auto val = _value;
257 _value += arg;
258 return val;
259 }
260 U* fetch_add(std::ptrdiff_t arg, std::memory_order) volatile noexcept {
261 auto val = _value;
262 _value += arg;
263 return val;
264 }
265
266 U* fetch_sub(std::ptrdiff_t arg, std::memory_order) noexcept {
267 auto val = _value;
268 _value -= arg;
269 return val;
270 }
271 U* fetch_sub(std::ptrdiff_t arg, std::memory_order) volatile noexcept {
272 auto val = _value;
273 _value -= arg;
274 return val;
275 }
276
278 return _value++;
279 }
281 return _value++;
282 }
283
284 U* operator++(int) noexcept {
285 return ++_value;
286 }
287 U* operator++(int) volatile noexcept {
288 return ++_value;
289 }
290
292 return _value--;
293 }
295 return _value--;
296 }
297
298 U* operator--(int) noexcept {
299 return --_value;
300 }
301 U* operator--(int) volatile noexcept {
302 return --_value;
303 }
304
305 U* operator+=(std::ptrdiff_t arg) noexcept {
306 return _value += arg;
307 }
308 U* operator+=(std::ptrdiff_t arg) volatile noexcept {
309 return _value += arg;
310 }
311
312 U* operator-=(std::ptrdiff_t arg) noexcept {
313 return _value -= arg;
314 }
315 U* operator-=(std::ptrdiff_t arg) volatile noexcept {
316 return _value -= arg;
317 }
318
319 protected:
320 using Base::_value;
321};
322
323// TODO(myannyax) Implement
324// template <typename Impl, typename U>
325// class Atomic<Impl, std::shared_ptr<U>>;
326//
327// template <typename Impl, typename U>
328// class Atomic<Impl, std::weak_ptr<U>>;
329
330} // namespace yaclib::detail::fiber
bool compare_exchange_strong(T &expected, T desired, std::memory_order, std::memory_order) noexcept
Definition atomic.hpp:58
bool compare_exchange_strong(T &expected, T desired, std::memory_order, std::memory_order) volatile noexcept
Definition atomic.hpp:61
bool compare_exchange_strong(T &expected, T desired, std::memory_order) volatile noexcept
Definition atomic.hpp:67
T load(std::memory_order) const noexcept
Definition atomic.hpp:25
void store(T desired, std::memory_order) volatile noexcept
Definition atomic.hpp:21
bool compare_exchange_strong(T &expected, T desired, std::memory_order) noexcept
Definition atomic.hpp:64
bool compare_exchange_weak(T &expected, T desired, std::memory_order) volatile noexcept
Definition atomic.hpp:55
T load(std::memory_order) const volatile noexcept
Definition atomic.hpp:28
bool CompareExchangeHelper(T &expected, T desired)
Definition atomic.hpp:72
bool compare_exchange_weak(T &expected, T desired, std::memory_order, std::memory_order) noexcept
Definition atomic.hpp:46
void store(T desired, std::memory_order) noexcept
Definition atomic.hpp:18
T exchange(T desired, std::memory_order) volatile noexcept
Definition atomic.hpp:42
bool compare_exchange_weak(T &expected, T desired, std::memory_order, std::memory_order) volatile noexcept
Definition atomic.hpp:49
bool compare_exchange_weak(T &expected, T desired, std::memory_order) noexcept
Definition atomic.hpp:52
T exchange(T desired, std::memory_order) noexcept
Definition atomic.hpp:39
T fetch_sub(T arg, std::memory_order) volatile noexcept
Definition atomic.hpp:115
T fetch_sub(T arg, std::memory_order) noexcept
Definition atomic.hpp:110
T fetch_add(T arg, std::memory_order) volatile noexcept
Definition atomic.hpp:104
T fetch_add(T arg, std::memory_order) noexcept
Definition atomic.hpp:99
T fetch_or(T arg, std::memory_order) volatile noexcept
Definition atomic.hpp:170
T fetch_xor(T arg, std::memory_order) noexcept
Definition atomic.hpp:176
T fetch_and(T arg, std::memory_order) noexcept
Definition atomic.hpp:154
T fetch_and(T arg, std::memory_order) volatile noexcept
Definition atomic.hpp:159
T fetch_xor(T arg, std::memory_order) volatile noexcept
Definition atomic.hpp:181
T fetch_or(T arg, std::memory_order) noexcept
Definition atomic.hpp:165
bool is_lock_free() const volatile noexcept
static constexpr bool is_always_lock_free
U * operator++() volatile noexcept
Definition atomic.hpp:280
U * fetch_add(std::ptrdiff_t arg, std::memory_order) volatile noexcept
Definition atomic.hpp:260
U * fetch_add(std::ptrdiff_t arg, std::memory_order) noexcept
Definition atomic.hpp:255
U * fetch_sub(std::ptrdiff_t arg, std::memory_order) noexcept
Definition atomic.hpp:266
U * operator+=(std::ptrdiff_t arg) volatile noexcept
Definition atomic.hpp:308
U * operator-=(std::ptrdiff_t arg) noexcept
Definition atomic.hpp:312
U * operator--(int) volatile noexcept
Definition atomic.hpp:301
U * operator++(int) volatile noexcept
Definition atomic.hpp:287
U * operator--() volatile noexcept
Definition atomic.hpp:294
U * fetch_sub(std::ptrdiff_t arg, std::memory_order) volatile noexcept
Definition atomic.hpp:271
U * operator-=(std::ptrdiff_t arg) volatile noexcept
Definition atomic.hpp:315
U * operator+=(std::ptrdiff_t arg) noexcept
Definition atomic.hpp:305
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25