1 | // -*- C++ -*- header. |
2 | |
3 | // Copyright (C) 2008-2017 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | // ???????????????????????????????????????????????????????????????????? |
26 | // |
27 | // This is a copy of the libstdc++ header, with the trivial modification |
28 | // of ignoring the c++config.h include. If and when the top-level build is |
29 | // fixed so that target libraries can be built using the newly built, we can |
30 | // delete this file. |
31 | // |
32 | // ???????????????????????????????????????????????????????????????????? |
33 | |
34 | /** @file include/atomic |
35 | * This is a Standard C++ Library header. |
36 | */ |
37 | |
38 | // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. |
39 | // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html |
40 | |
41 | #ifndef _GLIBCXX_ATOMIC |
42 | #define _GLIBCXX_ATOMIC 1 |
43 | |
44 | #define __libitm_always_inline __attribute__((always_inline)) |
45 | |
46 | // #pragma GCC system_header |
47 | |
48 | // #ifndef __GXX_EXPERIMENTAL_CXX0X__ |
49 | // # include <bits/c++0x_warning.h> |
50 | // #endif |
51 | |
52 | // #include <bits/atomic_base.h> |
53 | |
54 | namespace std // _GLIBCXX_VISIBILITY(default) |
55 | { |
56 | // _GLIBCXX_BEGIN_NAMESPACE_VERSION |
57 | |
58 | /** |
59 | * @defgroup atomics Atomics |
60 | * |
61 | * Components for performing atomic operations. |
62 | * @{ |
63 | */ |
64 | |
65 | /// Enumeration for memory_order |
66 | typedef enum memory_order |
67 | { |
68 | memory_order_relaxed, |
69 | memory_order_consume, |
70 | memory_order_acquire, |
71 | memory_order_release, |
72 | memory_order_acq_rel, |
73 | memory_order_seq_cst |
74 | } memory_order; |
75 | |
76 | inline __libitm_always_inline memory_order |
77 | __calculate_memory_order(memory_order __m) noexcept |
78 | { |
79 | const bool __cond1 = __m == memory_order_release; |
80 | const bool __cond2 = __m == memory_order_acq_rel; |
81 | memory_order __mo1(__cond1 ? memory_order_relaxed : __m); |
82 | memory_order __mo2(__cond2 ? memory_order_acquire : __mo1); |
83 | return __mo2; |
84 | } |
85 | |
86 | inline __libitm_always_inline void |
87 | atomic_thread_fence(memory_order __m) noexcept |
88 | { |
89 | __atomic_thread_fence (__m); |
90 | } |
91 | |
92 | inline __libitm_always_inline void |
93 | atomic_signal_fence(memory_order __m) noexcept |
94 | { |
95 | __atomic_thread_fence (__m); |
96 | } |
97 | |
98 | /// kill_dependency |
99 | template<typename _Tp> |
100 | inline _Tp |
101 | kill_dependency(_Tp __y) noexcept |
102 | { |
103 | _Tp __ret(__y); |
104 | return __ret; |
105 | } |
106 | |
107 | /// Lock-free Property |
108 | |
109 | |
110 | #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE |
111 | #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE |
112 | #define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE |
113 | #define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE |
114 | #define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE |
115 | #define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE |
116 | #define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE |
117 | #define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE |
118 | #define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE |
119 | #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE |
120 | |
121 | // Base types for atomics. |
122 | template<typename _IntTp> |
123 | struct __atomic_base; |
124 | |
125 | /// atomic_char |
126 | typedef __atomic_base<char> atomic_char; |
127 | |
128 | /// atomic_schar |
129 | typedef __atomic_base<signed char> atomic_schar; |
130 | |
131 | /// atomic_uchar |
132 | typedef __atomic_base<unsigned char> atomic_uchar; |
133 | |
134 | /// atomic_short |
135 | typedef __atomic_base<short> atomic_short; |
136 | |
137 | /// atomic_ushort |
138 | typedef __atomic_base<unsigned short> atomic_ushort; |
139 | |
140 | /// atomic_int |
141 | typedef __atomic_base<int> atomic_int; |
142 | |
143 | /// atomic_uint |
144 | typedef __atomic_base<unsigned int> atomic_uint; |
145 | |
146 | /// atomic_long |
147 | typedef __atomic_base<long> atomic_long; |
148 | |
149 | /// atomic_ulong |
150 | typedef __atomic_base<unsigned long> atomic_ulong; |
151 | |
152 | /// atomic_llong |
153 | typedef __atomic_base<long long> atomic_llong; |
154 | |
155 | /// atomic_ullong |
156 | typedef __atomic_base<unsigned long long> atomic_ullong; |
157 | |
158 | /// atomic_wchar_t |
159 | typedef __atomic_base<wchar_t> atomic_wchar_t; |
160 | |
161 | /// atomic_char16_t |
162 | typedef __atomic_base<char16_t> atomic_char16_t; |
163 | |
164 | /// atomic_char32_t |
165 | typedef __atomic_base<char32_t> atomic_char32_t; |
166 | |
167 | /// atomic_char32_t |
168 | typedef __atomic_base<char32_t> atomic_char32_t; |
169 | |
170 | |
171 | /// atomic_int_least8_t |
172 | typedef __atomic_base<int_least8_t> atomic_int_least8_t; |
173 | |
174 | /// atomic_uint_least8_t |
175 | typedef __atomic_base<uint_least8_t> atomic_uint_least8_t; |
176 | |
177 | /// atomic_int_least16_t |
178 | typedef __atomic_base<int_least16_t> atomic_int_least16_t; |
179 | |
180 | /// atomic_uint_least16_t |
181 | typedef __atomic_base<uint_least16_t> atomic_uint_least16_t; |
182 | |
183 | /// atomic_int_least32_t |
184 | typedef __atomic_base<int_least32_t> atomic_int_least32_t; |
185 | |
186 | /// atomic_uint_least32_t |
187 | typedef __atomic_base<uint_least32_t> atomic_uint_least32_t; |
188 | |
189 | /// atomic_int_least64_t |
190 | typedef __atomic_base<int_least64_t> atomic_int_least64_t; |
191 | |
192 | /// atomic_uint_least64_t |
193 | typedef __atomic_base<uint_least64_t> atomic_uint_least64_t; |
194 | |
195 | |
196 | /// atomic_int_fast8_t |
197 | typedef __atomic_base<int_fast8_t> atomic_int_fast8_t; |
198 | |
199 | /// atomic_uint_fast8_t |
200 | typedef __atomic_base<uint_fast8_t> atomic_uint_fast8_t; |
201 | |
202 | /// atomic_int_fast16_t |
203 | typedef __atomic_base<int_fast16_t> atomic_int_fast16_t; |
204 | |
205 | /// atomic_uint_fast16_t |
206 | typedef __atomic_base<uint_fast16_t> atomic_uint_fast16_t; |
207 | |
208 | /// atomic_int_fast32_t |
209 | typedef __atomic_base<int_fast32_t> atomic_int_fast32_t; |
210 | |
211 | /// atomic_uint_fast32_t |
212 | typedef __atomic_base<uint_fast32_t> atomic_uint_fast32_t; |
213 | |
214 | /// atomic_int_fast64_t |
215 | typedef __atomic_base<int_fast64_t> atomic_int_fast64_t; |
216 | |
217 | /// atomic_uint_fast64_t |
218 | typedef __atomic_base<uint_fast64_t> atomic_uint_fast64_t; |
219 | |
220 | |
221 | /// atomic_intptr_t |
222 | typedef __atomic_base<intptr_t> atomic_intptr_t; |
223 | |
224 | /// atomic_uintptr_t |
225 | typedef __atomic_base<uintptr_t> atomic_uintptr_t; |
226 | |
227 | /// atomic_size_t |
228 | typedef __atomic_base<size_t> atomic_size_t; |
229 | |
230 | /// atomic_intmax_t |
231 | typedef __atomic_base<intmax_t> atomic_intmax_t; |
232 | |
233 | /// atomic_uintmax_t |
234 | typedef __atomic_base<uintmax_t> atomic_uintmax_t; |
235 | |
236 | /// atomic_ptrdiff_t |
237 | typedef __atomic_base<ptrdiff_t> atomic_ptrdiff_t; |
238 | |
239 | |
240 | #define ATOMIC_VAR_INIT(_VI) { _VI } |
241 | |
242 | template<typename _Tp> |
243 | struct atomic; |
244 | |
245 | template<typename _Tp> |
246 | struct atomic<_Tp*>; |
247 | |
248 | |
249 | /** |
250 | * @brief Base type for atomic_flag. |
251 | * |
252 | * Base type is POD with data, allowing atomic_flag to derive from |
253 | * it and meet the standard layout type requirement. In addition to |
254 | * compatibilty with a C interface, this allows different |
255 | * implementations of atomic_flag to use the same atomic operation |
256 | * functions, via a standard conversion to the __atomic_flag_base |
257 | * argument. |
258 | */ |
259 | // _GLIBCXX_BEGIN_EXTERN_C |
260 | |
261 | struct __atomic_flag_base |
262 | { |
263 | bool _M_i; |
264 | }; |
265 | |
266 | // _GLIBCXX_END_EXTERN_C |
267 | |
268 | #define ATOMIC_FLAG_INIT { false } |
269 | |
270 | /// atomic_flag |
271 | struct atomic_flag : public __atomic_flag_base |
272 | { |
273 | atomic_flag() noexcept = default; |
274 | ~atomic_flag() noexcept = default; |
275 | atomic_flag(const atomic_flag&) = delete; |
276 | atomic_flag& operator=(const atomic_flag&) = delete; |
277 | atomic_flag& operator=(const atomic_flag&) volatile = delete; |
278 | |
279 | // Conversion to ATOMIC_FLAG_INIT. |
280 | atomic_flag(bool __i) noexcept : __atomic_flag_base({ __i }) { } |
281 | |
282 | __libitm_always_inline bool |
283 | test_and_set(memory_order __m = memory_order_seq_cst) noexcept |
284 | { |
285 | return __atomic_test_and_set (&_M_i, __m); |
286 | } |
287 | |
288 | __libitm_always_inline bool |
289 | test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept |
290 | { |
291 | return __atomic_test_and_set (&_M_i, __m); |
292 | } |
293 | |
294 | __libitm_always_inline void |
295 | clear(memory_order __m = memory_order_seq_cst) noexcept |
296 | { |
297 | // __glibcxx_assert(__m != memory_order_consume); |
298 | // __glibcxx_assert(__m != memory_order_acquire); |
299 | // __glibcxx_assert(__m != memory_order_acq_rel); |
300 | |
301 | __atomic_clear (&_M_i, __m); |
302 | } |
303 | |
304 | __libitm_always_inline void |
305 | clear(memory_order __m = memory_order_seq_cst) volatile noexcept |
306 | { |
307 | // __glibcxx_assert(__m != memory_order_consume); |
308 | // __glibcxx_assert(__m != memory_order_acquire); |
309 | // __glibcxx_assert(__m != memory_order_acq_rel); |
310 | |
311 | __atomic_clear (&_M_i, __m); |
312 | } |
313 | }; |
314 | |
315 | |
316 | /// Base class for atomic integrals. |
317 | // |
318 | // For each of the integral types, define atomic_[integral type] struct |
319 | // |
320 | // atomic_bool bool |
321 | // atomic_char char |
322 | // atomic_schar signed char |
323 | // atomic_uchar unsigned char |
324 | // atomic_short short |
325 | // atomic_ushort unsigned short |
326 | // atomic_int int |
327 | // atomic_uint unsigned int |
328 | // atomic_long long |
329 | // atomic_ulong unsigned long |
330 | // atomic_llong long long |
331 | // atomic_ullong unsigned long long |
332 | // atomic_char16_t char16_t |
333 | // atomic_char32_t char32_t |
334 | // atomic_wchar_t wchar_t |
335 | // |
336 | // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or |
337 | // 8 bytes, since that is what GCC built-in functions for atomic |
338 | // memory access expect. |
339 | template<typename _ITp> |
340 | struct __atomic_base |
341 | { |
342 | private: |
343 | typedef _ITp __int_type; |
344 | |
345 | __int_type _M_i; |
346 | |
347 | public: |
348 | __atomic_base() noexcept = default; |
349 | ~__atomic_base() noexcept = default; |
350 | __atomic_base(const __atomic_base&) = delete; |
351 | __atomic_base& operator=(const __atomic_base&) = delete; |
352 | __atomic_base& operator=(const __atomic_base&) volatile = delete; |
353 | |
354 | // Requires __int_type convertible to _M_i. |
355 | constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { } |
356 | |
357 | operator __int_type() const noexcept |
358 | { return load(); } |
359 | |
360 | operator __int_type() const volatile noexcept |
361 | { return load(); } |
362 | |
363 | __int_type |
364 | operator=(__int_type __i) noexcept |
365 | { |
366 | store(__i); |
367 | return __i; |
368 | } |
369 | |
370 | __int_type |
371 | operator=(__int_type __i) volatile noexcept |
372 | { |
373 | store(__i); |
374 | return __i; |
375 | } |
376 | |
377 | __int_type |
378 | operator++(int) noexcept |
379 | { return fetch_add(1); } |
380 | |
381 | __int_type |
382 | operator++(int) volatile noexcept |
383 | { return fetch_add(1); } |
384 | |
385 | __int_type |
386 | operator--(int) noexcept |
387 | { return fetch_sub(1); } |
388 | |
389 | __int_type |
390 | operator--(int) volatile noexcept |
391 | { return fetch_sub(1); } |
392 | |
393 | __int_type |
394 | operator++() noexcept |
395 | { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); } |
396 | |
397 | __int_type |
398 | operator++() volatile noexcept |
399 | { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); } |
400 | |
401 | __int_type |
402 | operator--() noexcept |
403 | { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); } |
404 | |
405 | __int_type |
406 | operator--() volatile noexcept |
407 | { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); } |
408 | |
409 | __int_type |
410 | operator+=(__int_type __i) noexcept |
411 | { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); } |
412 | |
413 | __int_type |
414 | operator+=(__int_type __i) volatile noexcept |
415 | { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); } |
416 | |
417 | __int_type |
418 | operator-=(__int_type __i) noexcept |
419 | { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); } |
420 | |
421 | __int_type |
422 | operator-=(__int_type __i) volatile noexcept |
423 | { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); } |
424 | |
425 | __int_type |
426 | operator&=(__int_type __i) noexcept |
427 | { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); } |
428 | |
429 | __int_type |
430 | operator&=(__int_type __i) volatile noexcept |
431 | { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); } |
432 | |
433 | __int_type |
434 | operator|=(__int_type __i) noexcept |
435 | { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); } |
436 | |
437 | __int_type |
438 | operator|=(__int_type __i) volatile noexcept |
439 | { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); } |
440 | |
441 | __int_type |
442 | operator^=(__int_type __i) noexcept |
443 | { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); } |
444 | |
445 | __int_type |
446 | operator^=(__int_type __i) volatile noexcept |
447 | { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); } |
448 | |
449 | bool |
450 | is_lock_free() const noexcept |
451 | { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); } |
452 | |
453 | bool |
454 | is_lock_free() const volatile noexcept |
455 | { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); } |
456 | |
457 | __libitm_always_inline void |
458 | store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept |
459 | { |
460 | // __glibcxx_assert(__m != memory_order_acquire); |
461 | // __glibcxx_assert(__m != memory_order_acq_rel); |
462 | // __glibcxx_assert(__m != memory_order_consume); |
463 | |
464 | __atomic_store_n(&_M_i, __i, __m); |
465 | } |
466 | |
467 | __libitm_always_inline void |
468 | store(__int_type __i, |
469 | memory_order __m = memory_order_seq_cst) volatile noexcept |
470 | { |
471 | // __glibcxx_assert(__m != memory_order_acquire); |
472 | // __glibcxx_assert(__m != memory_order_acq_rel); |
473 | // __glibcxx_assert(__m != memory_order_consume); |
474 | |
475 | __atomic_store_n(&_M_i, __i, __m); |
476 | } |
477 | |
478 | __libitm_always_inline __int_type |
479 | load(memory_order __m = memory_order_seq_cst) const noexcept |
480 | { |
481 | // __glibcxx_assert(__m != memory_order_release); |
482 | // __glibcxx_assert(__m != memory_order_acq_rel); |
483 | |
484 | return __atomic_load_n(&_M_i, __m); |
485 | } |
486 | |
487 | __libitm_always_inline __int_type |
488 | load(memory_order __m = memory_order_seq_cst) const volatile noexcept |
489 | { |
490 | // __glibcxx_assert(__m != memory_order_release); |
491 | // __glibcxx_assert(__m != memory_order_acq_rel); |
492 | |
493 | return __atomic_load_n(&_M_i, __m); |
494 | } |
495 | |
496 | __libitm_always_inline __int_type |
497 | exchange(__int_type __i, |
498 | memory_order __m = memory_order_seq_cst) noexcept |
499 | { |
500 | return __atomic_exchange_n(&_M_i, __i, __m); |
501 | } |
502 | |
503 | __libitm_always_inline __int_type |
504 | exchange(__int_type __i, |
505 | memory_order __m = memory_order_seq_cst) volatile noexcept |
506 | { |
507 | return __atomic_exchange_n(&_M_i, __i, __m); |
508 | } |
509 | |
510 | __libitm_always_inline bool |
511 | compare_exchange_weak(__int_type& __i1, __int_type __i2, |
512 | memory_order __m1, memory_order __m2) noexcept |
513 | { |
514 | // __glibcxx_assert(__m2 != memory_order_release); |
515 | // __glibcxx_assert(__m2 != memory_order_acq_rel); |
516 | // __glibcxx_assert(__m2 <= __m1); |
517 | |
518 | return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2); |
519 | } |
520 | |
521 | __libitm_always_inline bool |
522 | compare_exchange_weak(__int_type& __i1, __int_type __i2, |
523 | memory_order __m1, |
524 | memory_order __m2) volatile noexcept |
525 | { |
526 | // __glibcxx_assert(__m2 != memory_order_release); |
527 | // __glibcxx_assert(__m2 != memory_order_acq_rel); |
528 | // __glibcxx_assert(__m2 <= __m1); |
529 | |
530 | return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2); |
531 | } |
532 | |
533 | __libitm_always_inline bool |
534 | compare_exchange_weak(__int_type& __i1, __int_type __i2, |
535 | memory_order __m = memory_order_seq_cst) noexcept |
536 | { |
537 | return compare_exchange_weak(__i1, __i2, __m, |
538 | __calculate_memory_order(__m)); |
539 | } |
540 | |
541 | __libitm_always_inline bool |
542 | compare_exchange_weak(__int_type& __i1, __int_type __i2, |
543 | memory_order __m = memory_order_seq_cst) volatile noexcept |
544 | { |
545 | return compare_exchange_weak(__i1, __i2, __m, |
546 | __calculate_memory_order(__m)); |
547 | } |
548 | |
549 | __libitm_always_inline bool |
550 | compare_exchange_strong(__int_type& __i1, __int_type __i2, |
551 | memory_order __m1, memory_order __m2) noexcept |
552 | { |
553 | // __glibcxx_assert(__m2 != memory_order_release); |
554 | // __glibcxx_assert(__m2 != memory_order_acq_rel); |
555 | // __glibcxx_assert(__m2 <= __m1); |
556 | |
557 | return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2); |
558 | } |
559 | |
560 | __libitm_always_inline bool |
561 | compare_exchange_strong(__int_type& __i1, __int_type __i2, |
562 | memory_order __m1, |
563 | memory_order __m2) volatile noexcept |
564 | { |
565 | // __glibcxx_assert(__m2 != memory_order_release); |
566 | // __glibcxx_assert(__m2 != memory_order_acq_rel); |
567 | // __glibcxx_assert(__m2 <= __m1); |
568 | |
569 | return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2); |
570 | } |
571 | |
572 | __libitm_always_inline bool |
573 | compare_exchange_strong(__int_type& __i1, __int_type __i2, |
574 | memory_order __m = memory_order_seq_cst) noexcept |
575 | { |
576 | return compare_exchange_strong(__i1, __i2, __m, |
577 | __calculate_memory_order(__m)); |
578 | } |
579 | |
580 | __libitm_always_inline bool |
581 | compare_exchange_strong(__int_type& __i1, __int_type __i2, |
582 | memory_order __m = memory_order_seq_cst) volatile noexcept |
583 | { |
584 | return compare_exchange_strong(__i1, __i2, __m, |
585 | __calculate_memory_order(__m)); |
586 | } |
587 | |
588 | __libitm_always_inline __int_type |
589 | fetch_add(__int_type __i, |
590 | memory_order __m = memory_order_seq_cst) noexcept |
591 | { return __atomic_fetch_add(&_M_i, __i, __m); } |
592 | |
593 | __libitm_always_inline __int_type |
594 | fetch_add(__int_type __i, |
595 | memory_order __m = memory_order_seq_cst) volatile noexcept |
596 | { return __atomic_fetch_add(&_M_i, __i, __m); } |
597 | |
598 | __libitm_always_inline __int_type |
599 | fetch_sub(__int_type __i, |
600 | memory_order __m = memory_order_seq_cst) noexcept |
601 | { return __atomic_fetch_sub(&_M_i, __i, __m); } |
602 | |
603 | __libitm_always_inline __int_type |
604 | fetch_sub(__int_type __i, |
605 | memory_order __m = memory_order_seq_cst) volatile noexcept |
606 | { return __atomic_fetch_sub(&_M_i, __i, __m); } |
607 | |
608 | __libitm_always_inline __int_type |
609 | fetch_and(__int_type __i, |
610 | memory_order __m = memory_order_seq_cst) noexcept |
611 | { return __atomic_fetch_and(&_M_i, __i, __m); } |
612 | |
613 | __libitm_always_inline __int_type |
614 | fetch_and(__int_type __i, |
615 | memory_order __m = memory_order_seq_cst) volatile noexcept |
616 | { return __atomic_fetch_and(&_M_i, __i, __m); } |
617 | |
618 | __libitm_always_inline __int_type |
619 | fetch_or(__int_type __i, |
620 | memory_order __m = memory_order_seq_cst) noexcept |
621 | { return __atomic_fetch_or(&_M_i, __i, __m); } |
622 | |
623 | __libitm_always_inline __int_type |
624 | fetch_or(__int_type __i, |
625 | memory_order __m = memory_order_seq_cst) volatile noexcept |
626 | { return __atomic_fetch_or(&_M_i, __i, __m); } |
627 | |
628 | __libitm_always_inline __int_type |
629 | fetch_xor(__int_type __i, |
630 | memory_order __m = memory_order_seq_cst) noexcept |
631 | { return __atomic_fetch_xor(&_M_i, __i, __m); } |
632 | |
633 | __libitm_always_inline __int_type |
634 | fetch_xor(__int_type __i, |
635 | memory_order __m = memory_order_seq_cst) volatile noexcept |
636 | { return __atomic_fetch_xor(&_M_i, __i, __m); } |
637 | }; |
638 | |
639 | |
640 | /// Partial specialization for pointer types. |
641 | template<typename _PTp> |
642 | struct __atomic_base<_PTp*> |
643 | { |
644 | private: |
645 | typedef _PTp* __pointer_type; |
646 | |
647 | __pointer_type _M_p; |
648 | |
649 | public: |
650 | __atomic_base() noexcept = default; |
651 | ~__atomic_base() noexcept = default; |
652 | __atomic_base(const __atomic_base&) = delete; |
653 | __atomic_base& operator=(const __atomic_base&) = delete; |
654 | __atomic_base& operator=(const __atomic_base&) volatile = delete; |
655 | |
656 | // Requires __pointer_type convertible to _M_p. |
657 | constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { } |
658 | |
659 | operator __pointer_type() const noexcept |
660 | { return load(); } |
661 | |
662 | operator __pointer_type() const volatile noexcept |
663 | { return load(); } |
664 | |
665 | __pointer_type |
666 | operator=(__pointer_type __p) noexcept |
667 | { |
668 | store(__p); |
669 | return __p; |
670 | } |
671 | |
672 | __pointer_type |
673 | operator=(__pointer_type __p) volatile noexcept |
674 | { |
675 | store(__p); |
676 | return __p; |
677 | } |
678 | |
679 | __pointer_type |
680 | operator++(int) noexcept |
681 | { return fetch_add(1); } |
682 | |
683 | __pointer_type |
684 | operator++(int) volatile noexcept |
685 | { return fetch_add(1); } |
686 | |
687 | __pointer_type |
688 | operator--(int) noexcept |
689 | { return fetch_sub(1); } |
690 | |
691 | __pointer_type |
692 | operator--(int) volatile noexcept |
693 | { return fetch_sub(1); } |
694 | |
695 | __pointer_type |
696 | operator++() noexcept |
697 | { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); } |
698 | |
699 | __pointer_type |
700 | operator++() volatile noexcept |
701 | { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); } |
702 | |
703 | __pointer_type |
704 | operator--() noexcept |
705 | { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); } |
706 | |
707 | __pointer_type |
708 | operator--() volatile noexcept |
709 | { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); } |
710 | |
711 | __pointer_type |
712 | operator+=(ptrdiff_t __d) noexcept |
713 | { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); } |
714 | |
715 | __pointer_type |
716 | operator+=(ptrdiff_t __d) volatile noexcept |
717 | { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); } |
718 | |
719 | __pointer_type |
720 | operator-=(ptrdiff_t __d) noexcept |
721 | { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); } |
722 | |
723 | __pointer_type |
724 | operator-=(ptrdiff_t __d) volatile noexcept |
725 | { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); } |
726 | |
727 | bool |
728 | is_lock_free() const noexcept |
729 | { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); } |
730 | |
731 | bool |
732 | is_lock_free() const volatile noexcept |
733 | { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); } |
734 | |
735 | __libitm_always_inline void |
736 | store(__pointer_type __p, |
737 | memory_order __m = memory_order_seq_cst) noexcept |
738 | { |
739 | // __glibcxx_assert(__m != memory_order_acquire); |
740 | // __glibcxx_assert(__m != memory_order_acq_rel); |
741 | // __glibcxx_assert(__m != memory_order_consume); |
742 | |
743 | __atomic_store_n(&_M_p, __p, __m); |
744 | } |
745 | |
746 | __libitm_always_inline void |
747 | store(__pointer_type __p, |
748 | memory_order __m = memory_order_seq_cst) volatile noexcept |
749 | { |
750 | // __glibcxx_assert(__m != memory_order_acquire); |
751 | // __glibcxx_assert(__m != memory_order_acq_rel); |
752 | // __glibcxx_assert(__m != memory_order_consume); |
753 | |
754 | __atomic_store_n(&_M_p, __p, __m); |
755 | } |
756 | |
757 | __libitm_always_inline __pointer_type |
758 | load(memory_order __m = memory_order_seq_cst) const noexcept |
759 | { |
760 | // __glibcxx_assert(__m != memory_order_release); |
761 | // __glibcxx_assert(__m != memory_order_acq_rel); |
762 | |
763 | return __atomic_load_n(&_M_p, __m); |
764 | } |
765 | |
766 | __libitm_always_inline __pointer_type |
767 | load(memory_order __m = memory_order_seq_cst) const volatile noexcept |
768 | { |
769 | // __glibcxx_assert(__m != memory_order_release); |
770 | // __glibcxx_assert(__m != memory_order_acq_rel); |
771 | |
772 | return __atomic_load_n(&_M_p, __m); |
773 | } |
774 | |
775 | __libitm_always_inline __pointer_type |
776 | exchange(__pointer_type __p, |
777 | memory_order __m = memory_order_seq_cst) noexcept |
778 | { |
779 | return __atomic_exchange_n(&_M_p, __p, __m); |
780 | } |
781 | |
782 | __libitm_always_inline __pointer_type |
783 | exchange(__pointer_type __p, |
784 | memory_order __m = memory_order_seq_cst) volatile noexcept |
785 | { |
786 | return __atomic_exchange_n(&_M_p, __p, __m); |
787 | } |
788 | |
789 | __libitm_always_inline bool |
790 | compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, |
791 | memory_order __m1, |
792 | memory_order __m2) noexcept |
793 | { |
794 | // __glibcxx_assert(__m2 != memory_order_release); |
795 | // __glibcxx_assert(__m2 != memory_order_acq_rel); |
796 | // __glibcxx_assert(__m2 <= __m1); |
797 | |
798 | return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2); |
799 | } |
800 | |
801 | __libitm_always_inline bool |
802 | compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, |
803 | memory_order __m1, |
804 | memory_order __m2) volatile noexcept |
805 | { |
806 | // __glibcxx_assert(__m2 != memory_order_release); |
807 | // __glibcxx_assert(__m2 != memory_order_acq_rel); |
808 | // __glibcxx_assert(__m2 <= __m1); |
809 | |
810 | return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2); |
811 | } |
812 | |
813 | __libitm_always_inline __pointer_type |
814 | fetch_add(ptrdiff_t __d, |
815 | memory_order __m = memory_order_seq_cst) noexcept |
816 | { return __atomic_fetch_add(&_M_p, __d, __m); } |
817 | |
818 | __libitm_always_inline __pointer_type |
819 | fetch_add(ptrdiff_t __d, |
820 | memory_order __m = memory_order_seq_cst) volatile noexcept |
821 | { return __atomic_fetch_add(&_M_p, __d, __m); } |
822 | |
823 | __libitm_always_inline __pointer_type |
824 | fetch_sub(ptrdiff_t __d, |
825 | memory_order __m = memory_order_seq_cst) noexcept |
826 | { return __atomic_fetch_sub(&_M_p, __d, __m); } |
827 | |
828 | __libitm_always_inline __pointer_type |
829 | fetch_sub(ptrdiff_t __d, |
830 | memory_order __m = memory_order_seq_cst) volatile noexcept |
831 | { return __atomic_fetch_sub(&_M_p, __d, __m); } |
832 | }; |
833 | |
834 | |
835 | /** |
836 | * @addtogroup atomics |
837 | * @{ |
838 | */ |
839 | |
840 | /// atomic_bool |
841 | // NB: No operators or fetch-operations for this type. |
842 | struct atomic_bool |
843 | { |
844 | private: |
845 | __atomic_base<bool> _M_base; |
846 | |
847 | public: |
848 | atomic_bool() noexcept = default; |
849 | ~atomic_bool() noexcept = default; |
850 | atomic_bool(const atomic_bool&) = delete; |
851 | atomic_bool& operator=(const atomic_bool&) = delete; |
852 | atomic_bool& operator=(const atomic_bool&) volatile = delete; |
853 | |
854 | constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { } |
855 | |
856 | bool |
857 | operator=(bool __i) noexcept |
858 | { return _M_base.operator=(__i); } |
859 | |
860 | operator bool() const noexcept |
861 | { return _M_base.load(); } |
862 | |
863 | operator bool() const volatile noexcept |
864 | { return _M_base.load(); } |
865 | |
866 | bool |
867 | is_lock_free() const noexcept { return _M_base.is_lock_free(); } |
868 | |
869 | bool |
870 | is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } |
871 | |
872 | __libitm_always_inline void |
873 | store(bool __i, memory_order __m = memory_order_seq_cst) noexcept |
874 | { _M_base.store(__i, __m); } |
875 | |
876 | __libitm_always_inline void |
877 | store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept |
878 | { _M_base.store(__i, __m); } |
879 | |
880 | __libitm_always_inline bool |
881 | load(memory_order __m = memory_order_seq_cst) const noexcept |
882 | { return _M_base.load(__m); } |
883 | |
884 | __libitm_always_inline bool |
885 | load(memory_order __m = memory_order_seq_cst) const volatile noexcept |
886 | { return _M_base.load(__m); } |
887 | |
888 | __libitm_always_inline bool |
889 | exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept |
890 | { return _M_base.exchange(__i, __m); } |
891 | |
892 | __libitm_always_inline bool |
893 | exchange(bool __i, |
894 | memory_order __m = memory_order_seq_cst) volatile noexcept |
895 | { return _M_base.exchange(__i, __m); } |
896 | |
897 | __libitm_always_inline bool |
898 | compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, |
899 | memory_order __m2) noexcept |
900 | { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } |
901 | |
902 | __libitm_always_inline bool |
903 | compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, |
904 | memory_order __m2) volatile noexcept |
905 | { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } |
906 | |
907 | __libitm_always_inline bool |
908 | compare_exchange_weak(bool& __i1, bool __i2, |
909 | memory_order __m = memory_order_seq_cst) noexcept |
910 | { return _M_base.compare_exchange_weak(__i1, __i2, __m); } |
911 | |
912 | __libitm_always_inline bool |
913 | compare_exchange_weak(bool& __i1, bool __i2, |
914 | memory_order __m = memory_order_seq_cst) volatile noexcept |
915 | { return _M_base.compare_exchange_weak(__i1, __i2, __m); } |
916 | |
917 | __libitm_always_inline bool |
918 | compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, |
919 | memory_order __m2) noexcept |
920 | { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } |
921 | |
922 | __libitm_always_inline bool |
923 | compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, |
924 | memory_order __m2) volatile noexcept |
925 | { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } |
926 | |
927 | __libitm_always_inline bool |
928 | compare_exchange_strong(bool& __i1, bool __i2, |
929 | memory_order __m = memory_order_seq_cst) noexcept |
930 | { return _M_base.compare_exchange_strong(__i1, __i2, __m); } |
931 | |
932 | __libitm_always_inline bool |
933 | compare_exchange_strong(bool& __i1, bool __i2, |
934 | memory_order __m = memory_order_seq_cst) volatile noexcept |
935 | { return _M_base.compare_exchange_strong(__i1, __i2, __m); } |
936 | }; |
937 | |
938 | |
939 | /// atomic |
940 | /// 29.4.3, Generic atomic type, primary class template. |
941 | template<typename _Tp> |
942 | struct atomic |
943 | { |
944 | private: |
945 | _Tp _M_i; |
946 | |
947 | public: |
948 | atomic() noexcept = default; |
949 | ~atomic() noexcept = default; |
950 | atomic(const atomic&) = delete; |
951 | atomic& operator=(const atomic&) = delete; |
952 | atomic& operator=(const atomic&) volatile = delete; |
953 | |
954 | constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } |
955 | |
956 | operator _Tp() const noexcept |
957 | { return load(); } |
958 | |
959 | operator _Tp() const volatile noexcept |
960 | { return load(); } |
961 | |
962 | _Tp |
963 | operator=(_Tp __i) noexcept |
964 | { store(__i); return __i; } |
965 | |
966 | _Tp |
967 | operator=(_Tp __i) volatile noexcept |
968 | { store(__i); return __i; } |
969 | |
970 | bool |
971 | is_lock_free() const noexcept |
972 | { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); } |
973 | |
974 | bool |
975 | is_lock_free() const volatile noexcept |
976 | { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); } |
977 | |
978 | void |
979 | store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept |
980 | { __atomic_store(&_M_i, &__i, _m); } |
981 | |
982 | __libitm_always_inline void |
983 | store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept |
984 | { __atomic_store(&_M_i, &__i, _m); } |
985 | |
986 | __libitm_always_inline _Tp |
987 | load(memory_order _m = memory_order_seq_cst) const noexcept |
988 | { |
989 | _Tp tmp; |
990 | __atomic_load(&_M_i, &tmp, _m); |
991 | return tmp; |
992 | } |
993 | |
994 | __libitm_always_inline _Tp |
995 | load(memory_order _m = memory_order_seq_cst) const volatile noexcept |
996 | { |
997 | _Tp tmp; |
998 | __atomic_load(&_M_i, &tmp, _m); |
999 | return tmp; |
1000 | } |
1001 | |
1002 | __libitm_always_inline _Tp |
1003 | exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept |
1004 | { |
1005 | _Tp tmp; |
1006 | __atomic_exchange(&_M_i, &__i, &tmp, _m); |
1007 | return tmp; |
1008 | } |
1009 | |
1010 | __libitm_always_inline _Tp |
1011 | exchange(_Tp __i, |
1012 | memory_order _m = memory_order_seq_cst) volatile noexcept |
1013 | { |
1014 | _Tp tmp; |
1015 | __atomic_exchange(&_M_i, &__i, &tmp, _m); |
1016 | return tmp; |
1017 | } |
1018 | |
1019 | __libitm_always_inline bool |
1020 | compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, |
1021 | memory_order __f) noexcept |
1022 | { |
1023 | return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); |
1024 | } |
1025 | |
1026 | __libitm_always_inline bool |
1027 | compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, |
1028 | memory_order __f) volatile noexcept |
1029 | { |
1030 | return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); |
1031 | } |
1032 | |
1033 | __libitm_always_inline bool |
1034 | compare_exchange_weak(_Tp& __e, _Tp __i, |
1035 | memory_order __m = memory_order_seq_cst) noexcept |
1036 | { return compare_exchange_weak(__e, __i, __m, __m); } |
1037 | |
1038 | __libitm_always_inline bool |
1039 | compare_exchange_weak(_Tp& __e, _Tp __i, |
1040 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1041 | { return compare_exchange_weak(__e, __i, __m, __m); } |
1042 | |
1043 | __libitm_always_inline bool |
1044 | compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, |
1045 | memory_order __f) noexcept |
1046 | { |
1047 | return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); |
1048 | } |
1049 | |
1050 | __libitm_always_inline bool |
1051 | compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, |
1052 | memory_order __f) volatile noexcept |
1053 | { |
1054 | return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); |
1055 | } |
1056 | |
1057 | __libitm_always_inline bool |
1058 | compare_exchange_strong(_Tp& __e, _Tp __i, |
1059 | memory_order __m = memory_order_seq_cst) noexcept |
1060 | { return compare_exchange_strong(__e, __i, __m, __m); } |
1061 | |
1062 | __libitm_always_inline bool |
1063 | compare_exchange_strong(_Tp& __e, _Tp __i, |
1064 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1065 | { return compare_exchange_strong(__e, __i, __m, __m); } |
1066 | }; |
1067 | |
1068 | |
1069 | /// Partial specialization for pointer types. |
1070 | template<typename _Tp> |
1071 | struct atomic<_Tp*> |
1072 | { |
1073 | typedef _Tp* __pointer_type; |
1074 | typedef __atomic_base<_Tp*> __base_type; |
1075 | __base_type _M_b; |
1076 | |
1077 | atomic() noexcept = default; |
1078 | ~atomic() noexcept = default; |
1079 | atomic(const atomic&) = delete; |
1080 | atomic& operator=(const atomic&) = delete; |
1081 | atomic& operator=(const atomic&) volatile = delete; |
1082 | |
1083 | constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } |
1084 | |
1085 | operator __pointer_type() const noexcept |
1086 | { return __pointer_type(_M_b); } |
1087 | |
1088 | operator __pointer_type() const volatile noexcept |
1089 | { return __pointer_type(_M_b); } |
1090 | |
1091 | __pointer_type |
1092 | operator=(__pointer_type __p) noexcept |
1093 | { return _M_b.operator=(__p); } |
1094 | |
1095 | __pointer_type |
1096 | operator=(__pointer_type __p) volatile noexcept |
1097 | { return _M_b.operator=(__p); } |
1098 | |
1099 | __pointer_type |
1100 | operator++(int) noexcept |
1101 | { return _M_b++; } |
1102 | |
1103 | __pointer_type |
1104 | operator++(int) volatile noexcept |
1105 | { return _M_b++; } |
1106 | |
1107 | __pointer_type |
1108 | operator--(int) noexcept |
1109 | { return _M_b--; } |
1110 | |
1111 | __pointer_type |
1112 | operator--(int) volatile noexcept |
1113 | { return _M_b--; } |
1114 | |
1115 | __pointer_type |
1116 | operator++() noexcept |
1117 | { return ++_M_b; } |
1118 | |
1119 | __pointer_type |
1120 | operator++() volatile noexcept |
1121 | { return ++_M_b; } |
1122 | |
1123 | __pointer_type |
1124 | operator--() noexcept |
1125 | { return --_M_b; } |
1126 | |
1127 | __pointer_type |
1128 | operator--() volatile noexcept |
1129 | { return --_M_b; } |
1130 | |
1131 | __pointer_type |
1132 | operator+=(ptrdiff_t __d) noexcept |
1133 | { return _M_b.operator+=(__d); } |
1134 | |
1135 | __pointer_type |
1136 | operator+=(ptrdiff_t __d) volatile noexcept |
1137 | { return _M_b.operator+=(__d); } |
1138 | |
1139 | __pointer_type |
1140 | operator-=(ptrdiff_t __d) noexcept |
1141 | { return _M_b.operator-=(__d); } |
1142 | |
1143 | __pointer_type |
1144 | operator-=(ptrdiff_t __d) volatile noexcept |
1145 | { return _M_b.operator-=(__d); } |
1146 | |
1147 | bool |
1148 | is_lock_free() const noexcept |
1149 | { return _M_b.is_lock_free(); } |
1150 | |
1151 | bool |
1152 | is_lock_free() const volatile noexcept |
1153 | { return _M_b.is_lock_free(); } |
1154 | |
1155 | __libitm_always_inline void |
1156 | store(__pointer_type __p, |
1157 | memory_order __m = memory_order_seq_cst) noexcept |
1158 | { return _M_b.store(__p, __m); } |
1159 | |
1160 | __libitm_always_inline void |
1161 | store(__pointer_type __p, |
1162 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1163 | { return _M_b.store(__p, __m); } |
1164 | |
1165 | __libitm_always_inline __pointer_type |
1166 | load(memory_order __m = memory_order_seq_cst) const noexcept |
1167 | { return _M_b.load(__m); } |
1168 | |
1169 | __libitm_always_inline __pointer_type |
1170 | load(memory_order __m = memory_order_seq_cst) const volatile noexcept |
1171 | { return _M_b.load(__m); } |
1172 | |
1173 | __libitm_always_inline __pointer_type |
1174 | exchange(__pointer_type __p, |
1175 | memory_order __m = memory_order_seq_cst) noexcept |
1176 | { return _M_b.exchange(__p, __m); } |
1177 | |
1178 | __libitm_always_inline __pointer_type |
1179 | exchange(__pointer_type __p, |
1180 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1181 | { return _M_b.exchange(__p, __m); } |
1182 | |
1183 | __libitm_always_inline bool |
1184 | compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, |
1185 | memory_order __m1, memory_order __m2) noexcept |
1186 | { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } |
1187 | |
1188 | __libitm_always_inline bool |
1189 | compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, |
1190 | memory_order __m1, |
1191 | memory_order __m2) volatile noexcept |
1192 | { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } |
1193 | |
1194 | __libitm_always_inline bool |
1195 | compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, |
1196 | memory_order __m = memory_order_seq_cst) noexcept |
1197 | { |
1198 | return compare_exchange_weak(__p1, __p2, __m, |
1199 | __calculate_memory_order(__m)); |
1200 | } |
1201 | |
1202 | __libitm_always_inline bool |
1203 | compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, |
1204 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1205 | { |
1206 | return compare_exchange_weak(__p1, __p2, __m, |
1207 | __calculate_memory_order(__m)); |
1208 | } |
1209 | |
1210 | __libitm_always_inline bool |
1211 | compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, |
1212 | memory_order __m1, memory_order __m2) noexcept |
1213 | { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } |
1214 | |
1215 | __libitm_always_inline bool |
1216 | compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, |
1217 | memory_order __m1, |
1218 | memory_order __m2) volatile noexcept |
1219 | { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } |
1220 | |
1221 | __libitm_always_inline bool |
1222 | compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, |
1223 | memory_order __m = memory_order_seq_cst) noexcept |
1224 | { |
1225 | return _M_b.compare_exchange_strong(__p1, __p2, __m, |
1226 | __calculate_memory_order(__m)); |
1227 | } |
1228 | |
1229 | __libitm_always_inline bool |
1230 | compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, |
1231 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1232 | { |
1233 | return _M_b.compare_exchange_strong(__p1, __p2, __m, |
1234 | __calculate_memory_order(__m)); |
1235 | } |
1236 | |
1237 | __libitm_always_inline __pointer_type |
1238 | fetch_add(ptrdiff_t __d, |
1239 | memory_order __m = memory_order_seq_cst) noexcept |
1240 | { return _M_b.fetch_add(__d, __m); } |
1241 | |
1242 | __libitm_always_inline __pointer_type |
1243 | fetch_add(ptrdiff_t __d, |
1244 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1245 | { return _M_b.fetch_add(__d, __m); } |
1246 | |
1247 | __libitm_always_inline __pointer_type |
1248 | fetch_sub(ptrdiff_t __d, |
1249 | memory_order __m = memory_order_seq_cst) noexcept |
1250 | { return _M_b.fetch_sub(__d, __m); } |
1251 | |
1252 | __libitm_always_inline __pointer_type |
1253 | fetch_sub(ptrdiff_t __d, |
1254 | memory_order __m = memory_order_seq_cst) volatile noexcept |
1255 | { return _M_b.fetch_sub(__d, __m); } |
1256 | }; |
1257 | |
1258 | |
1259 | /// Explicit specialization for bool. |
1260 | template<> |
1261 | struct atomic<bool> : public atomic_bool |
1262 | { |
1263 | typedef bool __integral_type; |
1264 | typedef atomic_bool __base_type; |
1265 | |
1266 | atomic() noexcept = default; |
1267 | ~atomic() noexcept = default; |
1268 | atomic(const atomic&) = delete; |
1269 | atomic& operator=(const atomic&) = delete; |
1270 | atomic& operator=(const atomic&) volatile = delete; |
1271 | |
1272 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1273 | |
1274 | using __base_type::operator __integral_type; |
1275 | using __base_type::operator=; |
1276 | }; |
1277 | |
1278 | /// Explicit specialization for char. |
1279 | template<> |
1280 | struct atomic<char> : public atomic_char |
1281 | { |
1282 | typedef char __integral_type; |
1283 | typedef atomic_char __base_type; |
1284 | |
1285 | atomic() noexcept = default; |
1286 | ~atomic() noexcept = default; |
1287 | atomic(const atomic&) = delete; |
1288 | atomic& operator=(const atomic&) = delete; |
1289 | atomic& operator=(const atomic&) volatile = delete; |
1290 | |
1291 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1292 | |
1293 | using __base_type::operator __integral_type; |
1294 | using __base_type::operator=; |
1295 | }; |
1296 | |
1297 | /// Explicit specialization for signed char. |
1298 | template<> |
1299 | struct atomic<signed char> : public atomic_schar |
1300 | { |
1301 | typedef signed char __integral_type; |
1302 | typedef atomic_schar __base_type; |
1303 | |
1304 | atomic() noexcept= default; |
1305 | ~atomic() noexcept = default; |
1306 | atomic(const atomic&) = delete; |
1307 | atomic& operator=(const atomic&) = delete; |
1308 | atomic& operator=(const atomic&) volatile = delete; |
1309 | |
1310 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1311 | |
1312 | using __base_type::operator __integral_type; |
1313 | using __base_type::operator=; |
1314 | }; |
1315 | |
1316 | /// Explicit specialization for unsigned char. |
1317 | template<> |
1318 | struct atomic<unsigned char> : public atomic_uchar |
1319 | { |
1320 | typedef unsigned char __integral_type; |
1321 | typedef atomic_uchar __base_type; |
1322 | |
1323 | atomic() noexcept= default; |
1324 | ~atomic() noexcept = default; |
1325 | atomic(const atomic&) = delete; |
1326 | atomic& operator=(const atomic&) = delete; |
1327 | atomic& operator=(const atomic&) volatile = delete; |
1328 | |
1329 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1330 | |
1331 | using __base_type::operator __integral_type; |
1332 | using __base_type::operator=; |
1333 | }; |
1334 | |
1335 | /// Explicit specialization for short. |
1336 | template<> |
1337 | struct atomic<short> : public atomic_short |
1338 | { |
1339 | typedef short __integral_type; |
1340 | typedef atomic_short __base_type; |
1341 | |
1342 | atomic() noexcept = default; |
1343 | ~atomic() noexcept = default; |
1344 | atomic(const atomic&) = delete; |
1345 | atomic& operator=(const atomic&) = delete; |
1346 | atomic& operator=(const atomic&) volatile = delete; |
1347 | |
1348 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1349 | |
1350 | using __base_type::operator __integral_type; |
1351 | using __base_type::operator=; |
1352 | }; |
1353 | |
1354 | /// Explicit specialization for unsigned short. |
1355 | template<> |
1356 | struct atomic<unsigned short> : public atomic_ushort |
1357 | { |
1358 | typedef unsigned short __integral_type; |
1359 | typedef atomic_ushort __base_type; |
1360 | |
1361 | atomic() noexcept = default; |
1362 | ~atomic() noexcept = default; |
1363 | atomic(const atomic&) = delete; |
1364 | atomic& operator=(const atomic&) = delete; |
1365 | atomic& operator=(const atomic&) volatile = delete; |
1366 | |
1367 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1368 | |
1369 | using __base_type::operator __integral_type; |
1370 | using __base_type::operator=; |
1371 | }; |
1372 | |
1373 | /// Explicit specialization for int. |
1374 | template<> |
1375 | struct atomic<int> : atomic_int |
1376 | { |
1377 | typedef int __integral_type; |
1378 | typedef atomic_int __base_type; |
1379 | |
1380 | atomic() noexcept = default; |
1381 | ~atomic() noexcept = default; |
1382 | atomic(const atomic&) = delete; |
1383 | atomic& operator=(const atomic&) = delete; |
1384 | atomic& operator=(const atomic&) volatile = delete; |
1385 | |
1386 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1387 | |
1388 | using __base_type::operator __integral_type; |
1389 | using __base_type::operator=; |
1390 | }; |
1391 | |
1392 | /// Explicit specialization for unsigned int. |
1393 | template<> |
1394 | struct atomic<unsigned int> : public atomic_uint |
1395 | { |
1396 | typedef unsigned int __integral_type; |
1397 | typedef atomic_uint __base_type; |
1398 | |
1399 | atomic() noexcept = default; |
1400 | ~atomic() noexcept = default; |
1401 | atomic(const atomic&) = delete; |
1402 | atomic& operator=(const atomic&) = delete; |
1403 | atomic& operator=(const atomic&) volatile = delete; |
1404 | |
1405 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1406 | |
1407 | using __base_type::operator __integral_type; |
1408 | using __base_type::operator=; |
1409 | }; |
1410 | |
1411 | /// Explicit specialization for long. |
1412 | template<> |
1413 | struct atomic<long> : public atomic_long |
1414 | { |
1415 | typedef long __integral_type; |
1416 | typedef atomic_long __base_type; |
1417 | |
1418 | atomic() noexcept = default; |
1419 | ~atomic() noexcept = default; |
1420 | atomic(const atomic&) = delete; |
1421 | atomic& operator=(const atomic&) = delete; |
1422 | atomic& operator=(const atomic&) volatile = delete; |
1423 | |
1424 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1425 | |
1426 | using __base_type::operator __integral_type; |
1427 | using __base_type::operator=; |
1428 | }; |
1429 | |
1430 | /// Explicit specialization for unsigned long. |
1431 | template<> |
1432 | struct atomic<unsigned long> : public atomic_ulong |
1433 | { |
1434 | typedef unsigned long __integral_type; |
1435 | typedef atomic_ulong __base_type; |
1436 | |
1437 | atomic() noexcept = default; |
1438 | ~atomic() noexcept = default; |
1439 | atomic(const atomic&) = delete; |
1440 | atomic& operator=(const atomic&) = delete; |
1441 | atomic& operator=(const atomic&) volatile = delete; |
1442 | |
1443 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1444 | |
1445 | using __base_type::operator __integral_type; |
1446 | using __base_type::operator=; |
1447 | }; |
1448 | |
1449 | /// Explicit specialization for long long. |
1450 | template<> |
1451 | struct atomic<long long> : public atomic_llong |
1452 | { |
1453 | typedef long long __integral_type; |
1454 | typedef atomic_llong __base_type; |
1455 | |
1456 | atomic() noexcept = default; |
1457 | ~atomic() noexcept = default; |
1458 | atomic(const atomic&) = delete; |
1459 | atomic& operator=(const atomic&) = delete; |
1460 | atomic& operator=(const atomic&) volatile = delete; |
1461 | |
1462 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1463 | |
1464 | using __base_type::operator __integral_type; |
1465 | using __base_type::operator=; |
1466 | }; |
1467 | |
1468 | /// Explicit specialization for unsigned long long. |
1469 | template<> |
1470 | struct atomic<unsigned long long> : public atomic_ullong |
1471 | { |
1472 | typedef unsigned long long __integral_type; |
1473 | typedef atomic_ullong __base_type; |
1474 | |
1475 | atomic() noexcept = default; |
1476 | ~atomic() noexcept = default; |
1477 | atomic(const atomic&) = delete; |
1478 | atomic& operator=(const atomic&) = delete; |
1479 | atomic& operator=(const atomic&) volatile = delete; |
1480 | |
1481 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1482 | |
1483 | using __base_type::operator __integral_type; |
1484 | using __base_type::operator=; |
1485 | }; |
1486 | |
1487 | /// Explicit specialization for wchar_t. |
1488 | template<> |
1489 | struct atomic<wchar_t> : public atomic_wchar_t |
1490 | { |
1491 | typedef wchar_t __integral_type; |
1492 | typedef atomic_wchar_t __base_type; |
1493 | |
1494 | atomic() noexcept = default; |
1495 | ~atomic() noexcept = default; |
1496 | atomic(const atomic&) = delete; |
1497 | atomic& operator=(const atomic&) = delete; |
1498 | atomic& operator=(const atomic&) volatile = delete; |
1499 | |
1500 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1501 | |
1502 | using __base_type::operator __integral_type; |
1503 | using __base_type::operator=; |
1504 | }; |
1505 | |
1506 | /// Explicit specialization for char16_t. |
1507 | template<> |
1508 | struct atomic<char16_t> : public atomic_char16_t |
1509 | { |
1510 | typedef char16_t __integral_type; |
1511 | typedef atomic_char16_t __base_type; |
1512 | |
1513 | atomic() noexcept = default; |
1514 | ~atomic() noexcept = default; |
1515 | atomic(const atomic&) = delete; |
1516 | atomic& operator=(const atomic&) = delete; |
1517 | atomic& operator=(const atomic&) volatile = delete; |
1518 | |
1519 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1520 | |
1521 | using __base_type::operator __integral_type; |
1522 | using __base_type::operator=; |
1523 | }; |
1524 | |
1525 | /// Explicit specialization for char32_t. |
1526 | template<> |
1527 | struct atomic<char32_t> : public atomic_char32_t |
1528 | { |
1529 | typedef char32_t __integral_type; |
1530 | typedef atomic_char32_t __base_type; |
1531 | |
1532 | atomic() noexcept = default; |
1533 | ~atomic() noexcept = default; |
1534 | atomic(const atomic&) = delete; |
1535 | atomic& operator=(const atomic&) = delete; |
1536 | atomic& operator=(const atomic&) volatile = delete; |
1537 | |
1538 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } |
1539 | |
1540 | using __base_type::operator __integral_type; |
1541 | using __base_type::operator=; |
1542 | }; |
1543 | |
1544 | |
1545 | // Function definitions, atomic_flag operations. |
1546 | inline __libitm_always_inline bool |
1547 | atomic_flag_test_and_set_explicit(atomic_flag* __a, |
1548 | memory_order __m) noexcept |
1549 | { return __a->test_and_set(__m); } |
1550 | |
1551 | inline __libitm_always_inline bool |
1552 | atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, |
1553 | memory_order __m) noexcept |
1554 | { return __a->test_and_set(__m); } |
1555 | |
1556 | inline __libitm_always_inline void |
1557 | atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept |
1558 | { __a->clear(__m); } |
1559 | |
1560 | inline __libitm_always_inline void |
1561 | atomic_flag_clear_explicit(volatile atomic_flag* __a, |
1562 | memory_order __m) noexcept |
1563 | { __a->clear(__m); } |
1564 | |
1565 | inline __libitm_always_inline bool |
1566 | atomic_flag_test_and_set(atomic_flag* __a) noexcept |
1567 | { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } |
1568 | |
1569 | inline __libitm_always_inline bool |
1570 | atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept |
1571 | { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } |
1572 | |
1573 | inline __libitm_always_inline void |
1574 | atomic_flag_clear(atomic_flag* __a) noexcept |
1575 | { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } |
1576 | |
1577 | inline __libitm_always_inline void |
1578 | atomic_flag_clear(volatile atomic_flag* __a) noexcept |
1579 | { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } |
1580 | |
1581 | |
1582 | // Function templates generally applicable to atomic types. |
1583 | template<typename _ITp> |
1584 | __libitm_always_inline bool |
1585 | atomic_is_lock_free(const atomic<_ITp>* __a) noexcept |
1586 | { return __a->is_lock_free(); } |
1587 | |
1588 | template<typename _ITp> |
1589 | __libitm_always_inline bool |
1590 | atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept |
1591 | { return __a->is_lock_free(); } |
1592 | |
1593 | template<typename _ITp> |
1594 | __libitm_always_inline void |
1595 | atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept; |
1596 | |
1597 | template<typename _ITp> |
1598 | __libitm_always_inline void |
1599 | atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept; |
1600 | |
1601 | template<typename _ITp> |
1602 | __libitm_always_inline void |
1603 | atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, |
1604 | memory_order __m) noexcept |
1605 | { __a->store(__i, __m); } |
1606 | |
1607 | template<typename _ITp> |
1608 | __libitm_always_inline void |
1609 | atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, |
1610 | memory_order __m) noexcept |
1611 | { __a->store(__i, __m); } |
1612 | |
1613 | template<typename _ITp> |
1614 | __libitm_always_inline _ITp |
1615 | atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept |
1616 | { return __a->load(__m); } |
1617 | |
1618 | template<typename _ITp> |
1619 | __libitm_always_inline _ITp |
1620 | atomic_load_explicit(const volatile atomic<_ITp>* __a, |
1621 | memory_order __m) noexcept |
1622 | { return __a->load(__m); } |
1623 | |
1624 | template<typename _ITp> |
1625 | __libitm_always_inline _ITp |
1626 | atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, |
1627 | memory_order __m) noexcept |
1628 | { return __a->exchange(__i, __m); } |
1629 | |
1630 | template<typename _ITp> |
1631 | __libitm_always_inline _ITp |
1632 | atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, |
1633 | memory_order __m) noexcept |
1634 | { return __a->exchange(__i, __m); } |
1635 | |
1636 | template<typename _ITp> |
1637 | __libitm_always_inline bool |
1638 | atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, |
1639 | _ITp* __i1, _ITp __i2, |
1640 | memory_order __m1, |
1641 | memory_order __m2) noexcept |
1642 | { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } |
1643 | |
1644 | template<typename _ITp> |
1645 | __libitm_always_inline bool |
1646 | atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, |
1647 | _ITp* __i1, _ITp __i2, |
1648 | memory_order __m1, |
1649 | memory_order __m2) noexcept |
1650 | { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } |
1651 | |
1652 | template<typename _ITp> |
1653 | __libitm_always_inline bool |
1654 | atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, |
1655 | _ITp* __i1, _ITp __i2, |
1656 | memory_order __m1, |
1657 | memory_order __m2) noexcept |
1658 | { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } |
1659 | |
1660 | template<typename _ITp> |
1661 | __libitm_always_inline bool |
1662 | atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, |
1663 | _ITp* __i1, _ITp __i2, |
1664 | memory_order __m1, |
1665 | memory_order __m2) noexcept |
1666 | { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } |
1667 | |
1668 | |
1669 | template<typename _ITp> |
1670 | __libitm_always_inline void |
1671 | atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept |
1672 | { atomic_store_explicit(__a, __i, memory_order_seq_cst); } |
1673 | |
1674 | template<typename _ITp> |
1675 | __libitm_always_inline void |
1676 | atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept |
1677 | { atomic_store_explicit(__a, __i, memory_order_seq_cst); } |
1678 | |
1679 | template<typename _ITp> |
1680 | __libitm_always_inline _ITp |
1681 | atomic_load(const atomic<_ITp>* __a) noexcept |
1682 | { return atomic_load_explicit(__a, memory_order_seq_cst); } |
1683 | |
1684 | template<typename _ITp> |
1685 | __libitm_always_inline _ITp |
1686 | atomic_load(const volatile atomic<_ITp>* __a) noexcept |
1687 | { return atomic_load_explicit(__a, memory_order_seq_cst); } |
1688 | |
1689 | template<typename _ITp> |
1690 | __libitm_always_inline _ITp |
1691 | atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept |
1692 | { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } |
1693 | |
1694 | template<typename _ITp> |
1695 | __libitm_always_inline _ITp |
1696 | atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept |
1697 | { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } |
1698 | |
1699 | template<typename _ITp> |
1700 | __libitm_always_inline bool |
1701 | atomic_compare_exchange_weak(atomic<_ITp>* __a, |
1702 | _ITp* __i1, _ITp __i2) noexcept |
1703 | { |
1704 | return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, |
1705 | memory_order_seq_cst, |
1706 | memory_order_seq_cst); |
1707 | } |
1708 | |
1709 | template<typename _ITp> |
1710 | __libitm_always_inline bool |
1711 | atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, |
1712 | _ITp* __i1, _ITp __i2) noexcept |
1713 | { |
1714 | return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, |
1715 | memory_order_seq_cst, |
1716 | memory_order_seq_cst); |
1717 | } |
1718 | |
1719 | template<typename _ITp> |
1720 | __libitm_always_inline bool |
1721 | atomic_compare_exchange_strong(atomic<_ITp>* __a, |
1722 | _ITp* __i1, _ITp __i2) noexcept |
1723 | { |
1724 | return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, |
1725 | memory_order_seq_cst, |
1726 | memory_order_seq_cst); |
1727 | } |
1728 | |
1729 | template<typename _ITp> |
1730 | __libitm_always_inline bool |
1731 | atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, |
1732 | _ITp* __i1, _ITp __i2) noexcept |
1733 | { |
1734 | return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, |
1735 | memory_order_seq_cst, |
1736 | memory_order_seq_cst); |
1737 | } |
1738 | |
1739 | // Function templates for atomic_integral operations only, using |
1740 | // __atomic_base. Template argument should be constricted to |
1741 | // intergral types as specified in the standard, excluding address |
1742 | // types. |
1743 | template<typename _ITp> |
1744 | __libitm_always_inline _ITp |
1745 | atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, |
1746 | memory_order __m) noexcept |
1747 | { return __a->fetch_add(__i, __m); } |
1748 | |
1749 | template<typename _ITp> |
1750 | __libitm_always_inline _ITp |
1751 | atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, |
1752 | memory_order __m) noexcept |
1753 | { return __a->fetch_add(__i, __m); } |
1754 | |
1755 | template<typename _ITp> |
1756 | __libitm_always_inline _ITp |
1757 | atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, |
1758 | memory_order __m) noexcept |
1759 | { return __a->fetch_sub(__i, __m); } |
1760 | |
1761 | template<typename _ITp> |
1762 | __libitm_always_inline _ITp |
1763 | atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, |
1764 | memory_order __m) noexcept |
1765 | { return __a->fetch_sub(__i, __m); } |
1766 | |
1767 | template<typename _ITp> |
1768 | __libitm_always_inline _ITp |
1769 | atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, |
1770 | memory_order __m) noexcept |
1771 | { return __a->fetch_and(__i, __m); } |
1772 | |
1773 | template<typename _ITp> |
1774 | __libitm_always_inline _ITp |
1775 | atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, |
1776 | memory_order __m) noexcept |
1777 | { return __a->fetch_and(__i, __m); } |
1778 | |
1779 | template<typename _ITp> |
1780 | __libitm_always_inline _ITp |
1781 | atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, |
1782 | memory_order __m) noexcept |
1783 | { return __a->fetch_or(__i, __m); } |
1784 | |
1785 | template<typename _ITp> |
1786 | __libitm_always_inline _ITp |
1787 | atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, |
1788 | memory_order __m) noexcept |
1789 | { return __a->fetch_or(__i, __m); } |
1790 | |
1791 | template<typename _ITp> |
1792 | __libitm_always_inline _ITp |
1793 | atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, |
1794 | memory_order __m) noexcept |
1795 | { return __a->fetch_xor(__i, __m); } |
1796 | |
1797 | template<typename _ITp> |
1798 | __libitm_always_inline _ITp |
1799 | atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, |
1800 | memory_order __m) noexcept |
1801 | { return __a->fetch_xor(__i, __m); } |
1802 | |
1803 | template<typename _ITp> |
1804 | __libitm_always_inline _ITp |
1805 | atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept |
1806 | { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } |
1807 | |
1808 | template<typename _ITp> |
1809 | __libitm_always_inline _ITp |
1810 | atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept |
1811 | { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } |
1812 | |
1813 | template<typename _ITp> |
1814 | __libitm_always_inline _ITp |
1815 | atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept |
1816 | { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } |
1817 | |
1818 | template<typename _ITp> |
1819 | __libitm_always_inline _ITp |
1820 | atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept |
1821 | { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } |
1822 | |
1823 | template<typename _ITp> |
1824 | __libitm_always_inline _ITp |
1825 | atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept |
1826 | { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } |
1827 | |
1828 | template<typename _ITp> |
1829 | __libitm_always_inline _ITp |
1830 | atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept |
1831 | { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } |
1832 | |
1833 | template<typename _ITp> |
1834 | __libitm_always_inline _ITp |
1835 | atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept |
1836 | { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } |
1837 | |
1838 | template<typename _ITp> |
1839 | __libitm_always_inline _ITp |
1840 | atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept |
1841 | { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } |
1842 | |
1843 | template<typename _ITp> |
1844 | __libitm_always_inline _ITp |
1845 | atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept |
1846 | { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } |
1847 | |
1848 | template<typename _ITp> |
1849 | __libitm_always_inline _ITp |
1850 | atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept |
1851 | { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } |
1852 | |
1853 | |
1854 | // Partial specializations for pointers. |
1855 | template<typename _ITp> |
1856 | __libitm_always_inline _ITp* |
1857 | atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, |
1858 | memory_order __m) noexcept |
1859 | { return __a->fetch_add(__d, __m); } |
1860 | |
1861 | template<typename _ITp> |
1862 | __libitm_always_inline _ITp* |
1863 | atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, |
1864 | memory_order __m) noexcept |
1865 | { return __a->fetch_add(__d, __m); } |
1866 | |
1867 | template<typename _ITp> |
1868 | __libitm_always_inline _ITp* |
1869 | atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept |
1870 | { return __a->fetch_add(__d); } |
1871 | |
1872 | template<typename _ITp> |
1873 | __libitm_always_inline _ITp* |
1874 | atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept |
1875 | { return __a->fetch_add(__d); } |
1876 | |
1877 | template<typename _ITp> |
1878 | __libitm_always_inline _ITp* |
1879 | atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, |
1880 | ptrdiff_t __d, memory_order __m) noexcept |
1881 | { return __a->fetch_sub(__d, __m); } |
1882 | |
1883 | template<typename _ITp> |
1884 | __libitm_always_inline _ITp* |
1885 | atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, |
1886 | memory_order __m) noexcept |
1887 | { return __a->fetch_sub(__d, __m); } |
1888 | |
1889 | template<typename _ITp> |
1890 | __libitm_always_inline _ITp* |
1891 | atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept |
1892 | { return __a->fetch_sub(__d); } |
1893 | |
1894 | template<typename _ITp> |
1895 | __libitm_always_inline _ITp* |
1896 | atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept |
1897 | { return __a->fetch_sub(__d); } |
1898 | // @} group atomics |
1899 | |
1900 | // _GLIBCXX_END_NAMESPACE_VERSION |
1901 | } // namespace |
1902 | |
1903 | #endif |
1904 | |