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