|
libstdc++
|
00001 // -*- C++ -*- header. 00002 00003 // Copyright (C) 2008, 2009, 2010, 2011, 2012 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 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00038 # include <bits/c++0x_warning.h> 00039 #endif 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 /// atomic_bool 00053 // NB: No operators or fetch-operations for this type. 00054 struct atomic_bool 00055 { 00056 private: 00057 __atomic_base<bool> _M_base; 00058 00059 public: 00060 atomic_bool() noexcept = default; 00061 ~atomic_bool() noexcept = default; 00062 atomic_bool(const atomic_bool&) = delete; 00063 atomic_bool& operator=(const atomic_bool&) = delete; 00064 atomic_bool& operator=(const atomic_bool&) volatile = delete; 00065 00066 constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { } 00067 00068 bool 00069 operator=(bool __i) noexcept 00070 { return _M_base.operator=(__i); } 00071 00072 operator bool() const noexcept 00073 { return _M_base.load(); } 00074 00075 operator bool() const volatile noexcept 00076 { return _M_base.load(); } 00077 00078 bool 00079 is_lock_free() const noexcept { return _M_base.is_lock_free(); } 00080 00081 bool 00082 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } 00083 00084 void 00085 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept 00086 { _M_base.store(__i, __m); } 00087 00088 void 00089 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept 00090 { _M_base.store(__i, __m); } 00091 00092 bool 00093 load(memory_order __m = memory_order_seq_cst) const noexcept 00094 { return _M_base.load(__m); } 00095 00096 bool 00097 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00098 { return _M_base.load(__m); } 00099 00100 bool 00101 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept 00102 { return _M_base.exchange(__i, __m); } 00103 00104 bool 00105 exchange(bool __i, 00106 memory_order __m = memory_order_seq_cst) volatile noexcept 00107 { return _M_base.exchange(__i, __m); } 00108 00109 bool 00110 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 00111 memory_order __m2) noexcept 00112 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 00113 00114 bool 00115 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 00116 memory_order __m2) volatile noexcept 00117 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 00118 00119 bool 00120 compare_exchange_weak(bool& __i1, bool __i2, 00121 memory_order __m = memory_order_seq_cst) noexcept 00122 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 00123 00124 bool 00125 compare_exchange_weak(bool& __i1, bool __i2, 00126 memory_order __m = memory_order_seq_cst) volatile noexcept 00127 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 00128 00129 bool 00130 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 00131 memory_order __m2) noexcept 00132 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 00133 00134 bool 00135 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 00136 memory_order __m2) volatile noexcept 00137 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 00138 00139 bool 00140 compare_exchange_strong(bool& __i1, bool __i2, 00141 memory_order __m = memory_order_seq_cst) noexcept 00142 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 00143 00144 bool 00145 compare_exchange_strong(bool& __i1, bool __i2, 00146 memory_order __m = memory_order_seq_cst) volatile noexcept 00147 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 00148 }; 00149 00150 00151 /** 00152 * @brief Generic atomic type, primary class template. 00153 * 00154 * @tparam _Tp Type to be made atomic, must be trivally copyable. 00155 */ 00156 template<typename _Tp> 00157 struct atomic 00158 { 00159 private: 00160 _Tp _M_i; 00161 00162 public: 00163 atomic() noexcept = default; 00164 ~atomic() noexcept = default; 00165 atomic(const atomic&) = delete; 00166 atomic& operator=(const atomic&) = delete; 00167 atomic& operator=(const atomic&) volatile = delete; 00168 00169 constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } 00170 00171 operator _Tp() const noexcept 00172 { return load(); } 00173 00174 operator _Tp() const volatile noexcept 00175 { return load(); } 00176 00177 _Tp 00178 operator=(_Tp __i) noexcept 00179 { store(__i); return __i; } 00180 00181 _Tp 00182 operator=(_Tp __i) volatile noexcept 00183 { store(__i); return __i; } 00184 00185 bool 00186 is_lock_free() const noexcept 00187 { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); } 00188 00189 bool 00190 is_lock_free() const volatile noexcept 00191 { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); } 00192 00193 void 00194 store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept 00195 { __atomic_store(&_M_i, &__i, _m); } 00196 00197 void 00198 store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept 00199 { __atomic_store(&_M_i, &__i, _m); } 00200 00201 _Tp 00202 load(memory_order _m = memory_order_seq_cst) const noexcept 00203 { 00204 _Tp tmp; 00205 __atomic_load(&_M_i, &tmp, _m); 00206 return tmp; 00207 } 00208 00209 _Tp 00210 load(memory_order _m = memory_order_seq_cst) const volatile noexcept 00211 { 00212 _Tp tmp; 00213 __atomic_load(&_M_i, &tmp, _m); 00214 return tmp; 00215 } 00216 00217 _Tp 00218 exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept 00219 { 00220 _Tp tmp; 00221 __atomic_exchange(&_M_i, &__i, &tmp, _m); 00222 return tmp; 00223 } 00224 00225 _Tp 00226 exchange(_Tp __i, 00227 memory_order _m = memory_order_seq_cst) volatile noexcept 00228 { 00229 _Tp tmp; 00230 __atomic_exchange(&_M_i, &__i, &tmp, _m); 00231 return tmp; 00232 } 00233 00234 bool 00235 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00236 memory_order __f) noexcept 00237 { 00238 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00239 } 00240 00241 bool 00242 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00243 memory_order __f) volatile noexcept 00244 { 00245 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00246 } 00247 00248 bool 00249 compare_exchange_weak(_Tp& __e, _Tp __i, 00250 memory_order __m = memory_order_seq_cst) noexcept 00251 { return compare_exchange_weak(__e, __i, __m, __m); } 00252 00253 bool 00254 compare_exchange_weak(_Tp& __e, _Tp __i, 00255 memory_order __m = memory_order_seq_cst) volatile noexcept 00256 { return compare_exchange_weak(__e, __i, __m, __m); } 00257 00258 bool 00259 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00260 memory_order __f) noexcept 00261 { 00262 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00263 } 00264 00265 bool 00266 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00267 memory_order __f) volatile noexcept 00268 { 00269 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00270 } 00271 00272 bool 00273 compare_exchange_strong(_Tp& __e, _Tp __i, 00274 memory_order __m = memory_order_seq_cst) noexcept 00275 { return compare_exchange_strong(__e, __i, __m, __m); } 00276 00277 bool 00278 compare_exchange_strong(_Tp& __e, _Tp __i, 00279 memory_order __m = memory_order_seq_cst) volatile noexcept 00280 { return compare_exchange_strong(__e, __i, __m, __m); } 00281 }; 00282 00283 00284 /// Partial specialization for pointer types. 00285 template<typename _Tp> 00286 struct atomic<_Tp*> 00287 { 00288 typedef _Tp* __pointer_type; 00289 typedef __atomic_base<_Tp*> __base_type; 00290 __base_type _M_b; 00291 00292 atomic() noexcept = default; 00293 ~atomic() noexcept = default; 00294 atomic(const atomic&) = delete; 00295 atomic& operator=(const atomic&) = delete; 00296 atomic& operator=(const atomic&) volatile = delete; 00297 00298 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 00299 00300 operator __pointer_type() const noexcept 00301 { return __pointer_type(_M_b); } 00302 00303 operator __pointer_type() const volatile noexcept 00304 { return __pointer_type(_M_b); } 00305 00306 __pointer_type 00307 operator=(__pointer_type __p) noexcept 00308 { return _M_b.operator=(__p); } 00309 00310 __pointer_type 00311 operator=(__pointer_type __p) volatile noexcept 00312 { return _M_b.operator=(__p); } 00313 00314 __pointer_type 00315 operator++(int) noexcept 00316 { return _M_b++; } 00317 00318 __pointer_type 00319 operator++(int) volatile noexcept 00320 { return _M_b++; } 00321 00322 __pointer_type 00323 operator--(int) noexcept 00324 { return _M_b--; } 00325 00326 __pointer_type 00327 operator--(int) volatile noexcept 00328 { return _M_b--; } 00329 00330 __pointer_type 00331 operator++() noexcept 00332 { return ++_M_b; } 00333 00334 __pointer_type 00335 operator++() volatile noexcept 00336 { return ++_M_b; } 00337 00338 __pointer_type 00339 operator--() noexcept 00340 { return --_M_b; } 00341 00342 __pointer_type 00343 operator--() volatile noexcept 00344 { return --_M_b; } 00345 00346 __pointer_type 00347 operator+=(ptrdiff_t __d) noexcept 00348 { return _M_b.operator+=(__d); } 00349 00350 __pointer_type 00351 operator+=(ptrdiff_t __d) volatile noexcept 00352 { return _M_b.operator+=(__d); } 00353 00354 __pointer_type 00355 operator-=(ptrdiff_t __d) noexcept 00356 { return _M_b.operator-=(__d); } 00357 00358 __pointer_type 00359 operator-=(ptrdiff_t __d) volatile noexcept 00360 { return _M_b.operator-=(__d); } 00361 00362 bool 00363 is_lock_free() const noexcept 00364 { return _M_b.is_lock_free(); } 00365 00366 bool 00367 is_lock_free() const volatile noexcept 00368 { return _M_b.is_lock_free(); } 00369 00370 void 00371 store(__pointer_type __p, 00372 memory_order __m = memory_order_seq_cst) noexcept 00373 { return _M_b.store(__p, __m); } 00374 00375 void 00376 store(__pointer_type __p, 00377 memory_order __m = memory_order_seq_cst) volatile noexcept 00378 { return _M_b.store(__p, __m); } 00379 00380 __pointer_type 00381 load(memory_order __m = memory_order_seq_cst) const noexcept 00382 { return _M_b.load(__m); } 00383 00384 __pointer_type 00385 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00386 { return _M_b.load(__m); } 00387 00388 __pointer_type 00389 exchange(__pointer_type __p, 00390 memory_order __m = memory_order_seq_cst) noexcept 00391 { return _M_b.exchange(__p, __m); } 00392 00393 __pointer_type 00394 exchange(__pointer_type __p, 00395 memory_order __m = memory_order_seq_cst) volatile noexcept 00396 { return _M_b.exchange(__p, __m); } 00397 00398 bool 00399 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00400 memory_order __m1, memory_order __m2) noexcept 00401 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00402 00403 bool 00404 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00405 memory_order __m1, 00406 memory_order __m2) volatile noexcept 00407 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00408 00409 bool 00410 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00411 memory_order __m = memory_order_seq_cst) noexcept 00412 { 00413 return compare_exchange_weak(__p1, __p2, __m, 00414 __cmpexch_failure_order(__m)); 00415 } 00416 00417 bool 00418 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00419 memory_order __m = memory_order_seq_cst) volatile noexcept 00420 { 00421 return compare_exchange_weak(__p1, __p2, __m, 00422 __cmpexch_failure_order(__m)); 00423 } 00424 00425 bool 00426 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00427 memory_order __m1, memory_order __m2) noexcept 00428 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00429 00430 bool 00431 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00432 memory_order __m1, 00433 memory_order __m2) volatile noexcept 00434 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00435 00436 bool 00437 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00438 memory_order __m = memory_order_seq_cst) noexcept 00439 { 00440 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00441 __cmpexch_failure_order(__m)); 00442 } 00443 00444 bool 00445 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00446 memory_order __m = memory_order_seq_cst) volatile noexcept 00447 { 00448 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00449 __cmpexch_failure_order(__m)); 00450 } 00451 00452 __pointer_type 00453 fetch_add(ptrdiff_t __d, 00454 memory_order __m = memory_order_seq_cst) noexcept 00455 { return _M_b.fetch_add(__d, __m); } 00456 00457 __pointer_type 00458 fetch_add(ptrdiff_t __d, 00459 memory_order __m = memory_order_seq_cst) volatile noexcept 00460 { return _M_b.fetch_add(__d, __m); } 00461 00462 __pointer_type 00463 fetch_sub(ptrdiff_t __d, 00464 memory_order __m = memory_order_seq_cst) noexcept 00465 { return _M_b.fetch_sub(__d, __m); } 00466 00467 __pointer_type 00468 fetch_sub(ptrdiff_t __d, 00469 memory_order __m = memory_order_seq_cst) volatile noexcept 00470 { return _M_b.fetch_sub(__d, __m); } 00471 }; 00472 00473 00474 /// Explicit specialization for bool. 00475 template<> 00476 struct atomic<bool> : public atomic_bool 00477 { 00478 typedef bool __integral_type; 00479 typedef atomic_bool __base_type; 00480 00481 atomic() noexcept = default; 00482 ~atomic() noexcept = default; 00483 atomic(const atomic&) = delete; 00484 atomic& operator=(const atomic&) = delete; 00485 atomic& operator=(const atomic&) volatile = delete; 00486 00487 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00488 00489 using __base_type::operator __integral_type; 00490 using __base_type::operator=; 00491 }; 00492 00493 /// Explicit specialization for char. 00494 template<> 00495 struct atomic<char> : public atomic_char 00496 { 00497 typedef char __integral_type; 00498 typedef atomic_char __base_type; 00499 00500 atomic() noexcept = default; 00501 ~atomic() noexcept = default; 00502 atomic(const atomic&) = delete; 00503 atomic& operator=(const atomic&) = delete; 00504 atomic& operator=(const atomic&) volatile = delete; 00505 00506 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00507 00508 using __base_type::operator __integral_type; 00509 using __base_type::operator=; 00510 }; 00511 00512 /// Explicit specialization for signed char. 00513 template<> 00514 struct atomic<signed char> : public atomic_schar 00515 { 00516 typedef signed char __integral_type; 00517 typedef atomic_schar __base_type; 00518 00519 atomic() noexcept= default; 00520 ~atomic() noexcept = default; 00521 atomic(const atomic&) = delete; 00522 atomic& operator=(const atomic&) = delete; 00523 atomic& operator=(const atomic&) volatile = delete; 00524 00525 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00526 00527 using __base_type::operator __integral_type; 00528 using __base_type::operator=; 00529 }; 00530 00531 /// Explicit specialization for unsigned char. 00532 template<> 00533 struct atomic<unsigned char> : public atomic_uchar 00534 { 00535 typedef unsigned char __integral_type; 00536 typedef atomic_uchar __base_type; 00537 00538 atomic() noexcept= default; 00539 ~atomic() noexcept = default; 00540 atomic(const atomic&) = delete; 00541 atomic& operator=(const atomic&) = delete; 00542 atomic& operator=(const atomic&) volatile = delete; 00543 00544 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00545 00546 using __base_type::operator __integral_type; 00547 using __base_type::operator=; 00548 }; 00549 00550 /// Explicit specialization for short. 00551 template<> 00552 struct atomic<short> : public atomic_short 00553 { 00554 typedef short __integral_type; 00555 typedef atomic_short __base_type; 00556 00557 atomic() noexcept = default; 00558 ~atomic() noexcept = default; 00559 atomic(const atomic&) = delete; 00560 atomic& operator=(const atomic&) = delete; 00561 atomic& operator=(const atomic&) volatile = delete; 00562 00563 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00564 00565 using __base_type::operator __integral_type; 00566 using __base_type::operator=; 00567 }; 00568 00569 /// Explicit specialization for unsigned short. 00570 template<> 00571 struct atomic<unsigned short> : public atomic_ushort 00572 { 00573 typedef unsigned short __integral_type; 00574 typedef atomic_ushort __base_type; 00575 00576 atomic() noexcept = default; 00577 ~atomic() noexcept = default; 00578 atomic(const atomic&) = delete; 00579 atomic& operator=(const atomic&) = delete; 00580 atomic& operator=(const atomic&) volatile = delete; 00581 00582 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00583 00584 using __base_type::operator __integral_type; 00585 using __base_type::operator=; 00586 }; 00587 00588 /// Explicit specialization for int. 00589 template<> 00590 struct atomic<int> : atomic_int 00591 { 00592 typedef int __integral_type; 00593 typedef atomic_int __base_type; 00594 00595 atomic() noexcept = default; 00596 ~atomic() noexcept = default; 00597 atomic(const atomic&) = delete; 00598 atomic& operator=(const atomic&) = delete; 00599 atomic& operator=(const atomic&) volatile = delete; 00600 00601 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00602 00603 using __base_type::operator __integral_type; 00604 using __base_type::operator=; 00605 }; 00606 00607 /// Explicit specialization for unsigned int. 00608 template<> 00609 struct atomic<unsigned int> : public atomic_uint 00610 { 00611 typedef unsigned int __integral_type; 00612 typedef atomic_uint __base_type; 00613 00614 atomic() noexcept = default; 00615 ~atomic() noexcept = default; 00616 atomic(const atomic&) = delete; 00617 atomic& operator=(const atomic&) = delete; 00618 atomic& operator=(const atomic&) volatile = delete; 00619 00620 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00621 00622 using __base_type::operator __integral_type; 00623 using __base_type::operator=; 00624 }; 00625 00626 /// Explicit specialization for long. 00627 template<> 00628 struct atomic<long> : public atomic_long 00629 { 00630 typedef long __integral_type; 00631 typedef atomic_long __base_type; 00632 00633 atomic() noexcept = default; 00634 ~atomic() noexcept = default; 00635 atomic(const atomic&) = delete; 00636 atomic& operator=(const atomic&) = delete; 00637 atomic& operator=(const atomic&) volatile = delete; 00638 00639 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00640 00641 using __base_type::operator __integral_type; 00642 using __base_type::operator=; 00643 }; 00644 00645 /// Explicit specialization for unsigned long. 00646 template<> 00647 struct atomic<unsigned long> : public atomic_ulong 00648 { 00649 typedef unsigned long __integral_type; 00650 typedef atomic_ulong __base_type; 00651 00652 atomic() noexcept = default; 00653 ~atomic() noexcept = default; 00654 atomic(const atomic&) = delete; 00655 atomic& operator=(const atomic&) = delete; 00656 atomic& operator=(const atomic&) volatile = delete; 00657 00658 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00659 00660 using __base_type::operator __integral_type; 00661 using __base_type::operator=; 00662 }; 00663 00664 /// Explicit specialization for long long. 00665 template<> 00666 struct atomic<long long> : public atomic_llong 00667 { 00668 typedef long long __integral_type; 00669 typedef atomic_llong __base_type; 00670 00671 atomic() noexcept = default; 00672 ~atomic() noexcept = default; 00673 atomic(const atomic&) = delete; 00674 atomic& operator=(const atomic&) = delete; 00675 atomic& operator=(const atomic&) volatile = delete; 00676 00677 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00678 00679 using __base_type::operator __integral_type; 00680 using __base_type::operator=; 00681 }; 00682 00683 /// Explicit specialization for unsigned long long. 00684 template<> 00685 struct atomic<unsigned long long> : public atomic_ullong 00686 { 00687 typedef unsigned long long __integral_type; 00688 typedef atomic_ullong __base_type; 00689 00690 atomic() noexcept = default; 00691 ~atomic() noexcept = default; 00692 atomic(const atomic&) = delete; 00693 atomic& operator=(const atomic&) = delete; 00694 atomic& operator=(const atomic&) volatile = delete; 00695 00696 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00697 00698 using __base_type::operator __integral_type; 00699 using __base_type::operator=; 00700 }; 00701 00702 /// Explicit specialization for wchar_t. 00703 template<> 00704 struct atomic<wchar_t> : public atomic_wchar_t 00705 { 00706 typedef wchar_t __integral_type; 00707 typedef atomic_wchar_t __base_type; 00708 00709 atomic() noexcept = default; 00710 ~atomic() noexcept = default; 00711 atomic(const atomic&) = delete; 00712 atomic& operator=(const atomic&) = delete; 00713 atomic& operator=(const atomic&) volatile = delete; 00714 00715 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00716 00717 using __base_type::operator __integral_type; 00718 using __base_type::operator=; 00719 }; 00720 00721 /// Explicit specialization for char16_t. 00722 template<> 00723 struct atomic<char16_t> : public atomic_char16_t 00724 { 00725 typedef char16_t __integral_type; 00726 typedef atomic_char16_t __base_type; 00727 00728 atomic() noexcept = default; 00729 ~atomic() noexcept = default; 00730 atomic(const atomic&) = delete; 00731 atomic& operator=(const atomic&) = delete; 00732 atomic& operator=(const atomic&) volatile = delete; 00733 00734 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00735 00736 using __base_type::operator __integral_type; 00737 using __base_type::operator=; 00738 }; 00739 00740 /// Explicit specialization for char32_t. 00741 template<> 00742 struct atomic<char32_t> : public atomic_char32_t 00743 { 00744 typedef char32_t __integral_type; 00745 typedef atomic_char32_t __base_type; 00746 00747 atomic() noexcept = default; 00748 ~atomic() noexcept = default; 00749 atomic(const atomic&) = delete; 00750 atomic& operator=(const atomic&) = delete; 00751 atomic& operator=(const atomic&) volatile = delete; 00752 00753 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00754 00755 using __base_type::operator __integral_type; 00756 using __base_type::operator=; 00757 }; 00758 00759 00760 // Function definitions, atomic_flag operations. 00761 inline bool 00762 atomic_flag_test_and_set_explicit(atomic_flag* __a, 00763 memory_order __m) noexcept 00764 { return __a->test_and_set(__m); } 00765 00766 inline bool 00767 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 00768 memory_order __m) noexcept 00769 { return __a->test_and_set(__m); } 00770 00771 inline void 00772 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 00773 { __a->clear(__m); } 00774 00775 inline void 00776 atomic_flag_clear_explicit(volatile atomic_flag* __a, 00777 memory_order __m) noexcept 00778 { __a->clear(__m); } 00779 00780 inline bool 00781 atomic_flag_test_and_set(atomic_flag* __a) noexcept 00782 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00783 00784 inline bool 00785 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 00786 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00787 00788 inline void 00789 atomic_flag_clear(atomic_flag* __a) noexcept 00790 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00791 00792 inline void 00793 atomic_flag_clear(volatile atomic_flag* __a) noexcept 00794 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00795 00796 00797 // Function templates generally applicable to atomic types. 00798 template<typename _ITp> 00799 inline bool 00800 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 00801 { return __a->is_lock_free(); } 00802 00803 template<typename _ITp> 00804 inline bool 00805 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 00806 { return __a->is_lock_free(); } 00807 00808 template<typename _ITp> 00809 inline void 00810 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept; 00811 00812 template<typename _ITp> 00813 inline void 00814 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept; 00815 00816 template<typename _ITp> 00817 inline void 00818 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 00819 memory_order __m) noexcept 00820 { __a->store(__i, __m); } 00821 00822 template<typename _ITp> 00823 inline void 00824 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00825 memory_order __m) noexcept 00826 { __a->store(__i, __m); } 00827 00828 template<typename _ITp> 00829 inline _ITp 00830 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 00831 { return __a->load(__m); } 00832 00833 template<typename _ITp> 00834 inline _ITp 00835 atomic_load_explicit(const volatile atomic<_ITp>* __a, 00836 memory_order __m) noexcept 00837 { return __a->load(__m); } 00838 00839 template<typename _ITp> 00840 inline _ITp 00841 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 00842 memory_order __m) noexcept 00843 { return __a->exchange(__i, __m); } 00844 00845 template<typename _ITp> 00846 inline _ITp 00847 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00848 memory_order __m) noexcept 00849 { return __a->exchange(__i, __m); } 00850 00851 template<typename _ITp> 00852 inline bool 00853 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 00854 _ITp* __i1, _ITp __i2, 00855 memory_order __m1, 00856 memory_order __m2) noexcept 00857 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00858 00859 template<typename _ITp> 00860 inline bool 00861 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 00862 _ITp* __i1, _ITp __i2, 00863 memory_order __m1, 00864 memory_order __m2) noexcept 00865 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00866 00867 template<typename _ITp> 00868 inline bool 00869 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 00870 _ITp* __i1, _ITp __i2, 00871 memory_order __m1, 00872 memory_order __m2) noexcept 00873 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00874 00875 template<typename _ITp> 00876 inline bool 00877 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 00878 _ITp* __i1, _ITp __i2, 00879 memory_order __m1, 00880 memory_order __m2) noexcept 00881 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00882 00883 00884 template<typename _ITp> 00885 inline void 00886 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 00887 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00888 00889 template<typename _ITp> 00890 inline void 00891 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00892 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00893 00894 template<typename _ITp> 00895 inline _ITp 00896 atomic_load(const atomic<_ITp>* __a) noexcept 00897 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00898 00899 template<typename _ITp> 00900 inline _ITp 00901 atomic_load(const volatile atomic<_ITp>* __a) noexcept 00902 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00903 00904 template<typename _ITp> 00905 inline _ITp 00906 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 00907 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00908 00909 template<typename _ITp> 00910 inline _ITp 00911 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00912 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00913 00914 template<typename _ITp> 00915 inline bool 00916 atomic_compare_exchange_weak(atomic<_ITp>* __a, 00917 _ITp* __i1, _ITp __i2) noexcept 00918 { 00919 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00920 memory_order_seq_cst, 00921 memory_order_seq_cst); 00922 } 00923 00924 template<typename _ITp> 00925 inline bool 00926 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 00927 _ITp* __i1, _ITp __i2) noexcept 00928 { 00929 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00930 memory_order_seq_cst, 00931 memory_order_seq_cst); 00932 } 00933 00934 template<typename _ITp> 00935 inline bool 00936 atomic_compare_exchange_strong(atomic<_ITp>* __a, 00937 _ITp* __i1, _ITp __i2) noexcept 00938 { 00939 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00940 memory_order_seq_cst, 00941 memory_order_seq_cst); 00942 } 00943 00944 template<typename _ITp> 00945 inline bool 00946 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 00947 _ITp* __i1, _ITp __i2) noexcept 00948 { 00949 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00950 memory_order_seq_cst, 00951 memory_order_seq_cst); 00952 } 00953 00954 // Function templates for atomic_integral operations only, using 00955 // __atomic_base. Template argument should be constricted to 00956 // intergral types as specified in the standard, excluding address 00957 // types. 00958 template<typename _ITp> 00959 inline _ITp 00960 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00961 memory_order __m) noexcept 00962 { return __a->fetch_add(__i, __m); } 00963 00964 template<typename _ITp> 00965 inline _ITp 00966 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00967 memory_order __m) noexcept 00968 { return __a->fetch_add(__i, __m); } 00969 00970 template<typename _ITp> 00971 inline _ITp 00972 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00973 memory_order __m) noexcept 00974 { return __a->fetch_sub(__i, __m); } 00975 00976 template<typename _ITp> 00977 inline _ITp 00978 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00979 memory_order __m) noexcept 00980 { return __a->fetch_sub(__i, __m); } 00981 00982 template<typename _ITp> 00983 inline _ITp 00984 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00985 memory_order __m) noexcept 00986 { return __a->fetch_and(__i, __m); } 00987 00988 template<typename _ITp> 00989 inline _ITp 00990 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00991 memory_order __m) noexcept 00992 { return __a->fetch_and(__i, __m); } 00993 00994 template<typename _ITp> 00995 inline _ITp 00996 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00997 memory_order __m) noexcept 00998 { return __a->fetch_or(__i, __m); } 00999 01000 template<typename _ITp> 01001 inline _ITp 01002 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01003 memory_order __m) noexcept 01004 { return __a->fetch_or(__i, __m); } 01005 01006 template<typename _ITp> 01007 inline _ITp 01008 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01009 memory_order __m) noexcept 01010 { return __a->fetch_xor(__i, __m); } 01011 01012 template<typename _ITp> 01013 inline _ITp 01014 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01015 memory_order __m) noexcept 01016 { return __a->fetch_xor(__i, __m); } 01017 01018 template<typename _ITp> 01019 inline _ITp 01020 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01021 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01022 01023 template<typename _ITp> 01024 inline _ITp 01025 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01026 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01027 01028 template<typename _ITp> 01029 inline _ITp 01030 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01031 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01032 01033 template<typename _ITp> 01034 inline _ITp 01035 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01036 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01037 01038 template<typename _ITp> 01039 inline _ITp 01040 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01041 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01042 01043 template<typename _ITp> 01044 inline _ITp 01045 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01046 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01047 01048 template<typename _ITp> 01049 inline _ITp 01050 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01051 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01052 01053 template<typename _ITp> 01054 inline _ITp 01055 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01056 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01057 01058 template<typename _ITp> 01059 inline _ITp 01060 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01061 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01062 01063 template<typename _ITp> 01064 inline _ITp 01065 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01066 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01067 01068 01069 // Partial specializations for pointers. 01070 template<typename _ITp> 01071 inline _ITp* 01072 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01073 memory_order __m) noexcept 01074 { return __a->fetch_add(__d, __m); } 01075 01076 template<typename _ITp> 01077 inline _ITp* 01078 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 01079 memory_order __m) noexcept 01080 { return __a->fetch_add(__d, __m); } 01081 01082 template<typename _ITp> 01083 inline _ITp* 01084 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01085 { return __a->fetch_add(__d); } 01086 01087 template<typename _ITp> 01088 inline _ITp* 01089 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01090 { return __a->fetch_add(__d); } 01091 01092 template<typename _ITp> 01093 inline _ITp* 01094 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 01095 ptrdiff_t __d, memory_order __m) noexcept 01096 { return __a->fetch_sub(__d, __m); } 01097 01098 template<typename _ITp> 01099 inline _ITp* 01100 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01101 memory_order __m) noexcept 01102 { return __a->fetch_sub(__d, __m); } 01103 01104 template<typename _ITp> 01105 inline _ITp* 01106 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01107 { return __a->fetch_sub(__d); } 01108 01109 template<typename _ITp> 01110 inline _ITp* 01111 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01112 { return __a->fetch_sub(__d); } 01113 // @} group atomics 01114 01115 _GLIBCXX_END_NAMESPACE_VERSION 01116 } // namespace 01117 01118 #endif