libstdc++
|
00001 // -*- C++ -*- header. 00002 00003 // Copyright (C) 2008, 2009 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /** @file cstdatomic 00027 * This is a Standard C++ Library file. You should @c #include this file 00028 * in your programs, rather than any of the "*.h" implementation files. 00029 * 00030 * This is the C++ version of the Standard C Library header @c stdatomic.h, 00031 * and its contents are (mostly) the same as that header, but are all 00032 * contained in the namespace @c std (except for names which are defined 00033 * as macros in C). 00034 */ 00035 00036 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. 00037 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html 00038 00039 #ifndef _GLIBCXX_STDATOMIC 00040 #define _GLIBCXX_STDATOMIC 1 00041 00042 #pragma GCC system_header 00043 00044 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00045 # include <c++0x_warning.h> 00046 #endif 00047 00048 #include <stdatomic.h> 00049 #include <cstddef> 00050 00051 _GLIBCXX_BEGIN_NAMESPACE(std) 00052 00053 /** 00054 * @addtogroup atomics 00055 * @{ 00056 */ 00057 00058 /// kill_dependency 00059 template<typename _Tp> 00060 inline _Tp 00061 kill_dependency(_Tp __y) 00062 { 00063 _Tp ret(__y); 00064 return ret; 00065 } 00066 00067 inline memory_order 00068 __calculate_memory_order(memory_order __m) 00069 { 00070 const bool __cond1 = __m == memory_order_release; 00071 const bool __cond2 = __m == memory_order_acq_rel; 00072 memory_order __mo1(__cond1 ? memory_order_relaxed : __m); 00073 memory_order __mo2(__cond2 ? memory_order_acquire : __mo1); 00074 return __mo2; 00075 } 00076 00077 // 00078 // Three nested namespaces for atomic implementation details. 00079 // 00080 // The nested namespace inlined into std:: is determined by the value 00081 // of the _GLIBCXX_ATOMIC_PROPERTY macro and the resulting 00082 // ATOMIC_*_LOCK_FREE macros. See file stdatomic.h. 00083 // 00084 // 0 == __atomic0 == Never lock-free 00085 // 1 == __atomic1 == Best available, sometimes lock-free 00086 // 2 == __atomic2 == Always lock-free 00087 #include <bits/atomic_0.h> 00088 #include <bits/atomic_2.h> 00089 00090 /// atomic 00091 /// 29.4.3, Generic atomic type, primary class template. 00092 template<typename _Tp> 00093 struct atomic 00094 { 00095 private: 00096 _Tp _M_i; 00097 00098 public: 00099 atomic() = default; 00100 ~atomic() = default; 00101 atomic(const atomic&) = delete; 00102 atomic& operator=(const atomic&) = delete; 00103 00104 atomic(_Tp __i) : _M_i(__i) { } 00105 00106 operator _Tp() const volatile; 00107 00108 _Tp 00109 operator=(_Tp __i) volatile { store(__i); return __i; } 00110 00111 bool 00112 is_lock_free() const volatile; 00113 00114 void 00115 store(_Tp, memory_order = memory_order_seq_cst) volatile; 00116 00117 _Tp 00118 load(memory_order = memory_order_seq_cst) const volatile; 00119 00120 _Tp 00121 exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile; 00122 00123 bool 00124 compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile; 00125 00126 bool 00127 compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile; 00128 00129 bool 00130 compare_exchange_weak(_Tp&, _Tp, 00131 memory_order = memory_order_seq_cst) volatile; 00132 00133 bool 00134 compare_exchange_strong(_Tp&, _Tp, 00135 memory_order = memory_order_seq_cst) volatile; 00136 }; 00137 00138 00139 /// Partial specialization for pointer types. 00140 template<typename _Tp> 00141 struct atomic<_Tp*> : atomic_address 00142 { 00143 atomic() = default; 00144 ~atomic() = default; 00145 atomic(const atomic&) = delete; 00146 atomic& operator=(const atomic&) = delete; 00147 00148 atomic(_Tp* __v) : atomic_address(__v) { } 00149 00150 void 00151 store(_Tp*, memory_order = memory_order_seq_cst) volatile; 00152 00153 _Tp* 00154 load(memory_order = memory_order_seq_cst) const volatile; 00155 00156 _Tp* 00157 exchange(_Tp*, memory_order = memory_order_seq_cst) volatile; 00158 00159 bool 00160 compare_exchange_weak(_Tp*&, _Tp*, memory_order, memory_order) volatile; 00161 00162 bool 00163 compare_exchange_strong(_Tp*&, _Tp*, memory_order, memory_order) volatile; 00164 00165 bool 00166 compare_exchange_weak(_Tp*&, _Tp*, 00167 memory_order = memory_order_seq_cst) volatile; 00168 00169 bool 00170 compare_exchange_strong(_Tp*&, _Tp*, 00171 memory_order = memory_order_seq_cst) volatile; 00172 00173 _Tp* 00174 fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 00175 00176 _Tp* 00177 fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 00178 00179 operator _Tp*() const volatile 00180 { return load(); } 00181 00182 _Tp* 00183 operator=(_Tp* __v) volatile 00184 { 00185 store(__v); 00186 return __v; 00187 } 00188 00189 _Tp* 00190 operator++(int) volatile { return fetch_add(1); } 00191 00192 _Tp* 00193 operator--(int) volatile { return fetch_sub(1); } 00194 00195 _Tp* 00196 operator++() volatile { return fetch_add(1) + 1; } 00197 00198 _Tp* 00199 operator--() volatile { return fetch_sub(1) - 1; } 00200 00201 _Tp* 00202 operator+=(ptrdiff_t __d) volatile 00203 { return fetch_add(__d) + __d; } 00204 00205 _Tp* 00206 operator-=(ptrdiff_t __d) volatile 00207 { return fetch_sub(__d) - __d; } 00208 }; 00209 00210 00211 /// Explicit specialization for void* 00212 template<> 00213 struct atomic<void*> : public atomic_address 00214 { 00215 typedef void* __integral_type; 00216 typedef atomic_address __base_type; 00217 00218 atomic() = default; 00219 ~atomic() = default; 00220 atomic(const atomic&) = delete; 00221 atomic& operator=(const atomic&) = delete; 00222 00223 atomic(__integral_type __i) : __base_type(__i) { } 00224 00225 using __base_type::operator __integral_type; 00226 using __base_type::operator=; 00227 }; 00228 00229 /// Explicit specialization for bool. 00230 template<> 00231 struct atomic<bool> : public atomic_bool 00232 { 00233 typedef bool __integral_type; 00234 typedef atomic_bool __base_type; 00235 00236 atomic() = default; 00237 ~atomic() = default; 00238 atomic(const atomic&) = delete; 00239 atomic& operator=(const atomic&) = delete; 00240 00241 atomic(__integral_type __i) : __base_type(__i) { } 00242 00243 using __base_type::operator __integral_type; 00244 using __base_type::operator=; 00245 }; 00246 00247 /// Explicit specialization for char. 00248 template<> 00249 struct atomic<char> : public atomic_char 00250 { 00251 typedef char __integral_type; 00252 typedef atomic_char __base_type; 00253 00254 atomic() = default; 00255 ~atomic() = default; 00256 atomic(const atomic&) = delete; 00257 atomic& operator=(const atomic&) = delete; 00258 00259 atomic(__integral_type __i) : __base_type(__i) { } 00260 00261 using __base_type::operator __integral_type; 00262 using __base_type::operator=; 00263 }; 00264 00265 /// Explicit specialization for signed char. 00266 template<> 00267 struct atomic<signed char> : public atomic_schar 00268 { 00269 typedef signed char __integral_type; 00270 typedef atomic_schar __base_type; 00271 00272 atomic() = default; 00273 ~atomic() = default; 00274 atomic(const atomic&) = delete; 00275 atomic& operator=(const atomic&) = delete; 00276 00277 atomic(__integral_type __i) : __base_type(__i) { } 00278 00279 using __base_type::operator __integral_type; 00280 using __base_type::operator=; 00281 }; 00282 00283 /// Explicit specialization for unsigned char. 00284 template<> 00285 struct atomic<unsigned char> : public atomic_uchar 00286 { 00287 typedef unsigned char __integral_type; 00288 typedef atomic_uchar __base_type; 00289 00290 atomic() = default; 00291 ~atomic() = default; 00292 atomic(const atomic&) = delete; 00293 atomic& operator=(const atomic&) = delete; 00294 00295 atomic(__integral_type __i) : __base_type(__i) { } 00296 00297 using __base_type::operator __integral_type; 00298 using __base_type::operator=; 00299 }; 00300 00301 /// Explicit specialization for short. 00302 template<> 00303 struct atomic<short> : public atomic_short 00304 { 00305 typedef short __integral_type; 00306 typedef atomic_short __base_type; 00307 00308 atomic() = default; 00309 ~atomic() = default; 00310 atomic(const atomic&) = delete; 00311 atomic& operator=(const atomic&) = delete; 00312 00313 atomic(__integral_type __i) : __base_type(__i) { } 00314 00315 using __base_type::operator __integral_type; 00316 using __base_type::operator=; 00317 }; 00318 00319 /// Explicit specialization for unsigned short. 00320 template<> 00321 struct atomic<unsigned short> : public atomic_ushort 00322 { 00323 typedef unsigned short __integral_type; 00324 typedef atomic_ushort __base_type; 00325 00326 atomic() = default; 00327 ~atomic() = default; 00328 atomic(const atomic&) = delete; 00329 atomic& operator=(const atomic&) = delete; 00330 00331 atomic(__integral_type __i) : __base_type(__i) { } 00332 00333 using __base_type::operator __integral_type; 00334 using __base_type::operator=; 00335 }; 00336 00337 /// Explicit specialization for int. 00338 template<> 00339 struct atomic<int> : atomic_int 00340 { 00341 typedef int __integral_type; 00342 typedef atomic_int __base_type; 00343 00344 atomic() = default; 00345 ~atomic() = default; 00346 atomic(const atomic&) = delete; 00347 atomic& operator=(const atomic&) = delete; 00348 00349 atomic(__integral_type __i) : __base_type(__i) { } 00350 00351 using __base_type::operator __integral_type; 00352 using __base_type::operator=; 00353 }; 00354 00355 /// Explicit specialization for unsigned int. 00356 template<> 00357 struct atomic<unsigned int> : public atomic_uint 00358 { 00359 typedef unsigned int __integral_type; 00360 typedef atomic_uint __base_type; 00361 00362 atomic() = default; 00363 ~atomic() = default; 00364 atomic(const atomic&) = delete; 00365 atomic& operator=(const atomic&) = delete; 00366 00367 atomic(__integral_type __i) : __base_type(__i) { } 00368 00369 using __base_type::operator __integral_type; 00370 using __base_type::operator=; 00371 }; 00372 00373 /// Explicit specialization for long. 00374 template<> 00375 struct atomic<long> : public atomic_long 00376 { 00377 typedef long __integral_type; 00378 typedef atomic_long __base_type; 00379 00380 atomic() = default; 00381 ~atomic() = default; 00382 atomic(const atomic&) = delete; 00383 atomic& operator=(const atomic&) = delete; 00384 00385 atomic(__integral_type __i) : __base_type(__i) { } 00386 00387 using __base_type::operator __integral_type; 00388 using __base_type::operator=; 00389 }; 00390 00391 /// Explicit specialization for unsigned long. 00392 template<> 00393 struct atomic<unsigned long> : public atomic_ulong 00394 { 00395 typedef unsigned long __integral_type; 00396 typedef atomic_ulong __base_type; 00397 00398 atomic() = default; 00399 ~atomic() = default; 00400 atomic(const atomic&) = delete; 00401 atomic& operator=(const atomic&) = delete; 00402 00403 atomic(__integral_type __i) : __base_type(__i) { } 00404 00405 using __base_type::operator __integral_type; 00406 using __base_type::operator=; 00407 }; 00408 00409 /// Explicit specialization for long long. 00410 template<> 00411 struct atomic<long long> : public atomic_llong 00412 { 00413 typedef long long __integral_type; 00414 typedef atomic_llong __base_type; 00415 00416 atomic() = default; 00417 ~atomic() = default; 00418 atomic(const atomic&) = delete; 00419 atomic& operator=(const atomic&) = delete; 00420 00421 atomic(__integral_type __i) : __base_type(__i) { } 00422 00423 using __base_type::operator __integral_type; 00424 using __base_type::operator=; 00425 }; 00426 00427 /// Explicit specialization for unsigned long long. 00428 template<> 00429 struct atomic<unsigned long long> : public atomic_ullong 00430 { 00431 typedef unsigned long long __integral_type; 00432 typedef atomic_ullong __base_type; 00433 00434 atomic() = default; 00435 ~atomic() = default; 00436 atomic(const atomic&) = delete; 00437 atomic& operator=(const atomic&) = delete; 00438 00439 atomic(__integral_type __i) : __base_type(__i) { } 00440 00441 using __base_type::operator __integral_type; 00442 using __base_type::operator=; 00443 }; 00444 00445 /// Explicit specialization for wchar_t. 00446 template<> 00447 struct atomic<wchar_t> : public atomic_wchar_t 00448 { 00449 typedef wchar_t __integral_type; 00450 typedef atomic_wchar_t __base_type; 00451 00452 atomic() = default; 00453 ~atomic() = default; 00454 atomic(const atomic&) = delete; 00455 atomic& operator=(const atomic&) = delete; 00456 00457 atomic(__integral_type __i) : __base_type(__i) { } 00458 00459 using __base_type::operator __integral_type; 00460 using __base_type::operator=; 00461 }; 00462 00463 /// Explicit specialization for char16_t. 00464 template<> 00465 struct atomic<char16_t> : public atomic_char16_t 00466 { 00467 typedef char16_t __integral_type; 00468 typedef atomic_char16_t __base_type; 00469 00470 atomic() = default; 00471 ~atomic() = default; 00472 atomic(const atomic&) = delete; 00473 atomic& operator=(const atomic&) = delete; 00474 00475 atomic(__integral_type __i) : __base_type(__i) { } 00476 00477 using __base_type::operator __integral_type; 00478 using __base_type::operator=; 00479 }; 00480 00481 /// Explicit specialization for char32_t. 00482 template<> 00483 struct atomic<char32_t> : public atomic_char32_t 00484 { 00485 typedef char32_t __integral_type; 00486 typedef atomic_char32_t __base_type; 00487 00488 atomic() = default; 00489 ~atomic() = default; 00490 atomic(const atomic&) = delete; 00491 atomic& operator=(const atomic&) = delete; 00492 00493 atomic(__integral_type __i) : __base_type(__i) { } 00494 00495 using __base_type::operator __integral_type; 00496 using __base_type::operator=; 00497 }; 00498 00499 00500 template<typename _Tp> 00501 _Tp* 00502 atomic<_Tp*>::load(memory_order __m) const volatile 00503 { return static_cast<_Tp*>(atomic_address::load(__m)); } 00504 00505 template<typename _Tp> 00506 _Tp* 00507 atomic<_Tp*>::exchange(_Tp* __v, memory_order __m) volatile 00508 { return static_cast<_Tp*>(atomic_address::exchange(__v, __m)); } 00509 00510 template<typename _Tp> 00511 bool 00512 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m1, 00513 memory_order __m2) volatile 00514 { 00515 void** __vr = reinterpret_cast<void**>(&__r); 00516 void* __vv = static_cast<void*>(__v); 00517 return atomic_address::compare_exchange_weak(*__vr, __vv, __m1, __m2); 00518 } 00519 00520 template<typename _Tp> 00521 bool 00522 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v, 00523 memory_order __m1, 00524 memory_order __m2) volatile 00525 { 00526 void** __vr = reinterpret_cast<void**>(&__r); 00527 void* __vv = static_cast<void*>(__v); 00528 return atomic_address::compare_exchange_strong(*__vr, __vv, __m1, __m2); 00529 } 00530 00531 template<typename _Tp> 00532 bool 00533 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, 00534 memory_order __m) volatile 00535 { 00536 return compare_exchange_weak(__r, __v, __m, 00537 __calculate_memory_order(__m)); 00538 } 00539 00540 template<typename _Tp> 00541 bool 00542 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v, 00543 memory_order __m) volatile 00544 { 00545 return compare_exchange_strong(__r, __v, __m, 00546 __calculate_memory_order(__m)); 00547 } 00548 00549 template<typename _Tp> 00550 _Tp* 00551 atomic<_Tp*>::fetch_add(ptrdiff_t __d, memory_order __m) volatile 00552 { 00553 void* __p = atomic_fetch_add_explicit(this, sizeof(_Tp) * __d, __m); 00554 return static_cast<_Tp*>(__p); 00555 } 00556 00557 template<typename _Tp> 00558 _Tp* 00559 atomic<_Tp*>::fetch_sub(ptrdiff_t __d, memory_order __m) volatile 00560 { 00561 void* __p = atomic_fetch_sub_explicit(this, sizeof(_Tp) * __d, __m); 00562 return static_cast<_Tp*>(__p); 00563 } 00564 00565 // Convenience function definitions, atomic_flag. 00566 inline bool 00567 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, memory_order __m) 00568 { return __a->test_and_set(__m); } 00569 00570 inline void 00571 atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m) 00572 { return __a->clear(__m); } 00573 00574 00575 // Convenience function definitions, atomic_address. 00576 inline bool 00577 atomic_is_lock_free(const volatile atomic_address* __a) 00578 { return __a->is_lock_free(); } 00579 00580 inline void 00581 atomic_store(volatile atomic_address* __a, void* __v) 00582 { __a->store(__v); } 00583 00584 inline void 00585 atomic_store_explicit(volatile atomic_address* __a, void* __v, 00586 memory_order __m) 00587 { __a->store(__v, __m); } 00588 00589 inline void* 00590 atomic_load(const volatile atomic_address* __a) 00591 { return __a->load(); } 00592 00593 inline void* 00594 atomic_load_explicit(const volatile atomic_address* __a, memory_order __m) 00595 { return __a->load(__m); } 00596 00597 inline void* 00598 atomic_exchange(volatile atomic_address* __a, void* __v) 00599 { return __a->exchange(__v); } 00600 00601 inline void* 00602 atomic_exchange_explicit(volatile atomic_address* __a, void* __v, 00603 memory_order __m) 00604 { return __a->exchange(__v, __m); } 00605 00606 inline bool 00607 atomic_compare_exchange_weak(volatile atomic_address* __a, 00608 void** __v1, void* __v2) 00609 { 00610 return __a->compare_exchange_weak(*__v1, __v2, memory_order_seq_cst, 00611 memory_order_seq_cst); 00612 } 00613 00614 inline bool 00615 atomic_compare_exchange_strong(volatile atomic_address* __a, 00616 void** __v1, void* __v2) 00617 { 00618 return __a->compare_exchange_strong(*__v1, __v2, memory_order_seq_cst, 00619 memory_order_seq_cst); 00620 } 00621 00622 inline bool 00623 atomic_compare_exchange_weak_explicit(volatile atomic_address* __a, 00624 void** __v1, void* __v2, 00625 memory_order __m1, memory_order __m2) 00626 { return __a->compare_exchange_weak(*__v1, __v2, __m1, __m2); } 00627 00628 inline bool 00629 atomic_compare_exchange_strong_explicit(volatile atomic_address* __a, 00630 void** __v1, void* __v2, 00631 memory_order __m1, memory_order __m2) 00632 { return __a->compare_exchange_strong(*__v1, __v2, __m1, __m2); } 00633 00634 inline void* 00635 atomic_fetch_add_explicit(volatile atomic_address* __a, ptrdiff_t __d, 00636 memory_order __m) 00637 { return __a->fetch_add(__d, __m); } 00638 00639 inline void* 00640 atomic_fetch_add(volatile atomic_address* __a, ptrdiff_t __d) 00641 { return __a->fetch_add(__d); } 00642 00643 inline void* 00644 atomic_fetch_sub_explicit(volatile atomic_address* __a, ptrdiff_t __d, 00645 memory_order __m) 00646 { return __a->fetch_sub(__d, __m); } 00647 00648 inline void* 00649 atomic_fetch_sub(volatile atomic_address* __a, ptrdiff_t __d) 00650 { return __a->fetch_sub(__d); } 00651 00652 00653 // Convenience function definitions, atomic_bool. 00654 inline bool 00655 atomic_is_lock_free(const volatile atomic_bool* __a) 00656 { return __a->is_lock_free(); } 00657 00658 inline void 00659 atomic_store(volatile atomic_bool* __a, bool __i) 00660 { __a->store(__i); } 00661 00662 inline void 00663 atomic_store_explicit(volatile atomic_bool* __a, bool __i, memory_order __m) 00664 { __a->store(__i, __m); } 00665 00666 inline bool 00667 atomic_load(const volatile atomic_bool* __a) 00668 { return __a->load(); } 00669 00670 inline bool 00671 atomic_load_explicit(const volatile atomic_bool* __a, memory_order __m) 00672 { return __a->load(__m); } 00673 00674 inline bool 00675 atomic_exchange(volatile atomic_bool* __a, bool __i) 00676 { return __a->exchange(__i); } 00677 00678 inline bool 00679 atomic_exchange_explicit(volatile atomic_bool* __a, bool __i, 00680 memory_order __m) 00681 { return __a->exchange(__i, __m); } 00682 00683 inline bool 00684 atomic_compare_exchange_weak(volatile atomic_bool* __a, bool* __i1, bool __i2) 00685 { 00686 return __a->compare_exchange_weak(*__i1, __i2, memory_order_seq_cst, 00687 memory_order_seq_cst); 00688 } 00689 00690 inline bool 00691 atomic_compare_exchange_strong(volatile atomic_bool* __a, 00692 bool* __i1, bool __i2) 00693 { 00694 return __a->compare_exchange_strong(*__i1, __i2, memory_order_seq_cst, 00695 memory_order_seq_cst); 00696 } 00697 00698 inline bool 00699 atomic_compare_exchange_weak_explicit(volatile atomic_bool* __a, bool* __i1, 00700 bool __i2, memory_order __m1, 00701 memory_order __m2) 00702 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00703 00704 inline bool 00705 atomic_compare_exchange_strong_explicit(volatile atomic_bool* __a, 00706 bool* __i1, bool __i2, 00707 memory_order __m1, memory_order __m2) 00708 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00709 00710 00711 00712 // Free standing functions. Template argument should be constricted 00713 // to intergral types as specified in the standard. 00714 template<typename _ITp> 00715 inline void 00716 atomic_store_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00717 memory_order __m) 00718 { __a->store(__i, __m); } 00719 00720 template<typename _ITp> 00721 inline _ITp 00722 atomic_load_explicit(const volatile __atomic_base<_ITp>* __a, 00723 memory_order __m) 00724 { return __a->load(__m); } 00725 00726 template<typename _ITp> 00727 inline _ITp 00728 atomic_exchange_explicit(volatile __atomic_base<_ITp>* __a, 00729 _ITp __i, memory_order __m) 00730 { return __a->exchange(__i, __m); } 00731 00732 template<typename _ITp> 00733 inline bool 00734 atomic_compare_exchange_weak_explicit(volatile __atomic_base<_ITp>* __a, 00735 _ITp* __i1, _ITp __i2, 00736 memory_order __m1, memory_order __m2) 00737 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00738 00739 template<typename _ITp> 00740 inline bool 00741 atomic_compare_exchange_strong_explicit(volatile __atomic_base<_ITp>* __a, 00742 _ITp* __i1, _ITp __i2, 00743 memory_order __m1, 00744 memory_order __m2) 00745 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00746 00747 template<typename _ITp> 00748 inline _ITp 00749 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00750 memory_order __m) 00751 { return __a->fetch_add(__i, __m); } 00752 00753 template<typename _ITp> 00754 inline _ITp 00755 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00756 memory_order __m) 00757 { return __a->fetch_sub(__i, __m); } 00758 00759 template<typename _ITp> 00760 inline _ITp 00761 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00762 memory_order __m) 00763 { return __a->fetch_and(__i, __m); } 00764 00765 template<typename _ITp> 00766 inline _ITp 00767 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00768 memory_order __m) 00769 { return __a->fetch_or(__i, __m); } 00770 00771 template<typename _ITp> 00772 inline _ITp 00773 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00774 memory_order __m) 00775 { return __a->fetch_xor(__i, __m); } 00776 00777 template<typename _ITp> 00778 inline bool 00779 atomic_is_lock_free(const volatile __atomic_base<_ITp>* __a) 00780 { return __a->is_lock_free(); } 00781 00782 template<typename _ITp> 00783 inline void 00784 atomic_store(volatile __atomic_base<_ITp>* __a, _ITp __i) 00785 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00786 00787 template<typename _ITp> 00788 inline _ITp 00789 atomic_load(const volatile __atomic_base<_ITp>* __a) 00790 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00791 00792 template<typename _ITp> 00793 inline _ITp 00794 atomic_exchange(volatile __atomic_base<_ITp>* __a, _ITp __i) 00795 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00796 00797 template<typename _ITp> 00798 inline bool 00799 atomic_compare_exchange_weak(volatile __atomic_base<_ITp>* __a, 00800 _ITp* __i1, _ITp __i2) 00801 { 00802 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00803 memory_order_seq_cst, 00804 memory_order_seq_cst); 00805 } 00806 00807 template<typename _ITp> 00808 inline bool 00809 atomic_compare_exchange_strong(volatile __atomic_base<_ITp>* __a, 00810 _ITp* __i1, _ITp __i2) 00811 { 00812 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00813 memory_order_seq_cst, 00814 memory_order_seq_cst); 00815 } 00816 00817 template<typename _ITp> 00818 inline _ITp 00819 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) 00820 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 00821 00822 template<typename _ITp> 00823 inline _ITp 00824 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) 00825 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 00826 00827 template<typename _ITp> 00828 inline _ITp 00829 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) 00830 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 00831 00832 template<typename _ITp> 00833 inline _ITp 00834 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) 00835 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 00836 00837 template<typename _ITp> 00838 inline _ITp 00839 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) 00840 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 00841 00842 // @} group atomics 00843 00844 _GLIBCXX_END_NAMESPACE 00845 00846 #endif 00847 00848