1// -*- C++ -*- header. 2 3// Copyright (C) 2008-2015 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 43namespace 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 load(memory_order __m = memory_order_seq_cst) const noexcept 102 { 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 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 235 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 236 __atomic_load(&_M_i, __ptr, __m); 237 return *__ptr; 238 } 239 240 _Tp 241 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 242 { 243 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 244 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 245 __atomic_load(&_M_i, __ptr, __m); 246 return *__ptr; 247 } 248 249 _Tp 250 exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept 251 { 252 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 253 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 254 __atomic_exchange(&_M_i, &__i, __ptr, __m); 255 return *__ptr; 256 } 257 258 _Tp 259 exchange(_Tp __i, 260 memory_order __m = memory_order_seq_cst) volatile noexcept 261 { 262 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 263 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 264 __atomic_exchange(&_M_i, &__i, __ptr, __m); 265 return *__ptr; 266 } 267 268 bool 269 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 270 memory_order __f) noexcept 271 { 272 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 273 } 274 275 bool 276 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 277 memory_order __f) volatile noexcept 278 { 279 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 280 } 281 282 bool 283 compare_exchange_weak(_Tp& __e, _Tp __i, 284 memory_order __m = memory_order_seq_cst) noexcept 285 { return compare_exchange_weak(__e, __i, __m, 286 __cmpexch_failure_order(__m)); } 287 288 bool 289 compare_exchange_weak(_Tp& __e, _Tp __i, 290 memory_order __m = memory_order_seq_cst) volatile noexcept 291 { return compare_exchange_weak(__e, __i, __m, 292 __cmpexch_failure_order(__m)); } 293 294 bool 295 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 296 memory_order __f) noexcept 297 { 298 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 299 } 300 301 bool 302 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 303 memory_order __f) volatile noexcept 304 { 305 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 306 } 307 308 bool 309 compare_exchange_strong(_Tp& __e, _Tp __i, 310 memory_order __m = memory_order_seq_cst) noexcept 311 { return compare_exchange_strong(__e, __i, __m, 312 __cmpexch_failure_order(__m)); } 313 314 bool 315 compare_exchange_strong(_Tp& __e, _Tp __i, 316 memory_order __m = memory_order_seq_cst) volatile noexcept 317 { return compare_exchange_strong(__e, __i, __m, 318 __cmpexch_failure_order(__m)); } 319 }; 320 321 322 /// Partial specialization for pointer types. 323 template<typename _Tp> 324 struct atomic<_Tp*> 325 { 326 typedef _Tp* __pointer_type; 327 typedef __atomic_base<_Tp*> __base_type; 328 __base_type _M_b; 329 330 atomic() noexcept = default; 331 ~atomic() noexcept = default; 332 atomic(const atomic&) = delete; 333 atomic& operator=(const atomic&) = delete; 334 atomic& operator=(const atomic&) volatile = delete; 335 336 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 337 338 operator __pointer_type() const noexcept 339 { return __pointer_type(_M_b); } 340 341 operator __pointer_type() const volatile noexcept 342 { return __pointer_type(_M_b); } 343 344 __pointer_type 345 operator=(__pointer_type __p) noexcept 346 { return _M_b.operator=(__p); } 347 348 __pointer_type 349 operator=(__pointer_type __p) volatile noexcept 350 { return _M_b.operator=(__p); } 351 352 __pointer_type 353 operator++(int) noexcept 354 { return _M_b++; } 355 356 __pointer_type 357 operator++(int) volatile noexcept 358 { return _M_b++; } 359 360 __pointer_type 361 operator--(int) noexcept 362 { return _M_b--; } 363 364 __pointer_type 365 operator--(int) volatile noexcept 366 { return _M_b--; } 367 368 __pointer_type 369 operator++() noexcept 370 { return ++_M_b; } 371 372 __pointer_type 373 operator++() volatile noexcept 374 { return ++_M_b; } 375 376 __pointer_type 377 operator--() noexcept 378 { return --_M_b; } 379 380 __pointer_type 381 operator--() volatile noexcept 382 { return --_M_b; } 383 384 __pointer_type 385 operator+=(ptrdiff_t __d) noexcept 386 { return _M_b.operator+=(__d); } 387 388 __pointer_type 389 operator+=(ptrdiff_t __d) volatile noexcept 390 { return _M_b.operator+=(__d); } 391 392 __pointer_type 393 operator-=(ptrdiff_t __d) noexcept 394 { return _M_b.operator-=(__d); } 395 396 __pointer_type 397 operator-=(ptrdiff_t __d) volatile noexcept 398 { return _M_b.operator-=(__d); } 399 400 bool 401 is_lock_free() const noexcept 402 { return _M_b.is_lock_free(); } 403 404 bool 405 is_lock_free() const volatile noexcept 406 { return _M_b.is_lock_free(); } 407 408 void 409 store(__pointer_type __p, 410 memory_order __m = memory_order_seq_cst) noexcept 411 { return _M_b.store(__p, __m); } 412 413 void 414 store(__pointer_type __p, 415 memory_order __m = memory_order_seq_cst) volatile noexcept 416 { return _M_b.store(__p, __m); } 417 418 __pointer_type 419 load(memory_order __m = memory_order_seq_cst) const noexcept 420 { return _M_b.load(__m); } 421 422 __pointer_type 423 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 424 { return _M_b.load(__m); } 425 426 __pointer_type 427 exchange(__pointer_type __p, 428 memory_order __m = memory_order_seq_cst) noexcept 429 { return _M_b.exchange(__p, __m); } 430 431 __pointer_type 432 exchange(__pointer_type __p, 433 memory_order __m = memory_order_seq_cst) volatile noexcept 434 { return _M_b.exchange(__p, __m); } 435 436 bool 437 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 438 memory_order __m1, memory_order __m2) noexcept 439 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 440 441 bool 442 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 443 memory_order __m1, 444 memory_order __m2) volatile noexcept 445 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 446 447 bool 448 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 449 memory_order __m = memory_order_seq_cst) noexcept 450 { 451 return compare_exchange_weak(__p1, __p2, __m, 452 __cmpexch_failure_order(__m)); 453 } 454 455 bool 456 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 457 memory_order __m = memory_order_seq_cst) volatile noexcept 458 { 459 return compare_exchange_weak(__p1, __p2, __m, 460 __cmpexch_failure_order(__m)); 461 } 462 463 bool 464 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 465 memory_order __m1, memory_order __m2) noexcept 466 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 467 468 bool 469 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 470 memory_order __m1, 471 memory_order __m2) volatile noexcept 472 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 473 474 bool 475 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 476 memory_order __m = memory_order_seq_cst) noexcept 477 { 478 return _M_b.compare_exchange_strong(__p1, __p2, __m, 479 __cmpexch_failure_order(__m)); 480 } 481 482 bool 483 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 484 memory_order __m = memory_order_seq_cst) volatile noexcept 485 { 486 return _M_b.compare_exchange_strong(__p1, __p2, __m, 487 __cmpexch_failure_order(__m)); 488 } 489 490 __pointer_type 491 fetch_add(ptrdiff_t __d, 492 memory_order __m = memory_order_seq_cst) noexcept 493 { return _M_b.fetch_add(__d, __m); } 494 495 __pointer_type 496 fetch_add(ptrdiff_t __d, 497 memory_order __m = memory_order_seq_cst) volatile noexcept 498 { return _M_b.fetch_add(__d, __m); } 499 500 __pointer_type 501 fetch_sub(ptrdiff_t __d, 502 memory_order __m = memory_order_seq_cst) noexcept 503 { return _M_b.fetch_sub(__d, __m); } 504 505 __pointer_type 506 fetch_sub(ptrdiff_t __d, 507 memory_order __m = memory_order_seq_cst) volatile noexcept 508 { return _M_b.fetch_sub(__d, __m); } 509 }; 510 511 512 /// Explicit specialization for char. 513 template<> 514 struct atomic<char> : __atomic_base<char> 515 { 516 typedef char __integral_type; 517 typedef __atomic_base<char> __base_type; 518 519 atomic() noexcept = default; 520 ~atomic() noexcept = default; 521 atomic(const atomic&) = delete; 522 atomic& operator=(const atomic&) = delete; 523 atomic& operator=(const atomic&) volatile = delete; 524 525 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 526 527 using __base_type::operator __integral_type; 528 using __base_type::operator=; 529 }; 530 531 /// Explicit specialization for signed char. 532 template<> 533 struct atomic<signed char> : __atomic_base<signed char> 534 { 535 typedef signed char __integral_type; 536 typedef __atomic_base<signed char> __base_type; 537 538 atomic() noexcept= default; 539 ~atomic() noexcept = default; 540 atomic(const atomic&) = delete; 541 atomic& operator=(const atomic&) = delete; 542 atomic& operator=(const atomic&) volatile = delete; 543 544 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 545 546 using __base_type::operator __integral_type; 547 using __base_type::operator=; 548 }; 549 550 /// Explicit specialization for unsigned char. 551 template<> 552 struct atomic<unsigned char> : __atomic_base<unsigned char> 553 { 554 typedef unsigned char __integral_type; 555 typedef __atomic_base<unsigned char> __base_type; 556 557 atomic() noexcept= default; 558 ~atomic() noexcept = default; 559 atomic(const atomic&) = delete; 560 atomic& operator=(const atomic&) = delete; 561 atomic& operator=(const atomic&) volatile = delete; 562 563 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 564 565 using __base_type::operator __integral_type; 566 using __base_type::operator=; 567 }; 568 569 /// Explicit specialization for short. 570 template<> 571 struct atomic<short> : __atomic_base<short> 572 { 573 typedef short __integral_type; 574 typedef __atomic_base<short> __base_type; 575 576 atomic() noexcept = default; 577 ~atomic() noexcept = default; 578 atomic(const atomic&) = delete; 579 atomic& operator=(const atomic&) = delete; 580 atomic& operator=(const atomic&) volatile = delete; 581 582 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 583 584 using __base_type::operator __integral_type; 585 using __base_type::operator=; 586 }; 587 588 /// Explicit specialization for unsigned short. 589 template<> 590 struct atomic<unsigned short> : __atomic_base<unsigned short> 591 { 592 typedef unsigned short __integral_type; 593 typedef __atomic_base<unsigned short> __base_type; 594 595 atomic() noexcept = default; 596 ~atomic() noexcept = default; 597 atomic(const atomic&) = delete; 598 atomic& operator=(const atomic&) = delete; 599 atomic& operator=(const atomic&) volatile = delete; 600 601 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 602 603 using __base_type::operator __integral_type; 604 using __base_type::operator=; 605 }; 606 607 /// Explicit specialization for int. 608 template<> 609 struct atomic<int> : __atomic_base<int> 610 { 611 typedef int __integral_type; 612 typedef __atomic_base<int> __base_type; 613 614 atomic() noexcept = default; 615 ~atomic() noexcept = default; 616 atomic(const atomic&) = delete; 617 atomic& operator=(const atomic&) = delete; 618 atomic& operator=(const atomic&) volatile = delete; 619 620 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 621 622 using __base_type::operator __integral_type; 623 using __base_type::operator=; 624 }; 625 626 /// Explicit specialization for unsigned int. 627 template<> 628 struct atomic<unsigned int> : __atomic_base<unsigned int> 629 { 630 typedef unsigned int __integral_type; 631 typedef __atomic_base<unsigned int> __base_type; 632 633 atomic() noexcept = default; 634 ~atomic() noexcept = default; 635 atomic(const atomic&) = delete; 636 atomic& operator=(const atomic&) = delete; 637 atomic& operator=(const atomic&) volatile = delete; 638 639 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 640 641 using __base_type::operator __integral_type; 642 using __base_type::operator=; 643 }; 644 645 /// Explicit specialization for long. 646 template<> 647 struct atomic<long> : __atomic_base<long> 648 { 649 typedef long __integral_type; 650 typedef __atomic_base<long> __base_type; 651 652 atomic() noexcept = default; 653 ~atomic() noexcept = default; 654 atomic(const atomic&) = delete; 655 atomic& operator=(const atomic&) = delete; 656 atomic& operator=(const atomic&) volatile = delete; 657 658 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 659 660 using __base_type::operator __integral_type; 661 using __base_type::operator=; 662 }; 663 664 /// Explicit specialization for unsigned long. 665 template<> 666 struct atomic<unsigned long> : __atomic_base<unsigned long> 667 { 668 typedef unsigned long __integral_type; 669 typedef __atomic_base<unsigned long> __base_type; 670 671 atomic() noexcept = default; 672 ~atomic() noexcept = default; 673 atomic(const atomic&) = delete; 674 atomic& operator=(const atomic&) = delete; 675 atomic& operator=(const atomic&) volatile = delete; 676 677 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 678 679 using __base_type::operator __integral_type; 680 using __base_type::operator=; 681 }; 682 683 /// Explicit specialization for long long. 684 template<> 685 struct atomic<long long> : __atomic_base<long long> 686 { 687 typedef long long __integral_type; 688 typedef __atomic_base<long long> __base_type; 689 690 atomic() noexcept = default; 691 ~atomic() noexcept = default; 692 atomic(const atomic&) = delete; 693 atomic& operator=(const atomic&) = delete; 694 atomic& operator=(const atomic&) volatile = delete; 695 696 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 697 698 using __base_type::operator __integral_type; 699 using __base_type::operator=; 700 }; 701 702 /// Explicit specialization for unsigned long long. 703 template<> 704 struct atomic<unsigned long long> : __atomic_base<unsigned long long> 705 { 706 typedef unsigned long long __integral_type; 707 typedef __atomic_base<unsigned long long> __base_type; 708 709 atomic() noexcept = default; 710 ~atomic() noexcept = default; 711 atomic(const atomic&) = delete; 712 atomic& operator=(const atomic&) = delete; 713 atomic& operator=(const atomic&) volatile = delete; 714 715 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 716 717 using __base_type::operator __integral_type; 718 using __base_type::operator=; 719 }; 720 721 /// Explicit specialization for wchar_t. 722 template<> 723 struct atomic<wchar_t> : __atomic_base<wchar_t> 724 { 725 typedef wchar_t __integral_type; 726 typedef __atomic_base<wchar_t> __base_type; 727 728 atomic() noexcept = default; 729 ~atomic() noexcept = default; 730 atomic(const atomic&) = delete; 731 atomic& operator=(const atomic&) = delete; 732 atomic& operator=(const atomic&) volatile = delete; 733 734 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 735 736 using __base_type::operator __integral_type; 737 using __base_type::operator=; 738 }; 739 740 /// Explicit specialization for char16_t. 741 template<> 742 struct atomic<char16_t> : __atomic_base<char16_t> 743 { 744 typedef char16_t __integral_type; 745 typedef __atomic_base<char16_t> __base_type; 746 747 atomic() noexcept = default; 748 ~atomic() noexcept = default; 749 atomic(const atomic&) = delete; 750 atomic& operator=(const atomic&) = delete; 751 atomic& operator=(const atomic&) volatile = delete; 752 753 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 754 755 using __base_type::operator __integral_type; 756 using __base_type::operator=; 757 }; 758 759 /// Explicit specialization for char32_t. 760 template<> 761 struct atomic<char32_t> : __atomic_base<char32_t> 762 { 763 typedef char32_t __integral_type; 764 typedef __atomic_base<char32_t> __base_type; 765 766 atomic() noexcept = default; 767 ~atomic() noexcept = default; 768 atomic(const atomic&) = delete; 769 atomic& operator=(const atomic&) = delete; 770 atomic& operator=(const atomic&) volatile = delete; 771 772 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 773 774 using __base_type::operator __integral_type; 775 using __base_type::operator=; 776 }; 777 778 779 /// atomic_bool 780 typedef atomic<bool> atomic_bool; 781 782 /// atomic_char 783 typedef atomic<char> atomic_char; 784 785 /// atomic_schar 786 typedef atomic<signed char> atomic_schar; 787 788 /// atomic_uchar 789 typedef atomic<unsigned char> atomic_uchar; 790 791 /// atomic_short 792 typedef atomic<short> atomic_short; 793 794 /// atomic_ushort 795 typedef atomic<unsigned short> atomic_ushort; 796 797 /// atomic_int 798 typedef atomic<int> atomic_int; 799 800 /// atomic_uint 801 typedef atomic<unsigned int> atomic_uint; 802 803 /// atomic_long 804 typedef atomic<long> atomic_long; 805 806 /// atomic_ulong 807 typedef atomic<unsigned long> atomic_ulong; 808 809 /// atomic_llong 810 typedef atomic<long long> atomic_llong; 811 812 /// atomic_ullong 813 typedef atomic<unsigned long long> atomic_ullong; 814 815 /// atomic_wchar_t 816 typedef atomic<wchar_t> atomic_wchar_t; 817 818 /// atomic_char16_t 819 typedef atomic<char16_t> atomic_char16_t; 820 821 /// atomic_char32_t 822 typedef atomic<char32_t> atomic_char32_t; 823 824 825 /// atomic_int_least8_t 826 typedef atomic<int_least8_t> atomic_int_least8_t; 827 828 /// atomic_uint_least8_t 829 typedef atomic<uint_least8_t> atomic_uint_least8_t; 830 831 /// atomic_int_least16_t 832 typedef atomic<int_least16_t> atomic_int_least16_t; 833 834 /// atomic_uint_least16_t 835 typedef atomic<uint_least16_t> atomic_uint_least16_t; 836 837 /// atomic_int_least32_t 838 typedef atomic<int_least32_t> atomic_int_least32_t; 839 840 /// atomic_uint_least32_t 841 typedef atomic<uint_least32_t> atomic_uint_least32_t; 842 843 /// atomic_int_least64_t 844 typedef atomic<int_least64_t> atomic_int_least64_t; 845 846 /// atomic_uint_least64_t 847 typedef atomic<uint_least64_t> atomic_uint_least64_t; 848 849 850 /// atomic_int_fast8_t 851 typedef atomic<int_fast8_t> atomic_int_fast8_t; 852 853 /// atomic_uint_fast8_t 854 typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 855 856 /// atomic_int_fast16_t 857 typedef atomic<int_fast16_t> atomic_int_fast16_t; 858 859 /// atomic_uint_fast16_t 860 typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 861 862 /// atomic_int_fast32_t 863 typedef atomic<int_fast32_t> atomic_int_fast32_t; 864 865 /// atomic_uint_fast32_t 866 typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 867 868 /// atomic_int_fast64_t 869 typedef atomic<int_fast64_t> atomic_int_fast64_t; 870 871 /// atomic_uint_fast64_t 872 typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 873 874 875 /// atomic_intptr_t 876 typedef atomic<intptr_t> atomic_intptr_t; 877 878 /// atomic_uintptr_t 879 typedef atomic<uintptr_t> atomic_uintptr_t; 880 881 /// atomic_size_t 882 typedef atomic<size_t> atomic_size_t; 883 884 /// atomic_intmax_t 885 typedef atomic<intmax_t> atomic_intmax_t; 886 887 /// atomic_uintmax_t 888 typedef atomic<uintmax_t> atomic_uintmax_t; 889 890 /// atomic_ptrdiff_t 891 typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 892 893 894 // Function definitions, atomic_flag operations. 895 inline bool 896 atomic_flag_test_and_set_explicit(atomic_flag* __a, 897 memory_order __m) noexcept 898 { return __a->test_and_set(__m); } 899 900 inline bool 901 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 902 memory_order __m) noexcept 903 { return __a->test_and_set(__m); } 904 905 inline void 906 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 907 { __a->clear(__m); } 908 909 inline void 910 atomic_flag_clear_explicit(volatile atomic_flag* __a, 911 memory_order __m) noexcept 912 { __a->clear(__m); } 913 914 inline bool 915 atomic_flag_test_and_set(atomic_flag* __a) noexcept 916 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 917 918 inline bool 919 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 920 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 921 922 inline void 923 atomic_flag_clear(atomic_flag* __a) noexcept 924 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 925 926 inline void 927 atomic_flag_clear(volatile atomic_flag* __a) noexcept 928 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 929 930 931 // Function templates generally applicable to atomic types. 932 template<typename _ITp> 933 inline bool 934 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 935 { return __a->is_lock_free(); } 936 937 template<typename _ITp> 938 inline bool 939 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 940 { return __a->is_lock_free(); } 941 942 template<typename _ITp> 943 inline void 944 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept 945 { __a->store(__i, memory_order_relaxed); } 946 947 template<typename _ITp> 948 inline void 949 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept 950 { __a->store(__i, memory_order_relaxed); } 951 952 template<typename _ITp> 953 inline void 954 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 955 memory_order __m) noexcept 956 { __a->store(__i, __m); } 957 958 template<typename _ITp> 959 inline void 960 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 961 memory_order __m) noexcept 962 { __a->store(__i, __m); } 963 964 template<typename _ITp> 965 inline _ITp 966 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 967 { return __a->load(__m); } 968 969 template<typename _ITp> 970 inline _ITp 971 atomic_load_explicit(const volatile atomic<_ITp>* __a, 972 memory_order __m) noexcept 973 { return __a->load(__m); } 974 975 template<typename _ITp> 976 inline _ITp 977 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 978 memory_order __m) noexcept 979 { return __a->exchange(__i, __m); } 980 981 template<typename _ITp> 982 inline _ITp 983 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 984 memory_order __m) noexcept 985 { return __a->exchange(__i, __m); } 986 987 template<typename _ITp> 988 inline bool 989 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 990 _ITp* __i1, _ITp __i2, 991 memory_order __m1, 992 memory_order __m2) noexcept 993 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 994 995 template<typename _ITp> 996 inline bool 997 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 998 _ITp* __i1, _ITp __i2, 999 memory_order __m1, 1000 memory_order __m2) noexcept 1001 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 1002 1003 template<typename _ITp> 1004 inline bool 1005 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 1006 _ITp* __i1, _ITp __i2, 1007 memory_order __m1, 1008 memory_order __m2) noexcept 1009 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 1010 1011 template<typename _ITp> 1012 inline bool 1013 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 1014 _ITp* __i1, _ITp __i2, 1015 memory_order __m1, 1016 memory_order __m2) noexcept 1017 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 1018 1019 1020 template<typename _ITp> 1021 inline void 1022 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 1023 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 1024 1025 template<typename _ITp> 1026 inline void 1027 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 1028 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 1029 1030 template<typename _ITp> 1031 inline _ITp 1032 atomic_load(const atomic<_ITp>* __a) noexcept 1033 { return atomic_load_explicit(__a, memory_order_seq_cst); } 1034 1035 template<typename _ITp> 1036 inline _ITp 1037 atomic_load(const volatile atomic<_ITp>* __a) noexcept 1038 { return atomic_load_explicit(__a, memory_order_seq_cst); } 1039 1040 template<typename _ITp> 1041 inline _ITp 1042 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 1043 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 1044 1045 template<typename _ITp> 1046 inline _ITp 1047 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 1048 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 1049 1050 template<typename _ITp> 1051 inline bool 1052 atomic_compare_exchange_weak(atomic<_ITp>* __a, 1053 _ITp* __i1, _ITp __i2) noexcept 1054 { 1055 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 1056 memory_order_seq_cst, 1057 memory_order_seq_cst); 1058 } 1059 1060 template<typename _ITp> 1061 inline bool 1062 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 1063 _ITp* __i1, _ITp __i2) noexcept 1064 { 1065 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 1066 memory_order_seq_cst, 1067 memory_order_seq_cst); 1068 } 1069 1070 template<typename _ITp> 1071 inline bool 1072 atomic_compare_exchange_strong(atomic<_ITp>* __a, 1073 _ITp* __i1, _ITp __i2) noexcept 1074 { 1075 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 1076 memory_order_seq_cst, 1077 memory_order_seq_cst); 1078 } 1079 1080 template<typename _ITp> 1081 inline bool 1082 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 1083 _ITp* __i1, _ITp __i2) noexcept 1084 { 1085 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 1086 memory_order_seq_cst, 1087 memory_order_seq_cst); 1088 } 1089 1090 // Function templates for atomic_integral operations only, using 1091 // __atomic_base. Template argument should be constricted to 1092 // intergral types as specified in the standard, excluding address 1093 // types. 1094 template<typename _ITp> 1095 inline _ITp 1096 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 1097 memory_order __m) noexcept 1098 { return __a->fetch_add(__i, __m); } 1099 1100 template<typename _ITp> 1101 inline _ITp 1102 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 1103 memory_order __m) noexcept 1104 { return __a->fetch_add(__i, __m); } 1105 1106 template<typename _ITp> 1107 inline _ITp 1108 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 1109 memory_order __m) noexcept 1110 { return __a->fetch_sub(__i, __m); } 1111 1112 template<typename _ITp> 1113 inline _ITp 1114 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 1115 memory_order __m) noexcept 1116 { return __a->fetch_sub(__i, __m); } 1117 1118 template<typename _ITp> 1119 inline _ITp 1120 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 1121 memory_order __m) noexcept 1122 { return __a->fetch_and(__i, __m); } 1123 1124 template<typename _ITp> 1125 inline _ITp 1126 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 1127 memory_order __m) noexcept 1128 { return __a->fetch_and(__i, __m); } 1129 1130 template<typename _ITp> 1131 inline _ITp 1132 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 1133 memory_order __m) noexcept 1134 { return __a->fetch_or(__i, __m); } 1135 1136 template<typename _ITp> 1137 inline _ITp 1138 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 1139 memory_order __m) noexcept 1140 { return __a->fetch_or(__i, __m); } 1141 1142 template<typename _ITp> 1143 inline _ITp 1144 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 1145 memory_order __m) noexcept 1146 { return __a->fetch_xor(__i, __m); } 1147 1148 template<typename _ITp> 1149 inline _ITp 1150 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 1151 memory_order __m) noexcept 1152 { return __a->fetch_xor(__i, __m); } 1153 1154 template<typename _ITp> 1155 inline _ITp 1156 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1157 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 1158 1159 template<typename _ITp> 1160 inline _ITp 1161 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1162 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 1163 1164 template<typename _ITp> 1165 inline _ITp 1166 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1167 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 1168 1169 template<typename _ITp> 1170 inline _ITp 1171 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1172 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 1173 1174 template<typename _ITp> 1175 inline _ITp 1176 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1177 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 1178 1179 template<typename _ITp> 1180 inline _ITp 1181 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1182 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 1183 1184 template<typename _ITp> 1185 inline _ITp 1186 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1187 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 1188 1189 template<typename _ITp> 1190 inline _ITp 1191 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1192 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 1193 1194 template<typename _ITp> 1195 inline _ITp 1196 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1197 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 1198 1199 template<typename _ITp> 1200 inline _ITp 1201 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1202 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 1203 1204 1205 // Partial specializations for pointers. 1206 template<typename _ITp> 1207 inline _ITp* 1208 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 1209 memory_order __m) noexcept 1210 { return __a->fetch_add(__d, __m); } 1211 1212 template<typename _ITp> 1213 inline _ITp* 1214 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 1215 memory_order __m) noexcept 1216 { return __a->fetch_add(__d, __m); } 1217 1218 template<typename _ITp> 1219 inline _ITp* 1220 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1221 { return __a->fetch_add(__d); } 1222 1223 template<typename _ITp> 1224 inline _ITp* 1225 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1226 { return __a->fetch_add(__d); } 1227 1228 template<typename _ITp> 1229 inline _ITp* 1230 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 1231 ptrdiff_t __d, memory_order __m) noexcept 1232 { return __a->fetch_sub(__d, __m); } 1233 1234 template<typename _ITp> 1235 inline _ITp* 1236 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 1237 memory_order __m) noexcept 1238 { return __a->fetch_sub(__d, __m); } 1239 1240 template<typename _ITp> 1241 inline _ITp* 1242 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1243 { return __a->fetch_sub(__d); } 1244 1245 template<typename _ITp> 1246 inline _ITp* 1247 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1248 { return __a->fetch_sub(__d); } 1249 // @} group atomics 1250 1251_GLIBCXX_END_NAMESPACE_VERSION 1252} // namespace 1253 1254#endif // C++11 1255 1256#endif // _GLIBCXX_ATOMIC 1257