libstdc++
|
00001 // -*- C++ -*- header. 00002 00003 // Copyright (C) 2008-2015 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/atomic 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. 00030 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html 00031 00032 #ifndef _GLIBCXX_ATOMIC 00033 #define _GLIBCXX_ATOMIC 1 00034 00035 #pragma GCC system_header 00036 00037 #if __cplusplus < 201103L 00038 # include <bits/c++0x_warning.h> 00039 #else 00040 00041 #include <bits/atomic_base.h> 00042 00043 namespace std _GLIBCXX_VISIBILITY(default) 00044 { 00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00046 00047 /** 00048 * @addtogroup atomics 00049 * @{ 00050 */ 00051 00052 template<typename _Tp> 00053 struct atomic; 00054 00055 /// atomic<bool> 00056 // NB: No operators or fetch-operations for this type. 00057 template<> 00058 struct atomic<bool> 00059 { 00060 private: 00061 __atomic_base<bool> _M_base; 00062 00063 public: 00064 atomic() noexcept = default; 00065 ~atomic() noexcept = default; 00066 atomic(const atomic&) = delete; 00067 atomic& operator=(const atomic&) = delete; 00068 atomic& operator=(const atomic&) volatile = delete; 00069 00070 constexpr atomic(bool __i) noexcept : _M_base(__i) { } 00071 00072 bool 00073 operator=(bool __i) noexcept 00074 { return _M_base.operator=(__i); } 00075 00076 bool 00077 operator=(bool __i) volatile noexcept 00078 { return _M_base.operator=(__i); } 00079 00080 operator bool() const noexcept 00081 { return _M_base.load(); } 00082 00083 operator bool() const volatile noexcept 00084 { return _M_base.load(); } 00085 00086 bool 00087 is_lock_free() const noexcept { return _M_base.is_lock_free(); } 00088 00089 bool 00090 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } 00091 00092 void 00093 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept 00094 { _M_base.store(__i, __m); } 00095 00096 void 00097 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept 00098 { _M_base.store(__i, __m); } 00099 00100 bool 00101 load(memory_order __m = memory_order_seq_cst) const noexcept 00102 { return _M_base.load(__m); } 00103 00104 bool 00105 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00106 { return _M_base.load(__m); } 00107 00108 bool 00109 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept 00110 { return _M_base.exchange(__i, __m); } 00111 00112 bool 00113 exchange(bool __i, 00114 memory_order __m = memory_order_seq_cst) volatile noexcept 00115 { return _M_base.exchange(__i, __m); } 00116 00117 bool 00118 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 00119 memory_order __m2) noexcept 00120 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 00121 00122 bool 00123 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 00124 memory_order __m2) volatile noexcept 00125 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 00126 00127 bool 00128 compare_exchange_weak(bool& __i1, bool __i2, 00129 memory_order __m = memory_order_seq_cst) noexcept 00130 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 00131 00132 bool 00133 compare_exchange_weak(bool& __i1, bool __i2, 00134 memory_order __m = memory_order_seq_cst) volatile noexcept 00135 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 00136 00137 bool 00138 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 00139 memory_order __m2) noexcept 00140 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 00141 00142 bool 00143 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 00144 memory_order __m2) volatile noexcept 00145 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 00146 00147 bool 00148 compare_exchange_strong(bool& __i1, bool __i2, 00149 memory_order __m = memory_order_seq_cst) noexcept 00150 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 00151 00152 bool 00153 compare_exchange_strong(bool& __i1, bool __i2, 00154 memory_order __m = memory_order_seq_cst) volatile noexcept 00155 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 00156 }; 00157 00158 00159 /** 00160 * @brief Generic atomic type, primary class template. 00161 * 00162 * @tparam _Tp Type to be made atomic, must be trivally copyable. 00163 */ 00164 template<typename _Tp> 00165 struct atomic 00166 { 00167 private: 00168 // Align 1/2/4/8/16-byte types to at least their size. 00169 static constexpr int _S_min_alignment 00170 = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16 00171 ? 0 : sizeof(_Tp); 00172 00173 static constexpr int _S_alignment 00174 = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp); 00175 00176 alignas(_S_alignment) _Tp _M_i; 00177 00178 static_assert(__is_trivially_copyable(_Tp), 00179 "std::atomic requires a trivially copyable type"); 00180 00181 static_assert(sizeof(_Tp) > 0, 00182 "Incomplete or zero-sized types are not supported"); 00183 00184 public: 00185 atomic() noexcept = default; 00186 ~atomic() noexcept = default; 00187 atomic(const atomic&) = delete; 00188 atomic& operator=(const atomic&) = delete; 00189 atomic& operator=(const atomic&) volatile = delete; 00190 00191 constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } 00192 00193 operator _Tp() const noexcept 00194 { return load(); } 00195 00196 operator _Tp() const volatile noexcept 00197 { return load(); } 00198 00199 _Tp 00200 operator=(_Tp __i) noexcept 00201 { store(__i); return __i; } 00202 00203 _Tp 00204 operator=(_Tp __i) volatile noexcept 00205 { store(__i); return __i; } 00206 00207 bool 00208 is_lock_free() const noexcept 00209 { 00210 // Produce a fake, minimally aligned pointer. 00211 return __atomic_is_lock_free(sizeof(_M_i), 00212 reinterpret_cast<void *>(-__alignof(_M_i))); 00213 } 00214 00215 bool 00216 is_lock_free() const volatile noexcept 00217 { 00218 // Produce a fake, minimally aligned pointer. 00219 return __atomic_is_lock_free(sizeof(_M_i), 00220 reinterpret_cast<void *>(-__alignof(_M_i))); 00221 } 00222 00223 void 00224 store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept 00225 { __atomic_store(&_M_i, &__i, __m); } 00226 00227 void 00228 store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept 00229 { __atomic_store(&_M_i, &__i, __m); } 00230 00231 _Tp 00232 load(memory_order __m = memory_order_seq_cst) const noexcept 00233 { 00234 _Tp tmp; 00235 __atomic_load(&_M_i, &tmp, __m); 00236 return tmp; 00237 } 00238 00239 _Tp 00240 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00241 { 00242 _Tp tmp; 00243 __atomic_load(&_M_i, &tmp, __m); 00244 return tmp; 00245 } 00246 00247 _Tp 00248 exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept 00249 { 00250 _Tp tmp; 00251 __atomic_exchange(&_M_i, &__i, &tmp, __m); 00252 return tmp; 00253 } 00254 00255 _Tp 00256 exchange(_Tp __i, 00257 memory_order __m = memory_order_seq_cst) volatile noexcept 00258 { 00259 _Tp tmp; 00260 __atomic_exchange(&_M_i, &__i, &tmp, __m); 00261 return tmp; 00262 } 00263 00264 bool 00265 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00266 memory_order __f) noexcept 00267 { 00268 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00269 } 00270 00271 bool 00272 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00273 memory_order __f) volatile noexcept 00274 { 00275 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00276 } 00277 00278 bool 00279 compare_exchange_weak(_Tp& __e, _Tp __i, 00280 memory_order __m = memory_order_seq_cst) noexcept 00281 { return compare_exchange_weak(__e, __i, __m, 00282 __cmpexch_failure_order(__m)); } 00283 00284 bool 00285 compare_exchange_weak(_Tp& __e, _Tp __i, 00286 memory_order __m = memory_order_seq_cst) volatile noexcept 00287 { return compare_exchange_weak(__e, __i, __m, 00288 __cmpexch_failure_order(__m)); } 00289 00290 bool 00291 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00292 memory_order __f) noexcept 00293 { 00294 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00295 } 00296 00297 bool 00298 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00299 memory_order __f) volatile noexcept 00300 { 00301 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00302 } 00303 00304 bool 00305 compare_exchange_strong(_Tp& __e, _Tp __i, 00306 memory_order __m = memory_order_seq_cst) noexcept 00307 { return compare_exchange_strong(__e, __i, __m, 00308 __cmpexch_failure_order(__m)); } 00309 00310 bool 00311 compare_exchange_strong(_Tp& __e, _Tp __i, 00312 memory_order __m = memory_order_seq_cst) volatile noexcept 00313 { return compare_exchange_strong(__e, __i, __m, 00314 __cmpexch_failure_order(__m)); } 00315 }; 00316 00317 00318 /// Partial specialization for pointer types. 00319 template<typename _Tp> 00320 struct atomic<_Tp*> 00321 { 00322 typedef _Tp* __pointer_type; 00323 typedef __atomic_base<_Tp*> __base_type; 00324 __base_type _M_b; 00325 00326 atomic() noexcept = default; 00327 ~atomic() noexcept = default; 00328 atomic(const atomic&) = delete; 00329 atomic& operator=(const atomic&) = delete; 00330 atomic& operator=(const atomic&) volatile = delete; 00331 00332 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 00333 00334 operator __pointer_type() const noexcept 00335 { return __pointer_type(_M_b); } 00336 00337 operator __pointer_type() const volatile noexcept 00338 { return __pointer_type(_M_b); } 00339 00340 __pointer_type 00341 operator=(__pointer_type __p) noexcept 00342 { return _M_b.operator=(__p); } 00343 00344 __pointer_type 00345 operator=(__pointer_type __p) volatile noexcept 00346 { return _M_b.operator=(__p); } 00347 00348 __pointer_type 00349 operator++(int) noexcept 00350 { return _M_b++; } 00351 00352 __pointer_type 00353 operator++(int) volatile noexcept 00354 { return _M_b++; } 00355 00356 __pointer_type 00357 operator--(int) noexcept 00358 { return _M_b--; } 00359 00360 __pointer_type 00361 operator--(int) volatile noexcept 00362 { return _M_b--; } 00363 00364 __pointer_type 00365 operator++() noexcept 00366 { return ++_M_b; } 00367 00368 __pointer_type 00369 operator++() volatile noexcept 00370 { return ++_M_b; } 00371 00372 __pointer_type 00373 operator--() noexcept 00374 { return --_M_b; } 00375 00376 __pointer_type 00377 operator--() volatile noexcept 00378 { return --_M_b; } 00379 00380 __pointer_type 00381 operator+=(ptrdiff_t __d) noexcept 00382 { return _M_b.operator+=(__d); } 00383 00384 __pointer_type 00385 operator+=(ptrdiff_t __d) volatile noexcept 00386 { return _M_b.operator+=(__d); } 00387 00388 __pointer_type 00389 operator-=(ptrdiff_t __d) noexcept 00390 { return _M_b.operator-=(__d); } 00391 00392 __pointer_type 00393 operator-=(ptrdiff_t __d) volatile noexcept 00394 { return _M_b.operator-=(__d); } 00395 00396 bool 00397 is_lock_free() const noexcept 00398 { return _M_b.is_lock_free(); } 00399 00400 bool 00401 is_lock_free() const volatile noexcept 00402 { return _M_b.is_lock_free(); } 00403 00404 void 00405 store(__pointer_type __p, 00406 memory_order __m = memory_order_seq_cst) noexcept 00407 { return _M_b.store(__p, __m); } 00408 00409 void 00410 store(__pointer_type __p, 00411 memory_order __m = memory_order_seq_cst) volatile noexcept 00412 { return _M_b.store(__p, __m); } 00413 00414 __pointer_type 00415 load(memory_order __m = memory_order_seq_cst) const noexcept 00416 { return _M_b.load(__m); } 00417 00418 __pointer_type 00419 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00420 { return _M_b.load(__m); } 00421 00422 __pointer_type 00423 exchange(__pointer_type __p, 00424 memory_order __m = memory_order_seq_cst) noexcept 00425 { return _M_b.exchange(__p, __m); } 00426 00427 __pointer_type 00428 exchange(__pointer_type __p, 00429 memory_order __m = memory_order_seq_cst) volatile noexcept 00430 { return _M_b.exchange(__p, __m); } 00431 00432 bool 00433 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00434 memory_order __m1, memory_order __m2) noexcept 00435 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00436 00437 bool 00438 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00439 memory_order __m1, 00440 memory_order __m2) volatile noexcept 00441 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00442 00443 bool 00444 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00445 memory_order __m = memory_order_seq_cst) noexcept 00446 { 00447 return compare_exchange_weak(__p1, __p2, __m, 00448 __cmpexch_failure_order(__m)); 00449 } 00450 00451 bool 00452 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00453 memory_order __m = memory_order_seq_cst) volatile noexcept 00454 { 00455 return compare_exchange_weak(__p1, __p2, __m, 00456 __cmpexch_failure_order(__m)); 00457 } 00458 00459 bool 00460 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00461 memory_order __m1, memory_order __m2) noexcept 00462 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00463 00464 bool 00465 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00466 memory_order __m1, 00467 memory_order __m2) volatile noexcept 00468 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00469 00470 bool 00471 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00472 memory_order __m = memory_order_seq_cst) noexcept 00473 { 00474 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00475 __cmpexch_failure_order(__m)); 00476 } 00477 00478 bool 00479 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00480 memory_order __m = memory_order_seq_cst) volatile noexcept 00481 { 00482 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00483 __cmpexch_failure_order(__m)); 00484 } 00485 00486 __pointer_type 00487 fetch_add(ptrdiff_t __d, 00488 memory_order __m = memory_order_seq_cst) noexcept 00489 { return _M_b.fetch_add(__d, __m); } 00490 00491 __pointer_type 00492 fetch_add(ptrdiff_t __d, 00493 memory_order __m = memory_order_seq_cst) volatile noexcept 00494 { return _M_b.fetch_add(__d, __m); } 00495 00496 __pointer_type 00497 fetch_sub(ptrdiff_t __d, 00498 memory_order __m = memory_order_seq_cst) noexcept 00499 { return _M_b.fetch_sub(__d, __m); } 00500 00501 __pointer_type 00502 fetch_sub(ptrdiff_t __d, 00503 memory_order __m = memory_order_seq_cst) volatile noexcept 00504 { return _M_b.fetch_sub(__d, __m); } 00505 }; 00506 00507 00508 /// Explicit specialization for char. 00509 template<> 00510 struct atomic<char> : __atomic_base<char> 00511 { 00512 typedef char __integral_type; 00513 typedef __atomic_base<char> __base_type; 00514 00515 atomic() noexcept = default; 00516 ~atomic() noexcept = default; 00517 atomic(const atomic&) = delete; 00518 atomic& operator=(const atomic&) = delete; 00519 atomic& operator=(const atomic&) volatile = delete; 00520 00521 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00522 00523 using __base_type::operator __integral_type; 00524 using __base_type::operator=; 00525 }; 00526 00527 /// Explicit specialization for signed char. 00528 template<> 00529 struct atomic<signed char> : __atomic_base<signed char> 00530 { 00531 typedef signed char __integral_type; 00532 typedef __atomic_base<signed char> __base_type; 00533 00534 atomic() noexcept= default; 00535 ~atomic() noexcept = default; 00536 atomic(const atomic&) = delete; 00537 atomic& operator=(const atomic&) = delete; 00538 atomic& operator=(const atomic&) volatile = delete; 00539 00540 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00541 00542 using __base_type::operator __integral_type; 00543 using __base_type::operator=; 00544 }; 00545 00546 /// Explicit specialization for unsigned char. 00547 template<> 00548 struct atomic<unsigned char> : __atomic_base<unsigned char> 00549 { 00550 typedef unsigned char __integral_type; 00551 typedef __atomic_base<unsigned char> __base_type; 00552 00553 atomic() noexcept= default; 00554 ~atomic() noexcept = default; 00555 atomic(const atomic&) = delete; 00556 atomic& operator=(const atomic&) = delete; 00557 atomic& operator=(const atomic&) volatile = delete; 00558 00559 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00560 00561 using __base_type::operator __integral_type; 00562 using __base_type::operator=; 00563 }; 00564 00565 /// Explicit specialization for short. 00566 template<> 00567 struct atomic<short> : __atomic_base<short> 00568 { 00569 typedef short __integral_type; 00570 typedef __atomic_base<short> __base_type; 00571 00572 atomic() noexcept = default; 00573 ~atomic() noexcept = default; 00574 atomic(const atomic&) = delete; 00575 atomic& operator=(const atomic&) = delete; 00576 atomic& operator=(const atomic&) volatile = delete; 00577 00578 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00579 00580 using __base_type::operator __integral_type; 00581 using __base_type::operator=; 00582 }; 00583 00584 /// Explicit specialization for unsigned short. 00585 template<> 00586 struct atomic<unsigned short> : __atomic_base<unsigned short> 00587 { 00588 typedef unsigned short __integral_type; 00589 typedef __atomic_base<unsigned short> __base_type; 00590 00591 atomic() noexcept = default; 00592 ~atomic() noexcept = default; 00593 atomic(const atomic&) = delete; 00594 atomic& operator=(const atomic&) = delete; 00595 atomic& operator=(const atomic&) volatile = delete; 00596 00597 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00598 00599 using __base_type::operator __integral_type; 00600 using __base_type::operator=; 00601 }; 00602 00603 /// Explicit specialization for int. 00604 template<> 00605 struct atomic<int> : __atomic_base<int> 00606 { 00607 typedef int __integral_type; 00608 typedef __atomic_base<int> __base_type; 00609 00610 atomic() noexcept = default; 00611 ~atomic() noexcept = default; 00612 atomic(const atomic&) = delete; 00613 atomic& operator=(const atomic&) = delete; 00614 atomic& operator=(const atomic&) volatile = delete; 00615 00616 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00617 00618 using __base_type::operator __integral_type; 00619 using __base_type::operator=; 00620 }; 00621 00622 /// Explicit specialization for unsigned int. 00623 template<> 00624 struct atomic<unsigned int> : __atomic_base<unsigned int> 00625 { 00626 typedef unsigned int __integral_type; 00627 typedef __atomic_base<unsigned int> __base_type; 00628 00629 atomic() noexcept = default; 00630 ~atomic() noexcept = default; 00631 atomic(const atomic&) = delete; 00632 atomic& operator=(const atomic&) = delete; 00633 atomic& operator=(const atomic&) volatile = delete; 00634 00635 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00636 00637 using __base_type::operator __integral_type; 00638 using __base_type::operator=; 00639 }; 00640 00641 /// Explicit specialization for long. 00642 template<> 00643 struct atomic<long> : __atomic_base<long> 00644 { 00645 typedef long __integral_type; 00646 typedef __atomic_base<long> __base_type; 00647 00648 atomic() noexcept = default; 00649 ~atomic() noexcept = default; 00650 atomic(const atomic&) = delete; 00651 atomic& operator=(const atomic&) = delete; 00652 atomic& operator=(const atomic&) volatile = delete; 00653 00654 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00655 00656 using __base_type::operator __integral_type; 00657 using __base_type::operator=; 00658 }; 00659 00660 /// Explicit specialization for unsigned long. 00661 template<> 00662 struct atomic<unsigned long> : __atomic_base<unsigned long> 00663 { 00664 typedef unsigned long __integral_type; 00665 typedef __atomic_base<unsigned long> __base_type; 00666 00667 atomic() noexcept = default; 00668 ~atomic() noexcept = default; 00669 atomic(const atomic&) = delete; 00670 atomic& operator=(const atomic&) = delete; 00671 atomic& operator=(const atomic&) volatile = delete; 00672 00673 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00674 00675 using __base_type::operator __integral_type; 00676 using __base_type::operator=; 00677 }; 00678 00679 /// Explicit specialization for long long. 00680 template<> 00681 struct atomic<long long> : __atomic_base<long long> 00682 { 00683 typedef long long __integral_type; 00684 typedef __atomic_base<long long> __base_type; 00685 00686 atomic() noexcept = default; 00687 ~atomic() noexcept = default; 00688 atomic(const atomic&) = delete; 00689 atomic& operator=(const atomic&) = delete; 00690 atomic& operator=(const atomic&) volatile = delete; 00691 00692 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00693 00694 using __base_type::operator __integral_type; 00695 using __base_type::operator=; 00696 }; 00697 00698 /// Explicit specialization for unsigned long long. 00699 template<> 00700 struct atomic<unsigned long long> : __atomic_base<unsigned long long> 00701 { 00702 typedef unsigned long long __integral_type; 00703 typedef __atomic_base<unsigned long long> __base_type; 00704 00705 atomic() noexcept = default; 00706 ~atomic() noexcept = default; 00707 atomic(const atomic&) = delete; 00708 atomic& operator=(const atomic&) = delete; 00709 atomic& operator=(const atomic&) volatile = delete; 00710 00711 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00712 00713 using __base_type::operator __integral_type; 00714 using __base_type::operator=; 00715 }; 00716 00717 /// Explicit specialization for wchar_t. 00718 template<> 00719 struct atomic<wchar_t> : __atomic_base<wchar_t> 00720 { 00721 typedef wchar_t __integral_type; 00722 typedef __atomic_base<wchar_t> __base_type; 00723 00724 atomic() noexcept = default; 00725 ~atomic() noexcept = default; 00726 atomic(const atomic&) = delete; 00727 atomic& operator=(const atomic&) = delete; 00728 atomic& operator=(const atomic&) volatile = delete; 00729 00730 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00731 00732 using __base_type::operator __integral_type; 00733 using __base_type::operator=; 00734 }; 00735 00736 /// Explicit specialization for char16_t. 00737 template<> 00738 struct atomic<char16_t> : __atomic_base<char16_t> 00739 { 00740 typedef char16_t __integral_type; 00741 typedef __atomic_base<char16_t> __base_type; 00742 00743 atomic() noexcept = default; 00744 ~atomic() noexcept = default; 00745 atomic(const atomic&) = delete; 00746 atomic& operator=(const atomic&) = delete; 00747 atomic& operator=(const atomic&) volatile = delete; 00748 00749 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00750 00751 using __base_type::operator __integral_type; 00752 using __base_type::operator=; 00753 }; 00754 00755 /// Explicit specialization for char32_t. 00756 template<> 00757 struct atomic<char32_t> : __atomic_base<char32_t> 00758 { 00759 typedef char32_t __integral_type; 00760 typedef __atomic_base<char32_t> __base_type; 00761 00762 atomic() noexcept = default; 00763 ~atomic() noexcept = default; 00764 atomic(const atomic&) = delete; 00765 atomic& operator=(const atomic&) = delete; 00766 atomic& operator=(const atomic&) volatile = delete; 00767 00768 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00769 00770 using __base_type::operator __integral_type; 00771 using __base_type::operator=; 00772 }; 00773 00774 00775 /// atomic_bool 00776 typedef atomic<bool> atomic_bool; 00777 00778 /// atomic_char 00779 typedef atomic<char> atomic_char; 00780 00781 /// atomic_schar 00782 typedef atomic<signed char> atomic_schar; 00783 00784 /// atomic_uchar 00785 typedef atomic<unsigned char> atomic_uchar; 00786 00787 /// atomic_short 00788 typedef atomic<short> atomic_short; 00789 00790 /// atomic_ushort 00791 typedef atomic<unsigned short> atomic_ushort; 00792 00793 /// atomic_int 00794 typedef atomic<int> atomic_int; 00795 00796 /// atomic_uint 00797 typedef atomic<unsigned int> atomic_uint; 00798 00799 /// atomic_long 00800 typedef atomic<long> atomic_long; 00801 00802 /// atomic_ulong 00803 typedef atomic<unsigned long> atomic_ulong; 00804 00805 /// atomic_llong 00806 typedef atomic<long long> atomic_llong; 00807 00808 /// atomic_ullong 00809 typedef atomic<unsigned long long> atomic_ullong; 00810 00811 /// atomic_wchar_t 00812 typedef atomic<wchar_t> atomic_wchar_t; 00813 00814 /// atomic_char16_t 00815 typedef atomic<char16_t> atomic_char16_t; 00816 00817 /// atomic_char32_t 00818 typedef atomic<char32_t> atomic_char32_t; 00819 00820 00821 /// atomic_int_least8_t 00822 typedef atomic<int_least8_t> atomic_int_least8_t; 00823 00824 /// atomic_uint_least8_t 00825 typedef atomic<uint_least8_t> atomic_uint_least8_t; 00826 00827 /// atomic_int_least16_t 00828 typedef atomic<int_least16_t> atomic_int_least16_t; 00829 00830 /// atomic_uint_least16_t 00831 typedef atomic<uint_least16_t> atomic_uint_least16_t; 00832 00833 /// atomic_int_least32_t 00834 typedef atomic<int_least32_t> atomic_int_least32_t; 00835 00836 /// atomic_uint_least32_t 00837 typedef atomic<uint_least32_t> atomic_uint_least32_t; 00838 00839 /// atomic_int_least64_t 00840 typedef atomic<int_least64_t> atomic_int_least64_t; 00841 00842 /// atomic_uint_least64_t 00843 typedef atomic<uint_least64_t> atomic_uint_least64_t; 00844 00845 00846 /// atomic_int_fast8_t 00847 typedef atomic<int_fast8_t> atomic_int_fast8_t; 00848 00849 /// atomic_uint_fast8_t 00850 typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 00851 00852 /// atomic_int_fast16_t 00853 typedef atomic<int_fast16_t> atomic_int_fast16_t; 00854 00855 /// atomic_uint_fast16_t 00856 typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 00857 00858 /// atomic_int_fast32_t 00859 typedef atomic<int_fast32_t> atomic_int_fast32_t; 00860 00861 /// atomic_uint_fast32_t 00862 typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 00863 00864 /// atomic_int_fast64_t 00865 typedef atomic<int_fast64_t> atomic_int_fast64_t; 00866 00867 /// atomic_uint_fast64_t 00868 typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 00869 00870 00871 /// atomic_intptr_t 00872 typedef atomic<intptr_t> atomic_intptr_t; 00873 00874 /// atomic_uintptr_t 00875 typedef atomic<uintptr_t> atomic_uintptr_t; 00876 00877 /// atomic_size_t 00878 typedef atomic<size_t> atomic_size_t; 00879 00880 /// atomic_intmax_t 00881 typedef atomic<intmax_t> atomic_intmax_t; 00882 00883 /// atomic_uintmax_t 00884 typedef atomic<uintmax_t> atomic_uintmax_t; 00885 00886 /// atomic_ptrdiff_t 00887 typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 00888 00889 00890 // Function definitions, atomic_flag operations. 00891 inline bool 00892 atomic_flag_test_and_set_explicit(atomic_flag* __a, 00893 memory_order __m) noexcept 00894 { return __a->test_and_set(__m); } 00895 00896 inline bool 00897 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 00898 memory_order __m) noexcept 00899 { return __a->test_and_set(__m); } 00900 00901 inline void 00902 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 00903 { __a->clear(__m); } 00904 00905 inline void 00906 atomic_flag_clear_explicit(volatile atomic_flag* __a, 00907 memory_order __m) noexcept 00908 { __a->clear(__m); } 00909 00910 inline bool 00911 atomic_flag_test_and_set(atomic_flag* __a) noexcept 00912 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00913 00914 inline bool 00915 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 00916 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00917 00918 inline void 00919 atomic_flag_clear(atomic_flag* __a) noexcept 00920 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00921 00922 inline void 00923 atomic_flag_clear(volatile atomic_flag* __a) noexcept 00924 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00925 00926 00927 // Function templates generally applicable to atomic types. 00928 template<typename _ITp> 00929 inline bool 00930 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 00931 { return __a->is_lock_free(); } 00932 00933 template<typename _ITp> 00934 inline bool 00935 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 00936 { return __a->is_lock_free(); } 00937 00938 template<typename _ITp> 00939 inline void 00940 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept 00941 { __a->store(__i, memory_order_relaxed); } 00942 00943 template<typename _ITp> 00944 inline void 00945 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00946 { __a->store(__i, memory_order_relaxed); } 00947 00948 template<typename _ITp> 00949 inline void 00950 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 00951 memory_order __m) noexcept 00952 { __a->store(__i, __m); } 00953 00954 template<typename _ITp> 00955 inline void 00956 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00957 memory_order __m) noexcept 00958 { __a->store(__i, __m); } 00959 00960 template<typename _ITp> 00961 inline _ITp 00962 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 00963 { return __a->load(__m); } 00964 00965 template<typename _ITp> 00966 inline _ITp 00967 atomic_load_explicit(const volatile atomic<_ITp>* __a, 00968 memory_order __m) noexcept 00969 { return __a->load(__m); } 00970 00971 template<typename _ITp> 00972 inline _ITp 00973 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 00974 memory_order __m) noexcept 00975 { return __a->exchange(__i, __m); } 00976 00977 template<typename _ITp> 00978 inline _ITp 00979 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00980 memory_order __m) noexcept 00981 { return __a->exchange(__i, __m); } 00982 00983 template<typename _ITp> 00984 inline bool 00985 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 00986 _ITp* __i1, _ITp __i2, 00987 memory_order __m1, 00988 memory_order __m2) noexcept 00989 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00990 00991 template<typename _ITp> 00992 inline bool 00993 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 00994 _ITp* __i1, _ITp __i2, 00995 memory_order __m1, 00996 memory_order __m2) noexcept 00997 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00998 00999 template<typename _ITp> 01000 inline bool 01001 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 01002 _ITp* __i1, _ITp __i2, 01003 memory_order __m1, 01004 memory_order __m2) noexcept 01005 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 01006 01007 template<typename _ITp> 01008 inline bool 01009 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 01010 _ITp* __i1, _ITp __i2, 01011 memory_order __m1, 01012 memory_order __m2) noexcept 01013 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 01014 01015 01016 template<typename _ITp> 01017 inline void 01018 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 01019 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 01020 01021 template<typename _ITp> 01022 inline void 01023 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 01024 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 01025 01026 template<typename _ITp> 01027 inline _ITp 01028 atomic_load(const atomic<_ITp>* __a) noexcept 01029 { return atomic_load_explicit(__a, memory_order_seq_cst); } 01030 01031 template<typename _ITp> 01032 inline _ITp 01033 atomic_load(const volatile atomic<_ITp>* __a) noexcept 01034 { return atomic_load_explicit(__a, memory_order_seq_cst); } 01035 01036 template<typename _ITp> 01037 inline _ITp 01038 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 01039 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 01040 01041 template<typename _ITp> 01042 inline _ITp 01043 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 01044 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 01045 01046 template<typename _ITp> 01047 inline bool 01048 atomic_compare_exchange_weak(atomic<_ITp>* __a, 01049 _ITp* __i1, _ITp __i2) noexcept 01050 { 01051 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 01052 memory_order_seq_cst, 01053 memory_order_seq_cst); 01054 } 01055 01056 template<typename _ITp> 01057 inline bool 01058 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 01059 _ITp* __i1, _ITp __i2) noexcept 01060 { 01061 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 01062 memory_order_seq_cst, 01063 memory_order_seq_cst); 01064 } 01065 01066 template<typename _ITp> 01067 inline bool 01068 atomic_compare_exchange_strong(atomic<_ITp>* __a, 01069 _ITp* __i1, _ITp __i2) noexcept 01070 { 01071 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 01072 memory_order_seq_cst, 01073 memory_order_seq_cst); 01074 } 01075 01076 template<typename _ITp> 01077 inline bool 01078 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 01079 _ITp* __i1, _ITp __i2) noexcept 01080 { 01081 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 01082 memory_order_seq_cst, 01083 memory_order_seq_cst); 01084 } 01085 01086 // Function templates for atomic_integral operations only, using 01087 // __atomic_base. Template argument should be constricted to 01088 // intergral types as specified in the standard, excluding address 01089 // types. 01090 template<typename _ITp> 01091 inline _ITp 01092 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01093 memory_order __m) noexcept 01094 { return __a->fetch_add(__i, __m); } 01095 01096 template<typename _ITp> 01097 inline _ITp 01098 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01099 memory_order __m) noexcept 01100 { return __a->fetch_add(__i, __m); } 01101 01102 template<typename _ITp> 01103 inline _ITp 01104 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01105 memory_order __m) noexcept 01106 { return __a->fetch_sub(__i, __m); } 01107 01108 template<typename _ITp> 01109 inline _ITp 01110 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01111 memory_order __m) noexcept 01112 { return __a->fetch_sub(__i, __m); } 01113 01114 template<typename _ITp> 01115 inline _ITp 01116 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01117 memory_order __m) noexcept 01118 { return __a->fetch_and(__i, __m); } 01119 01120 template<typename _ITp> 01121 inline _ITp 01122 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01123 memory_order __m) noexcept 01124 { return __a->fetch_and(__i, __m); } 01125 01126 template<typename _ITp> 01127 inline _ITp 01128 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01129 memory_order __m) noexcept 01130 { return __a->fetch_or(__i, __m); } 01131 01132 template<typename _ITp> 01133 inline _ITp 01134 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01135 memory_order __m) noexcept 01136 { return __a->fetch_or(__i, __m); } 01137 01138 template<typename _ITp> 01139 inline _ITp 01140 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01141 memory_order __m) noexcept 01142 { return __a->fetch_xor(__i, __m); } 01143 01144 template<typename _ITp> 01145 inline _ITp 01146 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01147 memory_order __m) noexcept 01148 { return __a->fetch_xor(__i, __m); } 01149 01150 template<typename _ITp> 01151 inline _ITp 01152 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01153 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01154 01155 template<typename _ITp> 01156 inline _ITp 01157 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01158 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01159 01160 template<typename _ITp> 01161 inline _ITp 01162 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01163 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01164 01165 template<typename _ITp> 01166 inline _ITp 01167 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01168 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01169 01170 template<typename _ITp> 01171 inline _ITp 01172 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01173 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01174 01175 template<typename _ITp> 01176 inline _ITp 01177 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01178 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01179 01180 template<typename _ITp> 01181 inline _ITp 01182 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01183 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01184 01185 template<typename _ITp> 01186 inline _ITp 01187 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01188 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01189 01190 template<typename _ITp> 01191 inline _ITp 01192 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01193 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01194 01195 template<typename _ITp> 01196 inline _ITp 01197 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01198 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01199 01200 01201 // Partial specializations for pointers. 01202 template<typename _ITp> 01203 inline _ITp* 01204 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01205 memory_order __m) noexcept 01206 { return __a->fetch_add(__d, __m); } 01207 01208 template<typename _ITp> 01209 inline _ITp* 01210 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 01211 memory_order __m) noexcept 01212 { return __a->fetch_add(__d, __m); } 01213 01214 template<typename _ITp> 01215 inline _ITp* 01216 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01217 { return __a->fetch_add(__d); } 01218 01219 template<typename _ITp> 01220 inline _ITp* 01221 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01222 { return __a->fetch_add(__d); } 01223 01224 template<typename _ITp> 01225 inline _ITp* 01226 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 01227 ptrdiff_t __d, memory_order __m) noexcept 01228 { return __a->fetch_sub(__d, __m); } 01229 01230 template<typename _ITp> 01231 inline _ITp* 01232 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01233 memory_order __m) noexcept 01234 { return __a->fetch_sub(__d, __m); } 01235 01236 template<typename _ITp> 01237 inline _ITp* 01238 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01239 { return __a->fetch_sub(__d); } 01240 01241 template<typename _ITp> 01242 inline _ITp* 01243 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01244 { return __a->fetch_sub(__d); } 01245 // @} group atomics 01246 01247 _GLIBCXX_END_NAMESPACE_VERSION 01248 } // namespace 01249 01250 #endif // C++11 01251 01252 #endif // _GLIBCXX_ATOMIC