libstdc++
|
00001 // -*- C++ -*- header. 00002 00003 // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/atomic 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. 00030 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html 00031 00032 #ifndef _GLIBCXX_ATOMIC 00033 #define _GLIBCXX_ATOMIC 1 00034 00035 #pragma GCC system_header 00036 00037 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00038 # include <bits/c++0x_warning.h> 00039 #endif 00040 00041 #include <bits/atomic_base.h> 00042 #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*> 00234 { 00235 typedef _Tp* __pointer_type; 00236 typedef __atomic_base<_Tp*> __base_type; 00237 __base_type _M_b; 00238 00239 atomic() = default; 00240 ~atomic() = default; 00241 atomic(const atomic&) = delete; 00242 atomic& operator=(const atomic&) = delete; 00243 atomic& operator=(const atomic&) volatile = delete; 00244 00245 constexpr atomic(__pointer_type __p) : _M_b(__p) { } 00246 00247 operator __pointer_type() const 00248 { return __pointer_type(_M_b); } 00249 00250 operator __pointer_type() const volatile 00251 { return __pointer_type(_M_b); } 00252 00253 __pointer_type 00254 operator=(__pointer_type __p) 00255 { return _M_b.operator=(__p); } 00256 00257 __pointer_type 00258 operator=(__pointer_type __p) volatile 00259 { return _M_b.operator=(__p); } 00260 00261 __pointer_type 00262 operator++(int) 00263 { return _M_b++; } 00264 00265 __pointer_type 00266 operator++(int) volatile 00267 { return _M_b++; } 00268 00269 __pointer_type 00270 operator--(int) 00271 { return _M_b--; } 00272 00273 __pointer_type 00274 operator--(int) volatile 00275 { return _M_b--; } 00276 00277 __pointer_type 00278 operator++() 00279 { return ++_M_b; } 00280 00281 __pointer_type 00282 operator++() volatile 00283 { return ++_M_b; } 00284 00285 __pointer_type 00286 operator--() 00287 { return --_M_b; } 00288 00289 __pointer_type 00290 operator--() volatile 00291 { return --_M_b; } 00292 00293 __pointer_type 00294 operator+=(ptrdiff_t __d) 00295 { return _M_b.operator+=(__d); } 00296 00297 __pointer_type 00298 operator+=(ptrdiff_t __d) volatile 00299 { return _M_b.operator+=(__d); } 00300 00301 __pointer_type 00302 operator-=(ptrdiff_t __d) 00303 { return _M_b.operator-=(__d); } 00304 00305 __pointer_type 00306 operator-=(ptrdiff_t __d) volatile 00307 { return _M_b.operator-=(__d); } 00308 00309 bool 00310 is_lock_free() const 00311 { return _M_b.is_lock_free(); } 00312 00313 bool 00314 is_lock_free() const volatile 00315 { return _M_b.is_lock_free(); } 00316 00317 void 00318 store(__pointer_type __p, memory_order __m = memory_order_seq_cst) 00319 { return _M_b.store(__p, __m); } 00320 00321 void 00322 store(__pointer_type __p, 00323 memory_order __m = memory_order_seq_cst) volatile 00324 { return _M_b.store(__p, __m); } 00325 00326 __pointer_type 00327 load(memory_order __m = memory_order_seq_cst) const 00328 { return _M_b.load(__m); } 00329 00330 __pointer_type 00331 load(memory_order __m = memory_order_seq_cst) const volatile 00332 { return _M_b.load(__m); } 00333 00334 __pointer_type 00335 exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) 00336 { return _M_b.exchange(__p, __m); } 00337 00338 __pointer_type 00339 exchange(__pointer_type __p, 00340 memory_order __m = memory_order_seq_cst) volatile 00341 { return _M_b.exchange(__p, __m); } 00342 00343 bool 00344 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00345 memory_order __m1, memory_order __m2) 00346 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00347 00348 bool 00349 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00350 memory_order __m1, memory_order __m2) volatile 00351 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00352 00353 bool 00354 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00355 memory_order __m = memory_order_seq_cst) 00356 { 00357 return compare_exchange_weak(__p1, __p2, __m, 00358 __calculate_memory_order(__m)); 00359 } 00360 00361 bool 00362 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 00363 memory_order __m = memory_order_seq_cst) volatile 00364 { 00365 return compare_exchange_weak(__p1, __p2, __m, 00366 __calculate_memory_order(__m)); 00367 } 00368 00369 bool 00370 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00371 memory_order __m1, memory_order __m2) 00372 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00373 00374 bool 00375 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00376 memory_order __m1, memory_order __m2) volatile 00377 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 00378 00379 bool 00380 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00381 memory_order __m = memory_order_seq_cst) 00382 { 00383 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00384 __calculate_memory_order(__m)); 00385 } 00386 00387 bool 00388 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 00389 memory_order __m = memory_order_seq_cst) volatile 00390 { 00391 return _M_b.compare_exchange_strong(__p1, __p2, __m, 00392 __calculate_memory_order(__m)); 00393 } 00394 00395 __pointer_type 00396 fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) 00397 { return _M_b.fetch_add(__d, __m); } 00398 00399 __pointer_type 00400 fetch_add(ptrdiff_t __d, 00401 memory_order __m = memory_order_seq_cst) volatile 00402 { return _M_b.fetch_add(__d, __m); } 00403 00404 __pointer_type 00405 fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) 00406 { return _M_b.fetch_sub(__d, __m); } 00407 00408 __pointer_type 00409 fetch_sub(ptrdiff_t __d, 00410 memory_order __m = memory_order_seq_cst) volatile 00411 { return _M_b.fetch_sub(__d, __m); } 00412 }; 00413 00414 00415 /// Explicit specialization for bool. 00416 template<> 00417 struct atomic<bool> : public atomic_bool 00418 { 00419 typedef bool __integral_type; 00420 typedef atomic_bool __base_type; 00421 00422 atomic() = default; 00423 ~atomic() = default; 00424 atomic(const atomic&) = delete; 00425 atomic& operator=(const atomic&) = delete; 00426 atomic& operator=(const atomic&) volatile = delete; 00427 00428 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00429 00430 using __base_type::operator __integral_type; 00431 using __base_type::operator=; 00432 }; 00433 00434 /// Explicit specialization for char. 00435 template<> 00436 struct atomic<char> : public atomic_char 00437 { 00438 typedef char __integral_type; 00439 typedef atomic_char __base_type; 00440 00441 atomic() = default; 00442 ~atomic() = default; 00443 atomic(const atomic&) = delete; 00444 atomic& operator=(const atomic&) = delete; 00445 atomic& operator=(const atomic&) volatile = delete; 00446 00447 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00448 00449 using __base_type::operator __integral_type; 00450 using __base_type::operator=; 00451 }; 00452 00453 /// Explicit specialization for signed char. 00454 template<> 00455 struct atomic<signed char> : public atomic_schar 00456 { 00457 typedef signed char __integral_type; 00458 typedef atomic_schar __base_type; 00459 00460 atomic() = default; 00461 ~atomic() = default; 00462 atomic(const atomic&) = delete; 00463 atomic& operator=(const atomic&) = delete; 00464 atomic& operator=(const atomic&) volatile = delete; 00465 00466 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00467 00468 using __base_type::operator __integral_type; 00469 using __base_type::operator=; 00470 }; 00471 00472 /// Explicit specialization for unsigned char. 00473 template<> 00474 struct atomic<unsigned char> : public atomic_uchar 00475 { 00476 typedef unsigned char __integral_type; 00477 typedef atomic_uchar __base_type; 00478 00479 atomic() = default; 00480 ~atomic() = default; 00481 atomic(const atomic&) = delete; 00482 atomic& operator=(const atomic&) = delete; 00483 atomic& operator=(const atomic&) volatile = delete; 00484 00485 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00486 00487 using __base_type::operator __integral_type; 00488 using __base_type::operator=; 00489 }; 00490 00491 /// Explicit specialization for short. 00492 template<> 00493 struct atomic<short> : public atomic_short 00494 { 00495 typedef short __integral_type; 00496 typedef atomic_short __base_type; 00497 00498 atomic() = default; 00499 ~atomic() = default; 00500 atomic(const atomic&) = delete; 00501 atomic& operator=(const atomic&) = delete; 00502 atomic& operator=(const atomic&) volatile = delete; 00503 00504 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00505 00506 using __base_type::operator __integral_type; 00507 using __base_type::operator=; 00508 }; 00509 00510 /// Explicit specialization for unsigned short. 00511 template<> 00512 struct atomic<unsigned short> : public atomic_ushort 00513 { 00514 typedef unsigned short __integral_type; 00515 typedef atomic_ushort __base_type; 00516 00517 atomic() = default; 00518 ~atomic() = default; 00519 atomic(const atomic&) = delete; 00520 atomic& operator=(const atomic&) = delete; 00521 atomic& operator=(const atomic&) volatile = delete; 00522 00523 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00524 00525 using __base_type::operator __integral_type; 00526 using __base_type::operator=; 00527 }; 00528 00529 /// Explicit specialization for int. 00530 template<> 00531 struct atomic<int> : atomic_int 00532 { 00533 typedef int __integral_type; 00534 typedef atomic_int __base_type; 00535 00536 atomic() = default; 00537 ~atomic() = default; 00538 atomic(const atomic&) = delete; 00539 atomic& operator=(const atomic&) = delete; 00540 atomic& operator=(const atomic&) volatile = delete; 00541 00542 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00543 00544 using __base_type::operator __integral_type; 00545 using __base_type::operator=; 00546 }; 00547 00548 /// Explicit specialization for unsigned int. 00549 template<> 00550 struct atomic<unsigned int> : public atomic_uint 00551 { 00552 typedef unsigned int __integral_type; 00553 typedef atomic_uint __base_type; 00554 00555 atomic() = default; 00556 ~atomic() = default; 00557 atomic(const atomic&) = delete; 00558 atomic& operator=(const atomic&) = delete; 00559 atomic& operator=(const atomic&) volatile = delete; 00560 00561 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00562 00563 using __base_type::operator __integral_type; 00564 using __base_type::operator=; 00565 }; 00566 00567 /// Explicit specialization for long. 00568 template<> 00569 struct atomic<long> : public atomic_long 00570 { 00571 typedef long __integral_type; 00572 typedef atomic_long __base_type; 00573 00574 atomic() = default; 00575 ~atomic() = default; 00576 atomic(const atomic&) = delete; 00577 atomic& operator=(const atomic&) = delete; 00578 atomic& operator=(const atomic&) volatile = delete; 00579 00580 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00581 00582 using __base_type::operator __integral_type; 00583 using __base_type::operator=; 00584 }; 00585 00586 /// Explicit specialization for unsigned long. 00587 template<> 00588 struct atomic<unsigned long> : public atomic_ulong 00589 { 00590 typedef unsigned long __integral_type; 00591 typedef atomic_ulong __base_type; 00592 00593 atomic() = default; 00594 ~atomic() = default; 00595 atomic(const atomic&) = delete; 00596 atomic& operator=(const atomic&) = delete; 00597 atomic& operator=(const atomic&) volatile = delete; 00598 00599 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00600 00601 using __base_type::operator __integral_type; 00602 using __base_type::operator=; 00603 }; 00604 00605 /// Explicit specialization for long long. 00606 template<> 00607 struct atomic<long long> : public atomic_llong 00608 { 00609 typedef long long __integral_type; 00610 typedef atomic_llong __base_type; 00611 00612 atomic() = default; 00613 ~atomic() = default; 00614 atomic(const atomic&) = delete; 00615 atomic& operator=(const atomic&) = delete; 00616 atomic& operator=(const atomic&) volatile = delete; 00617 00618 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00619 00620 using __base_type::operator __integral_type; 00621 using __base_type::operator=; 00622 }; 00623 00624 /// Explicit specialization for unsigned long long. 00625 template<> 00626 struct atomic<unsigned long long> : public atomic_ullong 00627 { 00628 typedef unsigned long long __integral_type; 00629 typedef atomic_ullong __base_type; 00630 00631 atomic() = default; 00632 ~atomic() = default; 00633 atomic(const atomic&) = delete; 00634 atomic& operator=(const atomic&) = delete; 00635 atomic& operator=(const atomic&) volatile = delete; 00636 00637 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00638 00639 using __base_type::operator __integral_type; 00640 using __base_type::operator=; 00641 }; 00642 00643 /// Explicit specialization for wchar_t. 00644 template<> 00645 struct atomic<wchar_t> : public atomic_wchar_t 00646 { 00647 typedef wchar_t __integral_type; 00648 typedef atomic_wchar_t __base_type; 00649 00650 atomic() = default; 00651 ~atomic() = default; 00652 atomic(const atomic&) = delete; 00653 atomic& operator=(const atomic&) = delete; 00654 atomic& operator=(const atomic&) volatile = delete; 00655 00656 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00657 00658 using __base_type::operator __integral_type; 00659 using __base_type::operator=; 00660 }; 00661 00662 /// Explicit specialization for char16_t. 00663 template<> 00664 struct atomic<char16_t> : public atomic_char16_t 00665 { 00666 typedef char16_t __integral_type; 00667 typedef atomic_char16_t __base_type; 00668 00669 atomic() = default; 00670 ~atomic() = default; 00671 atomic(const atomic&) = delete; 00672 atomic& operator=(const atomic&) = delete; 00673 atomic& operator=(const atomic&) volatile = delete; 00674 00675 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00676 00677 using __base_type::operator __integral_type; 00678 using __base_type::operator=; 00679 }; 00680 00681 /// Explicit specialization for char32_t. 00682 template<> 00683 struct atomic<char32_t> : public atomic_char32_t 00684 { 00685 typedef char32_t __integral_type; 00686 typedef atomic_char32_t __base_type; 00687 00688 atomic() = default; 00689 ~atomic() = default; 00690 atomic(const atomic&) = delete; 00691 atomic& operator=(const atomic&) = delete; 00692 atomic& operator=(const atomic&) volatile = delete; 00693 00694 constexpr atomic(__integral_type __i) : __base_type(__i) { } 00695 00696 using __base_type::operator __integral_type; 00697 using __base_type::operator=; 00698 }; 00699 00700 00701 // Function definitions, atomic_flag operations. 00702 inline bool 00703 atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m) 00704 { return __a->test_and_set(__m); } 00705 00706 inline bool 00707 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 00708 memory_order __m) 00709 { return __a->test_and_set(__m); } 00710 00711 inline void 00712 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) 00713 { __a->clear(__m); } 00714 00715 inline void 00716 atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m) 00717 { __a->clear(__m); } 00718 00719 inline bool 00720 atomic_flag_test_and_set(atomic_flag* __a) 00721 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00722 00723 inline bool 00724 atomic_flag_test_and_set(volatile atomic_flag* __a) 00725 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 00726 00727 inline void 00728 atomic_flag_clear(atomic_flag* __a) 00729 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00730 00731 inline void 00732 atomic_flag_clear(volatile atomic_flag* __a) 00733 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 00734 00735 00736 // Function templates generally applicable to atomic types. 00737 template<typename _ITp> 00738 inline bool 00739 atomic_is_lock_free(const atomic<_ITp>* __a) 00740 { return __a->is_lock_free(); } 00741 00742 template<typename _ITp> 00743 inline bool 00744 atomic_is_lock_free(const volatile atomic<_ITp>* __a) 00745 { return __a->is_lock_free(); } 00746 00747 template<typename _ITp> 00748 inline void 00749 atomic_init(atomic<_ITp>* __a, _ITp __i); 00750 00751 template<typename _ITp> 00752 inline void 00753 atomic_init(volatile atomic<_ITp>* __a, _ITp __i); 00754 00755 template<typename _ITp> 00756 inline void 00757 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m) 00758 { __a->store(__i, __m); } 00759 00760 template<typename _ITp> 00761 inline void 00762 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00763 memory_order __m) 00764 { __a->store(__i, __m); } 00765 00766 template<typename _ITp> 00767 inline _ITp 00768 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) 00769 { return __a->load(__m); } 00770 00771 template<typename _ITp> 00772 inline _ITp 00773 atomic_load_explicit(const volatile atomic<_ITp>* __a, 00774 memory_order __m) 00775 { return __a->load(__m); } 00776 00777 template<typename _ITp> 00778 inline _ITp 00779 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 00780 memory_order __m) 00781 { return __a->exchange(__i, __m); } 00782 00783 template<typename _ITp> 00784 inline _ITp 00785 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 00786 memory_order __m) 00787 { return __a->exchange(__i, __m); } 00788 00789 template<typename _ITp> 00790 inline bool 00791 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 00792 _ITp* __i1, _ITp __i2, 00793 memory_order __m1, memory_order __m2) 00794 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00795 00796 template<typename _ITp> 00797 inline bool 00798 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 00799 _ITp* __i1, _ITp __i2, 00800 memory_order __m1, memory_order __m2) 00801 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 00802 00803 template<typename _ITp> 00804 inline bool 00805 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 00806 _ITp* __i1, _ITp __i2, 00807 memory_order __m1, 00808 memory_order __m2) 00809 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00810 00811 template<typename _ITp> 00812 inline bool 00813 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 00814 _ITp* __i1, _ITp __i2, 00815 memory_order __m1, 00816 memory_order __m2) 00817 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 00818 00819 00820 template<typename _ITp> 00821 inline void 00822 atomic_store(atomic<_ITp>* __a, _ITp __i) 00823 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00824 00825 template<typename _ITp> 00826 inline void 00827 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) 00828 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 00829 00830 template<typename _ITp> 00831 inline _ITp 00832 atomic_load(const atomic<_ITp>* __a) 00833 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00834 00835 template<typename _ITp> 00836 inline _ITp 00837 atomic_load(const volatile atomic<_ITp>* __a) 00838 { return atomic_load_explicit(__a, memory_order_seq_cst); } 00839 00840 template<typename _ITp> 00841 inline _ITp 00842 atomic_exchange(atomic<_ITp>* __a, _ITp __i) 00843 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00844 00845 template<typename _ITp> 00846 inline _ITp 00847 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) 00848 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 00849 00850 template<typename _ITp> 00851 inline bool 00852 atomic_compare_exchange_weak(atomic<_ITp>* __a, 00853 _ITp* __i1, _ITp __i2) 00854 { 00855 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00856 memory_order_seq_cst, 00857 memory_order_seq_cst); 00858 } 00859 00860 template<typename _ITp> 00861 inline bool 00862 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 00863 _ITp* __i1, _ITp __i2) 00864 { 00865 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 00866 memory_order_seq_cst, 00867 memory_order_seq_cst); 00868 } 00869 00870 template<typename _ITp> 00871 inline bool 00872 atomic_compare_exchange_strong(atomic<_ITp>* __a, 00873 _ITp* __i1, _ITp __i2) 00874 { 00875 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00876 memory_order_seq_cst, 00877 memory_order_seq_cst); 00878 } 00879 00880 template<typename _ITp> 00881 inline bool 00882 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 00883 _ITp* __i1, _ITp __i2) 00884 { 00885 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 00886 memory_order_seq_cst, 00887 memory_order_seq_cst); 00888 } 00889 00890 // Function templates for atomic_integral operations only, using 00891 // __atomic_base. Template argument should be constricted to 00892 // intergral types as specified in the standard, excluding address 00893 // types. 00894 template<typename _ITp> 00895 inline _ITp 00896 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00897 memory_order __m) 00898 { return __a->fetch_add(__i, __m); } 00899 00900 template<typename _ITp> 00901 inline _ITp 00902 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00903 memory_order __m) 00904 { return __a->fetch_add(__i, __m); } 00905 00906 template<typename _ITp> 00907 inline _ITp 00908 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00909 memory_order __m) 00910 { return __a->fetch_sub(__i, __m); } 00911 00912 template<typename _ITp> 00913 inline _ITp 00914 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00915 memory_order __m) 00916 { return __a->fetch_sub(__i, __m); } 00917 00918 template<typename _ITp> 00919 inline _ITp 00920 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00921 memory_order __m) 00922 { return __a->fetch_and(__i, __m); } 00923 00924 template<typename _ITp> 00925 inline _ITp 00926 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00927 memory_order __m) 00928 { return __a->fetch_and(__i, __m); } 00929 00930 template<typename _ITp> 00931 inline _ITp 00932 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00933 memory_order __m) 00934 { return __a->fetch_or(__i, __m); } 00935 00936 template<typename _ITp> 00937 inline _ITp 00938 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00939 memory_order __m) 00940 { return __a->fetch_or(__i, __m); } 00941 00942 template<typename _ITp> 00943 inline _ITp 00944 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 00945 memory_order __m) 00946 { return __a->fetch_xor(__i, __m); } 00947 00948 template<typename _ITp> 00949 inline _ITp 00950 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 00951 memory_order __m) 00952 { return __a->fetch_xor(__i, __m); } 00953 00954 template<typename _ITp> 00955 inline _ITp 00956 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) 00957 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 00958 00959 template<typename _ITp> 00960 inline _ITp 00961 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) 00962 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 00963 00964 template<typename _ITp> 00965 inline _ITp 00966 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) 00967 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 00968 00969 template<typename _ITp> 00970 inline _ITp 00971 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) 00972 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 00973 00974 template<typename _ITp> 00975 inline _ITp 00976 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) 00977 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 00978 00979 template<typename _ITp> 00980 inline _ITp 00981 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) 00982 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 00983 00984 template<typename _ITp> 00985 inline _ITp 00986 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) 00987 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 00988 00989 template<typename _ITp> 00990 inline _ITp 00991 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) 00992 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 00993 00994 template<typename _ITp> 00995 inline _ITp 00996 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) 00997 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 00998 00999 template<typename _ITp> 01000 inline _ITp 01001 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) 01002 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 01003 01004 01005 // Partial specializations for pointers. 01006 template<typename _ITp> 01007 inline _ITp* 01008 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01009 memory_order __m) 01010 { return __a->fetch_add(__d, __m); } 01011 01012 template<typename _ITp> 01013 inline _ITp* 01014 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 01015 memory_order __m) 01016 { return __a->fetch_add(__d, __m); } 01017 01018 template<typename _ITp> 01019 inline _ITp* 01020 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) 01021 { return __a->fetch_add(__d); } 01022 01023 template<typename _ITp> 01024 inline _ITp* 01025 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) 01026 { return __a->fetch_add(__d); } 01027 01028 template<typename _ITp> 01029 inline _ITp* 01030 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 01031 ptrdiff_t __d, memory_order __m) 01032 { return __a->fetch_sub(__d, __m); } 01033 01034 template<typename _ITp> 01035 inline _ITp* 01036 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 01037 memory_order __m) 01038 { return __a->fetch_sub(__d, __m); } 01039 01040 template<typename _ITp> 01041 inline _ITp* 01042 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) 01043 { return __a->fetch_sub(__d); } 01044 01045 template<typename _ITp> 01046 inline _ITp* 01047 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) 01048 { return __a->fetch_sub(__d); } 01049 // @} group atomics 01050 01051 _GLIBCXX_END_NAMESPACE_VERSION 01052 } // namespace 01053 01054 #endif