Line data Source code
1 : // -*- C++ -*- header.
2 :
3 : // Copyright (C) 2008-2016 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 : /** @file include/atomic
26 : * This is a Standard C++ Library header.
27 : */
28 :
29 : // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
30 : // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
31 :
32 : #ifndef _GLIBCXX_ATOMIC
33 : #define _GLIBCXX_ATOMIC 1
34 :
35 : #pragma GCC system_header
36 :
37 : #if __cplusplus < 201103L
38 : # include <bits/c++0x_warning.h>
39 : #else
40 :
41 : #include <bits/atomic_base.h>
42 :
43 : namespace std _GLIBCXX_VISIBILITY(default)
44 : {
45 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 :
47 : /**
48 : * @addtogroup atomics
49 : * @{
50 : */
51 :
52 : template<typename _Tp>
53 : struct atomic;
54 :
55 : /// atomic<bool>
56 : // NB: No operators or fetch-operations for this type.
57 : template<>
58 : struct atomic<bool>
59 : {
60 : private:
61 : __atomic_base<bool> _M_base;
62 :
63 : public:
64 : atomic() noexcept = default;
65 : ~atomic() noexcept = default;
66 : atomic(const atomic&) = delete;
67 : atomic& operator=(const atomic&) = delete;
68 : atomic& operator=(const atomic&) volatile = delete;
69 :
70 : constexpr atomic(bool __i) noexcept : _M_base(__i) { }
71 :
72 : bool
73 : operator=(bool __i) noexcept
74 : { return _M_base.operator=(__i); }
75 :
76 : bool
77 : operator=(bool __i) volatile noexcept
78 : { return _M_base.operator=(__i); }
79 :
80 : operator bool() const noexcept
81 : { return _M_base.load(); }
82 :
83 : operator bool() const volatile noexcept
84 : { return _M_base.load(); }
85 :
86 : bool
87 : is_lock_free() const noexcept { return _M_base.is_lock_free(); }
88 :
89 : bool
90 : is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
91 :
92 : void
93 : store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
94 : { _M_base.store(__i, __m); }
95 :
96 : void
97 : store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
98 : { _M_base.store(__i, __m); }
99 :
100 : bool
101 21 : load(memory_order __m = memory_order_seq_cst) const noexcept
102 42 : { return _M_base.load(__m); }
103 :
104 : bool
105 : load(memory_order __m = memory_order_seq_cst) const volatile noexcept
106 : { return _M_base.load(__m); }
107 :
108 : bool
109 : exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
110 : { return _M_base.exchange(__i, __m); }
111 :
112 : bool
113 : exchange(bool __i,
114 : memory_order __m = memory_order_seq_cst) volatile noexcept
115 : { return _M_base.exchange(__i, __m); }
116 :
117 : bool
118 : compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
119 : memory_order __m2) noexcept
120 : { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
121 :
122 : bool
123 : compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
124 : memory_order __m2) volatile noexcept
125 : { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
126 :
127 : bool
128 : compare_exchange_weak(bool& __i1, bool __i2,
129 : memory_order __m = memory_order_seq_cst) noexcept
130 : { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
131 :
132 : bool
133 : compare_exchange_weak(bool& __i1, bool __i2,
134 : memory_order __m = memory_order_seq_cst) volatile noexcept
135 : { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
136 :
137 : bool
138 : compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
139 : memory_order __m2) noexcept
140 : { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
141 :
142 : bool
143 : compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
144 : memory_order __m2) volatile noexcept
145 : { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
146 :
147 : bool
148 : compare_exchange_strong(bool& __i1, bool __i2,
149 : memory_order __m = memory_order_seq_cst) noexcept
150 : { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
151 :
152 : bool
153 : compare_exchange_strong(bool& __i1, bool __i2,
154 : memory_order __m = memory_order_seq_cst) volatile noexcept
155 : { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
156 : };
157 :
158 :
159 : /**
160 : * @brief Generic atomic type, primary class template.
161 : *
162 : * @tparam _Tp Type to be made atomic, must be trivally copyable.
163 : */
164 : template<typename _Tp>
165 : struct atomic
166 : {
167 : private:
168 : // Align 1/2/4/8/16-byte types to at least their size.
169 : static constexpr int _S_min_alignment
170 : = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
171 : ? 0 : sizeof(_Tp);
172 :
173 : static constexpr int _S_alignment
174 : = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
175 :
176 : alignas(_S_alignment) _Tp _M_i;
177 :
178 : static_assert(__is_trivially_copyable(_Tp),
179 : "std::atomic requires a trivially copyable type");
180 :
181 : static_assert(sizeof(_Tp) > 0,
182 : "Incomplete or zero-sized types are not supported");
183 :
184 : public:
185 : atomic() noexcept = default;
186 : ~atomic() noexcept = default;
187 : atomic(const atomic&) = delete;
188 : atomic& operator=(const atomic&) = delete;
189 : atomic& operator=(const atomic&) volatile = delete;
190 :
191 : constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
192 :
193 : operator _Tp() const noexcept
194 : { return load(); }
195 :
196 : operator _Tp() const volatile noexcept
197 : { return load(); }
198 :
199 : _Tp
200 : operator=(_Tp __i) noexcept
201 : { store(__i); return __i; }
202 :
203 : _Tp
204 : operator=(_Tp __i) volatile noexcept
205 : { store(__i); return __i; }
206 :
207 : bool
208 : is_lock_free() const noexcept
209 : {
210 : // Produce a fake, minimally aligned pointer.
211 : return __atomic_is_lock_free(sizeof(_M_i),
212 : reinterpret_cast<void *>(-__alignof(_M_i)));
213 : }
214 :
215 : bool
216 : is_lock_free() const volatile noexcept
217 : {
218 : // Produce a fake, minimally aligned pointer.
219 : return __atomic_is_lock_free(sizeof(_M_i),
220 : reinterpret_cast<void *>(-__alignof(_M_i)));
221 : }
222 :
223 : void
224 : store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
225 : { __atomic_store(&_M_i, &__i, __m); }
226 :
227 : void
228 : store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
229 : { __atomic_store(&_M_i, &__i, __m); }
230 :
231 : _Tp
232 : load(memory_order __m = memory_order_seq_cst) const noexcept
233 : {
234 : _Tp tmp;
235 : __atomic_load(&_M_i, &tmp, __m);
236 : return tmp;
237 : }
238 :
239 : _Tp
240 : load(memory_order __m = memory_order_seq_cst) const volatile noexcept
241 : {
242 : _Tp tmp;
243 : __atomic_load(&_M_i, &tmp, __m);
244 : return tmp;
245 : }
246 :
247 : _Tp
248 : exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
249 : {
250 : _Tp tmp;
251 : __atomic_exchange(&_M_i, &__i, &tmp, __m);
252 : return tmp;
253 : }
254 :
255 : _Tp
256 : exchange(_Tp __i,
257 : memory_order __m = memory_order_seq_cst) volatile noexcept
258 : {
259 : _Tp tmp;
260 : __atomic_exchange(&_M_i, &__i, &tmp, __m);
261 : return tmp;
262 : }
263 :
264 : bool
265 : compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
266 : memory_order __f) noexcept
267 : {
268 : return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
269 : }
270 :
271 : bool
272 : compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
273 : memory_order __f) volatile noexcept
274 : {
275 : return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
276 : }
277 :
278 : bool
279 : compare_exchange_weak(_Tp& __e, _Tp __i,
280 : memory_order __m = memory_order_seq_cst) noexcept
281 : { return compare_exchange_weak(__e, __i, __m,
282 : __cmpexch_failure_order(__m)); }
283 :
284 : bool
285 : compare_exchange_weak(_Tp& __e, _Tp __i,
286 : memory_order __m = memory_order_seq_cst) volatile noexcept
287 : { return compare_exchange_weak(__e, __i, __m,
288 : __cmpexch_failure_order(__m)); }
289 :
290 : bool
291 : compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
292 : memory_order __f) noexcept
293 : {
294 : return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
295 : }
296 :
297 : bool
298 : compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
299 : memory_order __f) volatile noexcept
300 : {
301 : return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
302 : }
303 :
304 : bool
305 : compare_exchange_strong(_Tp& __e, _Tp __i,
306 : memory_order __m = memory_order_seq_cst) noexcept
307 : { return compare_exchange_strong(__e, __i, __m,
308 : __cmpexch_failure_order(__m)); }
309 :
310 : bool
311 : compare_exchange_strong(_Tp& __e, _Tp __i,
312 : memory_order __m = memory_order_seq_cst) volatile noexcept
313 : { return compare_exchange_strong(__e, __i, __m,
314 : __cmpexch_failure_order(__m)); }
315 : };
316 :
317 :
318 : /// Partial specialization for pointer types.
319 : template<typename _Tp>
320 : struct atomic<_Tp*>
321 : {
322 : typedef _Tp* __pointer_type;
323 : typedef __atomic_base<_Tp*> __base_type;
324 : __base_type _M_b;
325 :
326 : atomic() noexcept = default;
327 : ~atomic() noexcept = default;
328 : atomic(const atomic&) = delete;
329 : atomic& operator=(const atomic&) = delete;
330 : atomic& operator=(const atomic&) volatile = delete;
331 :
332 : constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
333 :
334 : operator __pointer_type() const noexcept
335 : { return __pointer_type(_M_b); }
336 :
337 : operator __pointer_type() const volatile noexcept
338 : { return __pointer_type(_M_b); }
339 :
340 : __pointer_type
341 : operator=(__pointer_type __p) noexcept
342 : { return _M_b.operator=(__p); }
343 :
344 : __pointer_type
345 : operator=(__pointer_type __p) volatile noexcept
346 : { return _M_b.operator=(__p); }
347 :
348 : __pointer_type
349 : operator++(int) noexcept
350 : { return _M_b++; }
351 :
352 : __pointer_type
353 : operator++(int) volatile noexcept
354 : { return _M_b++; }
355 :
356 : __pointer_type
357 : operator--(int) noexcept
358 : { return _M_b--; }
359 :
360 : __pointer_type
361 : operator--(int) volatile noexcept
362 : { return _M_b--; }
363 :
364 : __pointer_type
365 : operator++() noexcept
366 : { return ++_M_b; }
367 :
368 : __pointer_type
369 : operator++() volatile noexcept
370 : { return ++_M_b; }
371 :
372 : __pointer_type
373 : operator--() noexcept
374 : { return --_M_b; }
375 :
376 : __pointer_type
377 : operator--() volatile noexcept
378 : { return --_M_b; }
379 :
380 : __pointer_type
381 : operator+=(ptrdiff_t __d) noexcept
382 : { return _M_b.operator+=(__d); }
383 :
384 : __pointer_type
385 : operator+=(ptrdiff_t __d) volatile noexcept
386 : { return _M_b.operator+=(__d); }
387 :
388 : __pointer_type
389 : operator-=(ptrdiff_t __d) noexcept
390 : { return _M_b.operator-=(__d); }
391 :
392 : __pointer_type
393 : operator-=(ptrdiff_t __d) volatile noexcept
394 : { return _M_b.operator-=(__d); }
395 :
396 : bool
397 : is_lock_free() const noexcept
398 : { return _M_b.is_lock_free(); }
399 :
400 : bool
401 : is_lock_free() const volatile noexcept
402 : { return _M_b.is_lock_free(); }
403 :
404 : void
405 : store(__pointer_type __p,
406 : memory_order __m = memory_order_seq_cst) noexcept
407 : { return _M_b.store(__p, __m); }
408 :
409 : void
410 : store(__pointer_type __p,
411 : memory_order __m = memory_order_seq_cst) volatile noexcept
412 : { return _M_b.store(__p, __m); }
413 :
414 : __pointer_type
415 : load(memory_order __m = memory_order_seq_cst) const noexcept
416 : { return _M_b.load(__m); }
417 :
418 : __pointer_type
419 : load(memory_order __m = memory_order_seq_cst) const volatile noexcept
420 : { return _M_b.load(__m); }
421 :
422 : __pointer_type
423 : exchange(__pointer_type __p,
424 : memory_order __m = memory_order_seq_cst) noexcept
425 : { return _M_b.exchange(__p, __m); }
426 :
427 : __pointer_type
428 : exchange(__pointer_type __p,
429 : memory_order __m = memory_order_seq_cst) volatile noexcept
430 : { return _M_b.exchange(__p, __m); }
431 :
432 : bool
433 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
434 : memory_order __m1, memory_order __m2) noexcept
435 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
436 :
437 : bool
438 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
439 : memory_order __m1,
440 : memory_order __m2) volatile noexcept
441 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
442 :
443 : bool
444 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
445 : memory_order __m = memory_order_seq_cst) noexcept
446 : {
447 : return compare_exchange_weak(__p1, __p2, __m,
448 : __cmpexch_failure_order(__m));
449 : }
450 :
451 : bool
452 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
453 : memory_order __m = memory_order_seq_cst) volatile noexcept
454 : {
455 : return compare_exchange_weak(__p1, __p2, __m,
456 : __cmpexch_failure_order(__m));
457 : }
458 :
459 : bool
460 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
461 : memory_order __m1, memory_order __m2) noexcept
462 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
463 :
464 : bool
465 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
466 : memory_order __m1,
467 : memory_order __m2) volatile noexcept
468 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
469 :
470 : bool
471 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
472 : memory_order __m = memory_order_seq_cst) noexcept
473 : {
474 : return _M_b.compare_exchange_strong(__p1, __p2, __m,
475 : __cmpexch_failure_order(__m));
476 : }
477 :
478 : bool
479 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
480 : memory_order __m = memory_order_seq_cst) volatile noexcept
481 : {
482 : return _M_b.compare_exchange_strong(__p1, __p2, __m,
483 : __cmpexch_failure_order(__m));
484 : }
485 :
486 : __pointer_type
487 : fetch_add(ptrdiff_t __d,
488 : memory_order __m = memory_order_seq_cst) noexcept
489 : { return _M_b.fetch_add(__d, __m); }
490 :
491 : __pointer_type
492 : fetch_add(ptrdiff_t __d,
493 : memory_order __m = memory_order_seq_cst) volatile noexcept
494 : { return _M_b.fetch_add(__d, __m); }
495 :
496 : __pointer_type
497 : fetch_sub(ptrdiff_t __d,
498 : memory_order __m = memory_order_seq_cst) noexcept
499 : { return _M_b.fetch_sub(__d, __m); }
500 :
501 : __pointer_type
502 : fetch_sub(ptrdiff_t __d,
503 : memory_order __m = memory_order_seq_cst) volatile noexcept
504 : { return _M_b.fetch_sub(__d, __m); }
505 : };
506 :
507 :
508 : /// Explicit specialization for char.
509 : template<>
510 : struct atomic<char> : __atomic_base<char>
511 : {
512 : typedef char __integral_type;
513 : typedef __atomic_base<char> __base_type;
514 :
515 : atomic() noexcept = default;
516 : ~atomic() noexcept = default;
517 : atomic(const atomic&) = delete;
518 : atomic& operator=(const atomic&) = delete;
519 : atomic& operator=(const atomic&) volatile = delete;
520 :
521 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
522 :
523 : using __base_type::operator __integral_type;
524 : using __base_type::operator=;
525 : };
526 :
527 : /// Explicit specialization for signed char.
528 : template<>
529 : struct atomic<signed char> : __atomic_base<signed char>
530 : {
531 : typedef signed char __integral_type;
532 : typedef __atomic_base<signed char> __base_type;
533 :
534 : atomic() noexcept= default;
535 : ~atomic() noexcept = default;
536 : atomic(const atomic&) = delete;
537 : atomic& operator=(const atomic&) = delete;
538 : atomic& operator=(const atomic&) volatile = delete;
539 :
540 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
541 :
542 : using __base_type::operator __integral_type;
543 : using __base_type::operator=;
544 : };
545 :
546 : /// Explicit specialization for unsigned char.
547 : template<>
548 : struct atomic<unsigned char> : __atomic_base<unsigned char>
549 : {
550 : typedef unsigned char __integral_type;
551 : typedef __atomic_base<unsigned char> __base_type;
552 :
553 : atomic() noexcept= default;
554 : ~atomic() noexcept = default;
555 : atomic(const atomic&) = delete;
556 : atomic& operator=(const atomic&) = delete;
557 : atomic& operator=(const atomic&) volatile = delete;
558 :
559 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
560 :
561 : using __base_type::operator __integral_type;
562 : using __base_type::operator=;
563 : };
564 :
565 : /// Explicit specialization for short.
566 : template<>
567 : struct atomic<short> : __atomic_base<short>
568 : {
569 : typedef short __integral_type;
570 : typedef __atomic_base<short> __base_type;
571 :
572 : atomic() noexcept = default;
573 : ~atomic() noexcept = default;
574 : atomic(const atomic&) = delete;
575 : atomic& operator=(const atomic&) = delete;
576 : atomic& operator=(const atomic&) volatile = delete;
577 :
578 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
579 :
580 : using __base_type::operator __integral_type;
581 : using __base_type::operator=;
582 : };
583 :
584 : /// Explicit specialization for unsigned short.
585 : template<>
586 : struct atomic<unsigned short> : __atomic_base<unsigned short>
587 : {
588 : typedef unsigned short __integral_type;
589 : typedef __atomic_base<unsigned short> __base_type;
590 :
591 : atomic() noexcept = default;
592 : ~atomic() noexcept = default;
593 : atomic(const atomic&) = delete;
594 : atomic& operator=(const atomic&) = delete;
595 : atomic& operator=(const atomic&) volatile = delete;
596 :
597 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
598 :
599 : using __base_type::operator __integral_type;
600 : using __base_type::operator=;
601 : };
602 :
603 : /// Explicit specialization for int.
604 : template<>
605 : struct atomic<int> : __atomic_base<int>
606 : {
607 : typedef int __integral_type;
608 : typedef __atomic_base<int> __base_type;
609 :
610 : atomic() noexcept = default;
611 : ~atomic() noexcept = default;
612 : atomic(const atomic&) = delete;
613 : atomic& operator=(const atomic&) = delete;
614 : atomic& operator=(const atomic&) volatile = delete;
615 :
616 80 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
617 :
618 : using __base_type::operator __integral_type;
619 : using __base_type::operator=;
620 : };
621 :
622 : /// Explicit specialization for unsigned int.
623 : template<>
624 : struct atomic<unsigned int> : __atomic_base<unsigned int>
625 : {
626 : typedef unsigned int __integral_type;
627 : typedef __atomic_base<unsigned int> __base_type;
628 :
629 : atomic() noexcept = default;
630 : ~atomic() noexcept = default;
631 : atomic(const atomic&) = delete;
632 : atomic& operator=(const atomic&) = delete;
633 : atomic& operator=(const atomic&) volatile = delete;
634 :
635 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
636 :
637 : using __base_type::operator __integral_type;
638 : using __base_type::operator=;
639 : };
640 :
641 : /// Explicit specialization for long.
642 : template<>
643 : struct atomic<long> : __atomic_base<long>
644 : {
645 : typedef long __integral_type;
646 : typedef __atomic_base<long> __base_type;
647 :
648 : atomic() noexcept = default;
649 : ~atomic() noexcept = default;
650 : atomic(const atomic&) = delete;
651 : atomic& operator=(const atomic&) = delete;
652 : atomic& operator=(const atomic&) volatile = delete;
653 :
654 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
655 :
656 : using __base_type::operator __integral_type;
657 : using __base_type::operator=;
658 : };
659 :
660 : /// Explicit specialization for unsigned long.
661 : template<>
662 : struct atomic<unsigned long> : __atomic_base<unsigned long>
663 : {
664 : typedef unsigned long __integral_type;
665 : typedef __atomic_base<unsigned long> __base_type;
666 :
667 : atomic() noexcept = default;
668 : ~atomic() noexcept = default;
669 : atomic(const atomic&) = delete;
670 : atomic& operator=(const atomic&) = delete;
671 : atomic& operator=(const atomic&) volatile = delete;
672 :
673 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
674 :
675 : using __base_type::operator __integral_type;
676 : using __base_type::operator=;
677 : };
678 :
679 : /// Explicit specialization for long long.
680 : template<>
681 : struct atomic<long long> : __atomic_base<long long>
682 : {
683 : typedef long long __integral_type;
684 : typedef __atomic_base<long long> __base_type;
685 :
686 : atomic() noexcept = default;
687 : ~atomic() noexcept = default;
688 : atomic(const atomic&) = delete;
689 : atomic& operator=(const atomic&) = delete;
690 : atomic& operator=(const atomic&) volatile = delete;
691 :
692 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
693 :
694 : using __base_type::operator __integral_type;
695 : using __base_type::operator=;
696 : };
697 :
698 : /// Explicit specialization for unsigned long long.
699 : template<>
700 : struct atomic<unsigned long long> : __atomic_base<unsigned long long>
701 : {
702 : typedef unsigned long long __integral_type;
703 : typedef __atomic_base<unsigned long long> __base_type;
704 :
705 : atomic() noexcept = default;
706 : ~atomic() noexcept = default;
707 : atomic(const atomic&) = delete;
708 : atomic& operator=(const atomic&) = delete;
709 : atomic& operator=(const atomic&) volatile = delete;
710 :
711 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
712 :
713 : using __base_type::operator __integral_type;
714 : using __base_type::operator=;
715 : };
716 :
717 : /// Explicit specialization for wchar_t.
718 : template<>
719 : struct atomic<wchar_t> : __atomic_base<wchar_t>
720 : {
721 : typedef wchar_t __integral_type;
722 : typedef __atomic_base<wchar_t> __base_type;
723 :
724 : atomic() noexcept = default;
725 : ~atomic() noexcept = default;
726 : atomic(const atomic&) = delete;
727 : atomic& operator=(const atomic&) = delete;
728 : atomic& operator=(const atomic&) volatile = delete;
729 :
730 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
731 :
732 : using __base_type::operator __integral_type;
733 : using __base_type::operator=;
734 : };
735 :
736 : /// Explicit specialization for char16_t.
737 : template<>
738 : struct atomic<char16_t> : __atomic_base<char16_t>
739 : {
740 : typedef char16_t __integral_type;
741 : typedef __atomic_base<char16_t> __base_type;
742 :
743 : atomic() noexcept = default;
744 : ~atomic() noexcept = default;
745 : atomic(const atomic&) = delete;
746 : atomic& operator=(const atomic&) = delete;
747 : atomic& operator=(const atomic&) volatile = delete;
748 :
749 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
750 :
751 : using __base_type::operator __integral_type;
752 : using __base_type::operator=;
753 : };
754 :
755 : /// Explicit specialization for char32_t.
756 : template<>
757 : struct atomic<char32_t> : __atomic_base<char32_t>
758 : {
759 : typedef char32_t __integral_type;
760 : typedef __atomic_base<char32_t> __base_type;
761 :
762 : atomic() noexcept = default;
763 : ~atomic() noexcept = default;
764 : atomic(const atomic&) = delete;
765 : atomic& operator=(const atomic&) = delete;
766 : atomic& operator=(const atomic&) volatile = delete;
767 :
768 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
769 :
770 : using __base_type::operator __integral_type;
771 : using __base_type::operator=;
772 : };
773 :
774 :
775 : /// atomic_bool
776 : typedef atomic<bool> atomic_bool;
777 :
778 : /// atomic_char
779 : typedef atomic<char> atomic_char;
780 :
781 : /// atomic_schar
782 : typedef atomic<signed char> atomic_schar;
783 :
784 : /// atomic_uchar
785 : typedef atomic<unsigned char> atomic_uchar;
786 :
787 : /// atomic_short
788 : typedef atomic<short> atomic_short;
789 :
790 : /// atomic_ushort
791 : typedef atomic<unsigned short> atomic_ushort;
792 :
793 : /// atomic_int
794 : typedef atomic<int> atomic_int;
795 :
796 : /// atomic_uint
797 : typedef atomic<unsigned int> atomic_uint;
798 :
799 : /// atomic_long
800 : typedef atomic<long> atomic_long;
801 :
802 : /// atomic_ulong
803 : typedef atomic<unsigned long> atomic_ulong;
804 :
805 : /// atomic_llong
806 : typedef atomic<long long> atomic_llong;
807 :
808 : /// atomic_ullong
809 : typedef atomic<unsigned long long> atomic_ullong;
810 :
811 : /// atomic_wchar_t
812 : typedef atomic<wchar_t> atomic_wchar_t;
813 :
814 : /// atomic_char16_t
815 : typedef atomic<char16_t> atomic_char16_t;
816 :
817 : /// atomic_char32_t
818 : typedef atomic<char32_t> atomic_char32_t;
819 :
820 :
821 : /// atomic_int_least8_t
822 : typedef atomic<int_least8_t> atomic_int_least8_t;
823 :
824 : /// atomic_uint_least8_t
825 : typedef atomic<uint_least8_t> atomic_uint_least8_t;
826 :
827 : /// atomic_int_least16_t
828 : typedef atomic<int_least16_t> atomic_int_least16_t;
829 :
830 : /// atomic_uint_least16_t
831 : typedef atomic<uint_least16_t> atomic_uint_least16_t;
832 :
833 : /// atomic_int_least32_t
834 : typedef atomic<int_least32_t> atomic_int_least32_t;
835 :
836 : /// atomic_uint_least32_t
837 : typedef atomic<uint_least32_t> atomic_uint_least32_t;
838 :
839 : /// atomic_int_least64_t
840 : typedef atomic<int_least64_t> atomic_int_least64_t;
841 :
842 : /// atomic_uint_least64_t
843 : typedef atomic<uint_least64_t> atomic_uint_least64_t;
844 :
845 :
846 : /// atomic_int_fast8_t
847 : typedef atomic<int_fast8_t> atomic_int_fast8_t;
848 :
849 : /// atomic_uint_fast8_t
850 : typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
851 :
852 : /// atomic_int_fast16_t
853 : typedef atomic<int_fast16_t> atomic_int_fast16_t;
854 :
855 : /// atomic_uint_fast16_t
856 : typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
857 :
858 : /// atomic_int_fast32_t
859 : typedef atomic<int_fast32_t> atomic_int_fast32_t;
860 :
861 : /// atomic_uint_fast32_t
862 : typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
863 :
864 : /// atomic_int_fast64_t
865 : typedef atomic<int_fast64_t> atomic_int_fast64_t;
866 :
867 : /// atomic_uint_fast64_t
868 : typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
869 :
870 :
871 : /// atomic_intptr_t
872 : typedef atomic<intptr_t> atomic_intptr_t;
873 :
874 : /// atomic_uintptr_t
875 : typedef atomic<uintptr_t> atomic_uintptr_t;
876 :
877 : /// atomic_size_t
878 : typedef atomic<size_t> atomic_size_t;
879 :
880 : /// atomic_intmax_t
881 : typedef atomic<intmax_t> atomic_intmax_t;
882 :
883 : /// atomic_uintmax_t
884 : typedef atomic<uintmax_t> atomic_uintmax_t;
885 :
886 : /// atomic_ptrdiff_t
887 : typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
888 :
889 :
890 : // Function definitions, atomic_flag operations.
891 : inline bool
892 : atomic_flag_test_and_set_explicit(atomic_flag* __a,
893 : memory_order __m) noexcept
894 : { return __a->test_and_set(__m); }
895 :
896 : inline bool
897 : atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
898 : memory_order __m) noexcept
899 : { return __a->test_and_set(__m); }
900 :
901 : inline void
902 : atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
903 : { __a->clear(__m); }
904 :
905 : inline void
906 : atomic_flag_clear_explicit(volatile atomic_flag* __a,
907 : memory_order __m) noexcept
908 : { __a->clear(__m); }
909 :
910 : inline bool
911 : atomic_flag_test_and_set(atomic_flag* __a) noexcept
912 : { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
913 :
914 : inline bool
915 : atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
916 : { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
917 :
918 : inline void
919 : atomic_flag_clear(atomic_flag* __a) noexcept
920 : { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
921 :
922 : inline void
923 : atomic_flag_clear(volatile atomic_flag* __a) noexcept
924 : { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
925 :
926 :
927 : // Function templates generally applicable to atomic types.
928 : template<typename _ITp>
929 : inline bool
930 : atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
931 : { return __a->is_lock_free(); }
932 :
933 : template<typename _ITp>
934 : inline bool
935 : atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
936 : { return __a->is_lock_free(); }
937 :
938 : template<typename _ITp>
939 : inline void
940 : atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
941 : { __a->store(__i, memory_order_relaxed); }
942 :
943 : template<typename _ITp>
944 : inline void
945 : atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
946 : { __a->store(__i, memory_order_relaxed); }
947 :
948 : template<typename _ITp>
949 : inline void
950 : atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
951 : memory_order __m) noexcept
952 : { __a->store(__i, __m); }
953 :
954 : template<typename _ITp>
955 : inline void
956 : atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
957 : memory_order __m) noexcept
958 : { __a->store(__i, __m); }
959 :
960 : template<typename _ITp>
961 : inline _ITp
962 : atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
963 : { return __a->load(__m); }
964 :
965 : template<typename _ITp>
966 : inline _ITp
967 : atomic_load_explicit(const volatile atomic<_ITp>* __a,
968 : memory_order __m) noexcept
969 : { return __a->load(__m); }
970 :
971 : template<typename _ITp>
972 : inline _ITp
973 : atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
974 : memory_order __m) noexcept
975 : { return __a->exchange(__i, __m); }
976 :
977 : template<typename _ITp>
978 : inline _ITp
979 : atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
980 : memory_order __m) noexcept
981 : { return __a->exchange(__i, __m); }
982 :
983 : template<typename _ITp>
984 : inline bool
985 : atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
986 : _ITp* __i1, _ITp __i2,
987 : memory_order __m1,
988 : memory_order __m2) noexcept
989 : { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
990 :
991 : template<typename _ITp>
992 : inline bool
993 : atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
994 : _ITp* __i1, _ITp __i2,
995 : memory_order __m1,
996 : memory_order __m2) noexcept
997 : { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
998 :
999 : template<typename _ITp>
1000 : inline bool
1001 : atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1002 : _ITp* __i1, _ITp __i2,
1003 : memory_order __m1,
1004 : memory_order __m2) noexcept
1005 : { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1006 :
1007 : template<typename _ITp>
1008 : inline bool
1009 : atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1010 : _ITp* __i1, _ITp __i2,
1011 : memory_order __m1,
1012 : memory_order __m2) noexcept
1013 : { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1014 :
1015 :
1016 : template<typename _ITp>
1017 : inline void
1018 : atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
1019 : { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1020 :
1021 : template<typename _ITp>
1022 : inline void
1023 : atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1024 : { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1025 :
1026 : template<typename _ITp>
1027 : inline _ITp
1028 : atomic_load(const atomic<_ITp>* __a) noexcept
1029 : { return atomic_load_explicit(__a, memory_order_seq_cst); }
1030 :
1031 : template<typename _ITp>
1032 : inline _ITp
1033 : atomic_load(const volatile atomic<_ITp>* __a) noexcept
1034 : { return atomic_load_explicit(__a, memory_order_seq_cst); }
1035 :
1036 : template<typename _ITp>
1037 : inline _ITp
1038 : atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
1039 : { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1040 :
1041 : template<typename _ITp>
1042 : inline _ITp
1043 : atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1044 : { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1045 :
1046 : template<typename _ITp>
1047 : inline bool
1048 : atomic_compare_exchange_weak(atomic<_ITp>* __a,
1049 : _ITp* __i1, _ITp __i2) noexcept
1050 : {
1051 : return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1052 : memory_order_seq_cst,
1053 : memory_order_seq_cst);
1054 : }
1055 :
1056 : template<typename _ITp>
1057 : inline bool
1058 : atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1059 : _ITp* __i1, _ITp __i2) noexcept
1060 : {
1061 : return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1062 : memory_order_seq_cst,
1063 : memory_order_seq_cst);
1064 : }
1065 :
1066 : template<typename _ITp>
1067 : inline bool
1068 : atomic_compare_exchange_strong(atomic<_ITp>* __a,
1069 : _ITp* __i1, _ITp __i2) noexcept
1070 : {
1071 : return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1072 : memory_order_seq_cst,
1073 : memory_order_seq_cst);
1074 : }
1075 :
1076 : template<typename _ITp>
1077 : inline bool
1078 : atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1079 : _ITp* __i1, _ITp __i2) noexcept
1080 : {
1081 : return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1082 : memory_order_seq_cst,
1083 : memory_order_seq_cst);
1084 : }
1085 :
1086 : // Function templates for atomic_integral operations only, using
1087 : // __atomic_base. Template argument should be constricted to
1088 : // intergral types as specified in the standard, excluding address
1089 : // types.
1090 : template<typename _ITp>
1091 : inline _ITp
1092 : atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1093 : memory_order __m) noexcept
1094 : { return __a->fetch_add(__i, __m); }
1095 :
1096 : template<typename _ITp>
1097 : inline _ITp
1098 : atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1099 : memory_order __m) noexcept
1100 : { return __a->fetch_add(__i, __m); }
1101 :
1102 : template<typename _ITp>
1103 : inline _ITp
1104 : atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1105 : memory_order __m) noexcept
1106 : { return __a->fetch_sub(__i, __m); }
1107 :
1108 : template<typename _ITp>
1109 : inline _ITp
1110 : atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1111 : memory_order __m) noexcept
1112 : { return __a->fetch_sub(__i, __m); }
1113 :
1114 : template<typename _ITp>
1115 : inline _ITp
1116 : atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1117 : memory_order __m) noexcept
1118 : { return __a->fetch_and(__i, __m); }
1119 :
1120 : template<typename _ITp>
1121 : inline _ITp
1122 : atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1123 : memory_order __m) noexcept
1124 : { return __a->fetch_and(__i, __m); }
1125 :
1126 : template<typename _ITp>
1127 : inline _ITp
1128 : atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1129 : memory_order __m) noexcept
1130 : { return __a->fetch_or(__i, __m); }
1131 :
1132 : template<typename _ITp>
1133 : inline _ITp
1134 : atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1135 : memory_order __m) noexcept
1136 : { return __a->fetch_or(__i, __m); }
1137 :
1138 : template<typename _ITp>
1139 : inline _ITp
1140 : atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1141 : memory_order __m) noexcept
1142 : { return __a->fetch_xor(__i, __m); }
1143 :
1144 : template<typename _ITp>
1145 : inline _ITp
1146 : atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1147 : memory_order __m) noexcept
1148 : { return __a->fetch_xor(__i, __m); }
1149 :
1150 : template<typename _ITp>
1151 : inline _ITp
1152 : atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1153 : { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1154 :
1155 : template<typename _ITp>
1156 : inline _ITp
1157 : atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1158 : { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1159 :
1160 : template<typename _ITp>
1161 : inline _ITp
1162 : atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1163 : { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1164 :
1165 : template<typename _ITp>
1166 : inline _ITp
1167 : atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1168 : { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1169 :
1170 : template<typename _ITp>
1171 : inline _ITp
1172 : atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1173 : { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1174 :
1175 : template<typename _ITp>
1176 : inline _ITp
1177 : atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1178 : { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1179 :
1180 : template<typename _ITp>
1181 : inline _ITp
1182 : atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1183 : { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1184 :
1185 : template<typename _ITp>
1186 : inline _ITp
1187 : atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1188 : { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1189 :
1190 : template<typename _ITp>
1191 : inline _ITp
1192 : atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1193 : { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1194 :
1195 : template<typename _ITp>
1196 : inline _ITp
1197 : atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1198 : { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1199 :
1200 :
1201 : // Partial specializations for pointers.
1202 : template<typename _ITp>
1203 : inline _ITp*
1204 : atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1205 : memory_order __m) noexcept
1206 : { return __a->fetch_add(__d, __m); }
1207 :
1208 : template<typename _ITp>
1209 : inline _ITp*
1210 : atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1211 : memory_order __m) noexcept
1212 : { return __a->fetch_add(__d, __m); }
1213 :
1214 : template<typename _ITp>
1215 : inline _ITp*
1216 : atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1217 : { return __a->fetch_add(__d); }
1218 :
1219 : template<typename _ITp>
1220 : inline _ITp*
1221 : atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1222 : { return __a->fetch_add(__d); }
1223 :
1224 : template<typename _ITp>
1225 : inline _ITp*
1226 : atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1227 : ptrdiff_t __d, memory_order __m) noexcept
1228 : { return __a->fetch_sub(__d, __m); }
1229 :
1230 : template<typename _ITp>
1231 : inline _ITp*
1232 : atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1233 : memory_order __m) noexcept
1234 : { return __a->fetch_sub(__d, __m); }
1235 :
1236 : template<typename _ITp>
1237 : inline _ITp*
1238 : atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1239 : { return __a->fetch_sub(__d); }
1240 :
1241 : template<typename _ITp>
1242 : inline _ITp*
1243 : atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1244 : { return __a->fetch_sub(__d); }
1245 : // @} group atomics
1246 :
1247 : _GLIBCXX_END_NAMESPACE_VERSION
1248 : } // namespace
1249 :
1250 : #endif // C++11
1251 :
1252 : #endif // _GLIBCXX_ATOMIC
|