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