libstdc++
|
00001 // -*- C++ -*- header. 00002 00003 // Copyright (C) 2008-2016 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 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 00235 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 00236 __atomic_load(&_M_i, __ptr, __m); 00237 return *__ptr; 00238 } 00239 00240 _Tp 00241 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00242 { 00243 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 00244 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 00245 __atomic_load(&_M_i, __ptr, __m); 00246 return *__ptr; 00247 } 00248 00249 _Tp 00250 exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept 00251 { 00252 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 00253 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 00254 __atomic_exchange(&_M_i, &__i, __ptr, __m); 00255 return *__ptr; 00256 } 00257 00258 _Tp 00259 exchange(_Tp __i, 00260 memory_order __m = memory_order_seq_cst) volatile noexcept 00261 { 00262 alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 00263 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 00264 __atomic_exchange(&_M_i, &__i, __ptr, __m); 00265 return *__ptr; 00266 } 00267 00268 bool 00269 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00270 memory_order __f) noexcept 00271 { 00272 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00273 } 00274 00275 bool 00276 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 00277 memory_order __f) volatile noexcept 00278 { 00279 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 00280 } 00281 00282 bool 00283 compare_exchange_weak(_Tp& __e, _Tp __i, 00284 memory_order __m = memory_order_seq_cst) noexcept 00285 { return compare_exchange_weak(__e, __i, __m, 00286 __cmpexch_failure_order(__m)); } 00287 00288 bool 00289 compare_exchange_weak(_Tp& __e, _Tp __i, 00290 memory_order __m = memory_order_seq_cst) volatile noexcept 00291 { return compare_exchange_weak(__e, __i, __m, 00292 __cmpexch_failure_order(__m)); } 00293 00294 bool 00295 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00296 memory_order __f) noexcept 00297 { 00298 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00299 } 00300 00301 bool 00302 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 00303 memory_order __f) volatile noexcept 00304 { 00305 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 00306 } 00307 00308 bool 00309 compare_exchange_strong(_Tp& __e, _Tp __i, 00310 memory_order __m = memory_order_seq_cst) noexcept 00311 { return compare_exchange_strong(__e, __i, __m, 00312 __cmpexch_failure_order(__m)); } 00313 00314 bool 00315 compare_exchange_strong(_Tp& __e, _Tp __i, 00316 memory_order __m = memory_order_seq_cst) volatile noexcept 00317 { return compare_exchange_strong(__e, __i, __m, 00318 __cmpexch_failure_order(__m)); } 00319 }; 00320 00321 00322 /// Partial specialization for pointer types. 00323 template<typename _Tp> 00324 struct atomic<_Tp*> 00325 { 00326 typedef _Tp* __pointer_type; 00327 typedef __atomic_base<_Tp*> __base_type; 00328 __base_type _M_b; 00329 00330 atomic() noexcept = default; 00331 ~atomic() noexcept = default; 00332 atomic(const atomic&) = delete; 00333 atomic& operator=(const atomic&) = delete; 00334 atomic& operator=(const atomic&) volatile = delete; 00335 00336 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 00337 00338 operator __pointer_type() const noexcept 00339 { return __pointer_type(_M_b); } 00340 00341 operator __pointer_type() const volatile noexcept 00342 { return __pointer_type(_M_b); } 00343 00344 __pointer_type 00345 operator=(__pointer_type __p) noexcept 00346 { return _M_b.operator=(__p); } 00347 00348 __pointer_type 00349 operator=(__pointer_type __p) volatile noexcept 00350 { return _M_b.operator=(__p); } 00351 00352 __pointer_type 00353 operator++(int) noexcept 00354 { return _M_b++; } 00355 00356 __pointer_type 00357 operator++(int) volatile noexcept 00358 { return _M_b++; } 00359 00360 __pointer_type 00361 operator--(int) noexcept 00362 { return _M_b--; } 00363 00364 __pointer_type 00365 operator--(int) volatile noexcept 00366 { return _M_b--; } 00367 00368 __pointer_type 00369 operator++() noexcept 00370 { return ++_M_b; } 00371 00372 __pointer_type 00373 operator++() volatile noexcept 00374 { return ++_M_b; } 00375 00376 __pointer_type 00377 operator--() noexcept 00378 { return --_M_b; } 00379 00380 __pointer_type 00381 operator--() volatile noexcept 00382 { return --_M_b; } 00383 00384 __pointer_type 00385 operator+=(ptrdiff_t __d) noexcept 00386 { return _M_b.operator+=(__d); } 00387 00388 __pointer_type 00389 operator+=(ptrdiff_t __d) volatile noexcept 00390 { return _M_b.operator+=(__d); } 00391 00392 __pointer_type 00393 operator-=(ptrdiff_t __d) noexcept 00394 { return _M_b.operator-=(__d); } 00395 00396 __pointer_type 00397 operator-=(ptrdiff_t __d) volatile noexcept 00398 { return _M_b.operator-=(__d); } 00399 00400 bool 00401 is_lock_free() const noexcept 00402 { return _M_b.is_lock_free(); } 00403 00404 bool 00405 is_lock_free() const volatile noexcept 00406 { return _M_b.is_lock_free(); } 00407 00408 void 00409 store(__pointer_type __p, 00410 memory_order __m = memory_order_seq_cst) noexcept 00411 { return _M_b.store(__p, __m); } 00412 00413 void 00414 store(__pointer_type __p, 00415 memory_order __m = memory_order_seq_cst) volatile noexcept 00416 { return _M_b.store(__p, __m); } 00417 00418 __pointer_type 00419 load(memory_order __m = memory_order_seq_cst) const noexcept 00420 { return _M_b.load(__m); } 00421 00422 __pointer_type 00423 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 00424 { return _M_b.load(__m); } 00425 00426 __pointer_type 00427 exchange(__pointer_type __p, 00428 memory_order __m = memory_order_seq_cst) noexcept 00429 { return _M_b.exchange(__p, __m); } 00430 00431 __pointer_type 00432 exchange(__pointer_type __p, 00433 memory_order __m = memory_order_seq_cst) volatile noexcept 00434 { return _M_b.exchange(__p, __m); } 00435 00436 bool 00437 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00438 memory_order __m1, memory_order __m2) noexcept 00439 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00440 00441 bool 00442 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00443 memory_order __m1, 00444 memory_order __m2) volatile noexcept 00445 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00446 00447 bool 00448 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00449 memory_order __m = memory_order_seq_cst) noexcept 00450 { 00451 return compare_exchange_weak(__p1, __p2, __m, 00452 __cmpexch_failure_order(__m)); 00453 } 00454 00455 bool 00456 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00457 memory_order __m = memory_order_seq_cst) volatile noexcept 00458 { 00459 return compare_exchange_weak(__p1, __p2, __m, 00460 __cmpexch_failure_order(__m)); 00461 } 00462 00463 bool 00464 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00465 memory_order __m1, memory_order __m2) noexcept 00466 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00467 00468 bool 00469 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00470 memory_order __m1, 00471 memory_order __m2) volatile noexcept 00472 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00473 00474 bool 00475 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00476 memory_order __m = memory_order_seq_cst) noexcept 00477 { 00478 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00479 __cmpexch_failure_order(__m)); 00480 } 00481 00482 bool 00483 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00484 memory_order __m = memory_order_seq_cst) volatile noexcept 00485 { 00486 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00487 __cmpexch_failure_order(__m)); 00488 } 00489 00490 __pointer_type 00491 fetch_add(ptrdiff_t __d, 00492 memory_order __m = memory_order_seq_cst) noexcept 00493 { return _M_b.fetch_add(__d, __m); } 00494 00495 __pointer_type 00496 fetch_add(ptrdiff_t __d, 00497 memory_order __m = memory_order_seq_cst) volatile noexcept 00498 { return _M_b.fetch_add(__d, __m); } 00499 00500 __pointer_type 00501 fetch_sub(ptrdiff_t __d, 00502 memory_order __m = memory_order_seq_cst) noexcept 00503 { return _M_b.fetch_sub(__d, __m); } 00504 00505 __pointer_type 00506 fetch_sub(ptrdiff_t __d, 00507 memory_order __m = memory_order_seq_cst) volatile noexcept 00508 { return _M_b.fetch_sub(__d, __m); } 00509 }; 00510 00511 00512 /// Explicit specialization for char. 00513 template<> 00514 struct atomic<char> : __atomic_base<char> 00515 { 00516 typedef char __integral_type; 00517 typedef __atomic_base<char> __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 signed char. 00532 template<> 00533 struct atomic<signed char> : __atomic_base<signed char> 00534 { 00535 typedef signed char __integral_type; 00536 typedef __atomic_base<signed char> __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 unsigned char. 00551 template<> 00552 struct atomic<unsigned char> : __atomic_base<unsigned char> 00553 { 00554 typedef unsigned char __integral_type; 00555 typedef __atomic_base<unsigned char> __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 short. 00570 template<> 00571 struct atomic<short> : __atomic_base<short> 00572 { 00573 typedef short __integral_type; 00574 typedef __atomic_base<short> __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 unsigned short. 00589 template<> 00590 struct atomic<unsigned short> : __atomic_base<unsigned short> 00591 { 00592 typedef unsigned short __integral_type; 00593 typedef __atomic_base<unsigned short> __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 int. 00608 template<> 00609 struct atomic<int> : __atomic_base<int> 00610 { 00611 typedef int __integral_type; 00612 typedef __atomic_base<int> __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 unsigned int. 00627 template<> 00628 struct atomic<unsigned int> : __atomic_base<unsigned int> 00629 { 00630 typedef unsigned int __integral_type; 00631 typedef __atomic_base<unsigned int> __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 long. 00646 template<> 00647 struct atomic<long> : __atomic_base<long> 00648 { 00649 typedef long __integral_type; 00650 typedef __atomic_base<long> __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 unsigned long. 00665 template<> 00666 struct atomic<unsigned long> : __atomic_base<unsigned long> 00667 { 00668 typedef unsigned long __integral_type; 00669 typedef __atomic_base<unsigned long> __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 long long. 00684 template<> 00685 struct atomic<long long> : __atomic_base<long long> 00686 { 00687 typedef long long __integral_type; 00688 typedef __atomic_base<long long> __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 unsigned long long. 00703 template<> 00704 struct atomic<unsigned long long> : __atomic_base<unsigned long long> 00705 { 00706 typedef unsigned long long __integral_type; 00707 typedef __atomic_base<unsigned long long> __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 wchar_t. 00722 template<> 00723 struct atomic<wchar_t> : __atomic_base<wchar_t> 00724 { 00725 typedef wchar_t __integral_type; 00726 typedef __atomic_base<wchar_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 char16_t. 00741 template<> 00742 struct atomic<char16_t> : __atomic_base<char16_t> 00743 { 00744 typedef char16_t __integral_type; 00745 typedef __atomic_base<char16_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 /// Explicit specialization for char32_t. 00760 template<> 00761 struct atomic<char32_t> : __atomic_base<char32_t> 00762 { 00763 typedef char32_t __integral_type; 00764 typedef __atomic_base<char32_t> __base_type; 00765 00766 atomic() noexcept = default; 00767 ~atomic() noexcept = default; 00768 atomic(const atomic&) = delete; 00769 atomic& operator=(const atomic&) = delete; 00770 atomic& operator=(const atomic&) volatile = delete; 00771 00772 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 00773 00774 using __base_type::operator __integral_type; 00775 using __base_type::operator=; 00776 }; 00777 00778 00779 /// atomic_bool 00780 typedef atomic<bool> atomic_bool; 00781 00782 /// atomic_char 00783 typedef atomic<char> atomic_char; 00784 00785 /// atomic_schar 00786 typedef atomic<signed char> atomic_schar; 00787 00788 /// atomic_uchar 00789 typedef atomic<unsigned char> atomic_uchar; 00790 00791 /// atomic_short 00792 typedef atomic<short> atomic_short; 00793 00794 /// atomic_ushort 00795 typedef atomic<unsigned short> atomic_ushort; 00796 00797 /// atomic_int 00798 typedef atomic<int> atomic_int; 00799 00800 /// atomic_uint 00801 typedef atomic<unsigned int> atomic_uint; 00802 00803 /// atomic_long 00804 typedef atomic<long> atomic_long; 00805 00806 /// atomic_ulong 00807 typedef atomic<unsigned long> atomic_ulong; 00808 00809 /// atomic_llong 00810 typedef atomic<long long> atomic_llong; 00811 00812 /// atomic_ullong 00813 typedef atomic<unsigned long long> atomic_ullong; 00814 00815 /// atomic_wchar_t 00816 typedef atomic<wchar_t> atomic_wchar_t; 00817 00818 /// atomic_char16_t 00819 typedef atomic<char16_t> atomic_char16_t; 00820 00821 /// atomic_char32_t 00822 typedef atomic<char32_t> atomic_char32_t; 00823 00824 00825 /// atomic_int_least8_t 00826 typedef atomic<int_least8_t> atomic_int_least8_t; 00827 00828 /// atomic_uint_least8_t 00829 typedef atomic<uint_least8_t> atomic_uint_least8_t; 00830 00831 /// atomic_int_least16_t 00832 typedef atomic<int_least16_t> atomic_int_least16_t; 00833 00834 /// atomic_uint_least16_t 00835 typedef atomic<uint_least16_t> atomic_uint_least16_t; 00836 00837 /// atomic_int_least32_t 00838 typedef atomic<int_least32_t> atomic_int_least32_t; 00839 00840 /// atomic_uint_least32_t 00841 typedef atomic<uint_least32_t> atomic_uint_least32_t; 00842 00843 /// atomic_int_least64_t 00844 typedef atomic<int_least64_t> atomic_int_least64_t; 00845 00846 /// atomic_uint_least64_t 00847 typedef atomic<uint_least64_t> atomic_uint_least64_t; 00848 00849 00850 /// atomic_int_fast8_t 00851 typedef atomic<int_fast8_t> atomic_int_fast8_t; 00852 00853 /// atomic_uint_fast8_t 00854 typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 00855 00856 /// atomic_int_fast16_t 00857 typedef atomic<int_fast16_t> atomic_int_fast16_t; 00858 00859 /// atomic_uint_fast16_t 00860 typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 00861 00862 /// atomic_int_fast32_t 00863 typedef atomic<int_fast32_t> atomic_int_fast32_t; 00864 00865 /// atomic_uint_fast32_t 00866 typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 00867 00868 /// atomic_int_fast64_t 00869 typedef atomic<int_fast64_t> atomic_int_fast64_t; 00870 00871 /// atomic_uint_fast64_t 00872 typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 00873 00874 00875 /// atomic_intptr_t 00876 typedef atomic<intptr_t> atomic_intptr_t; 00877 00878 /// atomic_uintptr_t 00879 typedef atomic<uintptr_t> atomic_uintptr_t; 00880 00881 /// atomic_size_t 00882 typedef atomic<size_t> atomic_size_t; 00883 00884 /// atomic_intmax_t 00885 typedef atomic<intmax_t> atomic_intmax_t; 00886 00887 /// atomic_uintmax_t 00888 typedef atomic<uintmax_t> atomic_uintmax_t; 00889 00890 /// atomic_ptrdiff_t 00891 typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 00892 00893 00894 // Function definitions, atomic_flag operations. 00895 inline bool 00896 atomic_flag_test_and_set_explicit(atomic_flag* __a, 00897 memory_order __m) noexcept 00898 { return __a->test_and_set(__m); } 00899 00900 inline bool 00901 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 00902 memory_order __m) noexcept 00903 { return __a->test_and_set(__m); } 00904 00905 inline void 00906 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 00907 { __a->clear(__m); } 00908 00909 inline void 00910 atomic_flag_clear_explicit(volatile atomic_flag* __a, 00911 memory_order __m) noexcept 00912 { __a->clear(__m); } 00913 00914 inline bool 00915 atomic_flag_test_and_set(atomic_flag* __a) noexcept 00916 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00917 00918 inline bool 00919 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 00920 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00921 00922 inline void 00923 atomic_flag_clear(atomic_flag* __a) noexcept 00924 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00925 00926 inline void 00927 atomic_flag_clear(volatile atomic_flag* __a) noexcept 00928 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00929 00930 00931 // Function templates generally applicable to atomic types. 00932 template<typename _ITp> 00933 inline bool 00934 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 00935 { return __a->is_lock_free(); } 00936 00937 template<typename _ITp> 00938 inline bool 00939 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 00940 { return __a->is_lock_free(); } 00941 00942 template<typename _ITp> 00943 inline void 00944 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept 00945 { __a->store(__i, memory_order_relaxed); } 00946 00947 template<typename _ITp> 00948 inline void 00949 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept 00950 { __a->store(__i, memory_order_relaxed); } 00951 00952 template<typename _ITp> 00953 inline void 00954 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 00955 memory_order __m) noexcept 00956 { __a->store(__i, __m); } 00957 00958 template<typename _ITp> 00959 inline void 00960 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00961 memory_order __m) noexcept 00962 { __a->store(__i, __m); } 00963 00964 template<typename _ITp> 00965 inline _ITp 00966 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 00967 { return __a->load(__m); } 00968 00969 template<typename _ITp> 00970 inline _ITp 00971 atomic_load_explicit(const volatile atomic<_ITp>* __a, 00972 memory_order __m) noexcept 00973 { return __a->load(__m); } 00974 00975 template<typename _ITp> 00976 inline _ITp 00977 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 00978 memory_order __m) noexcept 00979 { return __a->exchange(__i, __m); } 00980 00981 template<typename _ITp> 00982 inline _ITp 00983 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00984 memory_order __m) noexcept 00985 { return __a->exchange(__i, __m); } 00986 00987 template<typename _ITp> 00988 inline bool 00989 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 00990 _ITp* __i1, _ITp __i2, 00991 memory_order __m1, 00992 memory_order __m2) noexcept 00993 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00994 00995 template<typename _ITp> 00996 inline bool 00997 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 00998 _ITp* __i1, _ITp __i2, 00999 memory_order __m1, 01000 memory_order __m2) noexcept 01001 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 01002 01003 template<typename _ITp> 01004 inline bool 01005 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 01006 _ITp* __i1, _ITp __i2, 01007 memory_order __m1, 01008 memory_order __m2) noexcept 01009 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 01010 01011 template<typename _ITp> 01012 inline bool 01013 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 01014 _ITp* __i1, _ITp __i2, 01015 memory_order __m1, 01016 memory_order __m2) noexcept 01017 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 01018 01019 01020 template<typename _ITp> 01021 inline void 01022 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 01023 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 01024 01025 template<typename _ITp> 01026 inline void 01027 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 01028 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 01029 01030 template<typename _ITp> 01031 inline _ITp 01032 atomic_load(const atomic<_ITp>* __a) noexcept 01033 { return atomic_load_explicit(__a, memory_order_seq_cst); } 01034 01035 template<typename _ITp> 01036 inline _ITp 01037 atomic_load(const volatile atomic<_ITp>* __a) noexcept 01038 { return atomic_load_explicit(__a, memory_order_seq_cst); } 01039 01040 template<typename _ITp> 01041 inline _ITp 01042 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 01043 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 01044 01045 template<typename _ITp> 01046 inline _ITp 01047 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 01048 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 01049 01050 template<typename _ITp> 01051 inline bool 01052 atomic_compare_exchange_weak(atomic<_ITp>* __a, 01053 _ITp* __i1, _ITp __i2) noexcept 01054 { 01055 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 01056 memory_order_seq_cst, 01057 memory_order_seq_cst); 01058 } 01059 01060 template<typename _ITp> 01061 inline bool 01062 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 01063 _ITp* __i1, _ITp __i2) noexcept 01064 { 01065 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 01066 memory_order_seq_cst, 01067 memory_order_seq_cst); 01068 } 01069 01070 template<typename _ITp> 01071 inline bool 01072 atomic_compare_exchange_strong(atomic<_ITp>* __a, 01073 _ITp* __i1, _ITp __i2) noexcept 01074 { 01075 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 01076 memory_order_seq_cst, 01077 memory_order_seq_cst); 01078 } 01079 01080 template<typename _ITp> 01081 inline bool 01082 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 01083 _ITp* __i1, _ITp __i2) noexcept 01084 { 01085 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 01086 memory_order_seq_cst, 01087 memory_order_seq_cst); 01088 } 01089 01090 // Function templates for atomic_integral operations only, using 01091 // __atomic_base. Template argument should be constricted to 01092 // intergral types as specified in the standard, excluding address 01093 // types. 01094 template<typename _ITp> 01095 inline _ITp 01096 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01097 memory_order __m) noexcept 01098 { return __a->fetch_add(__i, __m); } 01099 01100 template<typename _ITp> 01101 inline _ITp 01102 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01103 memory_order __m) noexcept 01104 { return __a->fetch_add(__i, __m); } 01105 01106 template<typename _ITp> 01107 inline _ITp 01108 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01109 memory_order __m) noexcept 01110 { return __a->fetch_sub(__i, __m); } 01111 01112 template<typename _ITp> 01113 inline _ITp 01114 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01115 memory_order __m) noexcept 01116 { return __a->fetch_sub(__i, __m); } 01117 01118 template<typename _ITp> 01119 inline _ITp 01120 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01121 memory_order __m) noexcept 01122 { return __a->fetch_and(__i, __m); } 01123 01124 template<typename _ITp> 01125 inline _ITp 01126 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01127 memory_order __m) noexcept 01128 { return __a->fetch_and(__i, __m); } 01129 01130 template<typename _ITp> 01131 inline _ITp 01132 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01133 memory_order __m) noexcept 01134 { return __a->fetch_or(__i, __m); } 01135 01136 template<typename _ITp> 01137 inline _ITp 01138 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01139 memory_order __m) noexcept 01140 { return __a->fetch_or(__i, __m); } 01141 01142 template<typename _ITp> 01143 inline _ITp 01144 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 01145 memory_order __m) noexcept 01146 { return __a->fetch_xor(__i, __m); } 01147 01148 template<typename _ITp> 01149 inline _ITp 01150 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 01151 memory_order __m) noexcept 01152 { return __a->fetch_xor(__i, __m); } 01153 01154 template<typename _ITp> 01155 inline _ITp 01156 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01157 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01158 01159 template<typename _ITp> 01160 inline _ITp 01161 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01162 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 01163 01164 template<typename _ITp> 01165 inline _ITp 01166 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01167 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01168 01169 template<typename _ITp> 01170 inline _ITp 01171 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01172 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 01173 01174 template<typename _ITp> 01175 inline _ITp 01176 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01177 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01178 01179 template<typename _ITp> 01180 inline _ITp 01181 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01182 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 01183 01184 template<typename _ITp> 01185 inline _ITp 01186 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01187 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01188 01189 template<typename _ITp> 01190 inline _ITp 01191 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01192 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 01193 01194 template<typename _ITp> 01195 inline _ITp 01196 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 01197 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01198 01199 template<typename _ITp> 01200 inline _ITp 01201 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 01202 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01203 01204 01205 // Partial specializations for pointers. 01206 template<typename _ITp> 01207 inline _ITp* 01208 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01209 memory_order __m) noexcept 01210 { return __a->fetch_add(__d, __m); } 01211 01212 template<typename _ITp> 01213 inline _ITp* 01214 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 01215 memory_order __m) noexcept 01216 { return __a->fetch_add(__d, __m); } 01217 01218 template<typename _ITp> 01219 inline _ITp* 01220 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01221 { return __a->fetch_add(__d); } 01222 01223 template<typename _ITp> 01224 inline _ITp* 01225 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01226 { return __a->fetch_add(__d); } 01227 01228 template<typename _ITp> 01229 inline _ITp* 01230 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 01231 ptrdiff_t __d, memory_order __m) noexcept 01232 { return __a->fetch_sub(__d, __m); } 01233 01234 template<typename _ITp> 01235 inline _ITp* 01236 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01237 memory_order __m) noexcept 01238 { return __a->fetch_sub(__d, __m); } 01239 01240 template<typename _ITp> 01241 inline _ITp* 01242 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01243 { return __a->fetch_sub(__d); } 01244 01245 template<typename _ITp> 01246 inline _ITp* 01247 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 01248 { return __a->fetch_sub(__d); } 01249 // @} group atomics 01250 01251 _GLIBCXX_END_NAMESPACE_VERSION 01252 } // namespace 01253 01254 #endif // C++11 01255 01256 #endif // _GLIBCXX_ATOMIC