1e4b17023SJohn Marino // <atomic> compatibility -*- C++ -*- 2e4b17023SJohn Marino 3e4b17023SJohn Marino // Copyright (C) 2008, 2009, 2010, 2011, 2012 4e4b17023SJohn Marino // Free Software Foundation, Inc. 5e4b17023SJohn Marino // 6e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 7e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 8e4b17023SJohn Marino // terms of the GNU General Public License as published by the 9e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 10e4b17023SJohn Marino // any later version. 11e4b17023SJohn Marino 12e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 13e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 14e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15e4b17023SJohn Marino // GNU General Public License for more details. 16e4b17023SJohn Marino 17e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 18e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 19e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 20e4b17023SJohn Marino 21e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 22e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 23e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 25e4b17023SJohn Marino 26e4b17023SJohn Marino #include "gstdint.h" 27e4b17023SJohn Marino #include <atomic> 28e4b17023SJohn Marino #include <mutex> 29e4b17023SJohn Marino 30e4b17023SJohn Marino // XXX GLIBCXX_ABI Deprecated 31e4b17023SJohn Marino // gcc-4.7.0 32e4b17023SJohn Marino 33*5ce9237cSJohn Marino #ifdef _GLIBCXX_SHARED 34e4b17023SJohn Marino 35e4b17023SJohn Marino #define LOGSIZE 4 36e4b17023SJohn Marino 37e4b17023SJohn Marino namespace 38e4b17023SJohn Marino { 39e4b17023SJohn Marino #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) 40e4b17023SJohn Marino std::mutex& get_atomic_mutex()41e4b17023SJohn Marino get_atomic_mutex() 42e4b17023SJohn Marino { 43e4b17023SJohn Marino static std::mutex atomic_mutex; 44e4b17023SJohn Marino return atomic_mutex; 45e4b17023SJohn Marino } 46e4b17023SJohn Marino #endif 47e4b17023SJohn Marino 48e4b17023SJohn Marino std::__atomic_flag_base flag_table[ 1 << LOGSIZE ] = 49e4b17023SJohn Marino { 50e4b17023SJohn Marino ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, 51e4b17023SJohn Marino ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, 52e4b17023SJohn Marino ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, 53e4b17023SJohn Marino ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, 54e4b17023SJohn Marino }; 55e4b17023SJohn Marino } // anonymous namespace 56e4b17023SJohn Marino 57e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 58e4b17023SJohn Marino { 59e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 60e4b17023SJohn Marino 61e4b17023SJohn Marino namespace __atomic0 62e4b17023SJohn Marino { 63e4b17023SJohn Marino 64e4b17023SJohn Marino struct atomic_flag : public __atomic_flag_base 65e4b17023SJohn Marino { 66e4b17023SJohn Marino bool 67e4b17023SJohn Marino test_and_set(memory_order) noexcept; 68e4b17023SJohn Marino 69e4b17023SJohn Marino void 70e4b17023SJohn Marino clear(memory_order) noexcept; 71e4b17023SJohn Marino }; 72e4b17023SJohn Marino 73e4b17023SJohn Marino bool test_and_set(memory_order)74e4b17023SJohn Marino atomic_flag::test_and_set(memory_order) noexcept 75e4b17023SJohn Marino { 76e4b17023SJohn Marino #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) 77e4b17023SJohn Marino lock_guard<mutex> __lock(get_atomic_mutex()); 78e4b17023SJohn Marino #endif 79e4b17023SJohn Marino bool result = _M_i; 80e4b17023SJohn Marino _M_i = true; 81e4b17023SJohn Marino return result; 82e4b17023SJohn Marino } 83e4b17023SJohn Marino 84e4b17023SJohn Marino void clear(memory_order)85e4b17023SJohn Marino atomic_flag::clear(memory_order) noexcept 86e4b17023SJohn Marino { 87e4b17023SJohn Marino #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) 88e4b17023SJohn Marino lock_guard<mutex> __lock(get_atomic_mutex()); 89e4b17023SJohn Marino #endif 90e4b17023SJohn Marino _M_i = false; 91e4b17023SJohn Marino } 92e4b17023SJohn Marino } // namespace __atomic0 93e4b17023SJohn Marino 94e4b17023SJohn Marino _GLIBCXX_BEGIN_EXTERN_C 95e4b17023SJohn Marino 96e4b17023SJohn Marino bool atomic_flag_test_and_set_explicit(__atomic_flag_base * __a,memory_order __m)97e4b17023SJohn Marino atomic_flag_test_and_set_explicit(__atomic_flag_base* __a, 98e4b17023SJohn Marino memory_order __m) _GLIBCXX_NOTHROW 99e4b17023SJohn Marino { 100e4b17023SJohn Marino atomic_flag* d = static_cast<atomic_flag*>(__a); 101e4b17023SJohn Marino return d->test_and_set(__m); 102e4b17023SJohn Marino } 103e4b17023SJohn Marino 104e4b17023SJohn Marino void atomic_flag_clear_explicit(__atomic_flag_base * __a,memory_order __m)105e4b17023SJohn Marino atomic_flag_clear_explicit(__atomic_flag_base* __a, 106e4b17023SJohn Marino memory_order __m) _GLIBCXX_NOTHROW 107e4b17023SJohn Marino { 108e4b17023SJohn Marino atomic_flag* d = static_cast<atomic_flag*>(__a); 109e4b17023SJohn Marino return d->clear(__m); 110e4b17023SJohn Marino } 111e4b17023SJohn Marino 112e4b17023SJohn Marino void __atomic_flag_wait_explicit(__atomic_flag_base * __a,memory_order __x)113e4b17023SJohn Marino __atomic_flag_wait_explicit(__atomic_flag_base* __a, 114e4b17023SJohn Marino memory_order __x) _GLIBCXX_NOTHROW 115e4b17023SJohn Marino { 116e4b17023SJohn Marino while (atomic_flag_test_and_set_explicit(__a, __x)) 117e4b17023SJohn Marino { }; 118e4b17023SJohn Marino } 119e4b17023SJohn Marino 120e4b17023SJohn Marino _GLIBCXX_CONST __atomic_flag_base* __atomic_flag_for_address(const volatile void * __z)121e4b17023SJohn Marino __atomic_flag_for_address(const volatile void* __z) _GLIBCXX_NOTHROW 122e4b17023SJohn Marino { 123e4b17023SJohn Marino uintptr_t __u = reinterpret_cast<uintptr_t>(__z); 124e4b17023SJohn Marino __u += (__u >> 2) + (__u << 4); 125e4b17023SJohn Marino __u += (__u >> 7) + (__u << 5); 126e4b17023SJohn Marino __u += (__u >> 17) + (__u << 13); 127e4b17023SJohn Marino if (sizeof(uintptr_t) > 4) 128e4b17023SJohn Marino __u += (__u >> 31); 129e4b17023SJohn Marino __u &= ~((~uintptr_t(0)) << LOGSIZE); 130e4b17023SJohn Marino return flag_table + __u; 131e4b17023SJohn Marino } 132e4b17023SJohn Marino 133e4b17023SJohn Marino _GLIBCXX_END_EXTERN_C 134e4b17023SJohn Marino 135e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 136e4b17023SJohn Marino } // namespace std 137e4b17023SJohn Marino 138e4b17023SJohn Marino #endif 139e4b17023SJohn Marino 140e4b17023SJohn Marino // XXX GLIBCXX_ABI Deprecated 141e4b17023SJohn Marino // gcc-4.5.0 142e4b17023SJohn Marino // <atomic> signature changes 143e4b17023SJohn Marino 144e4b17023SJohn Marino // The rename syntax for default exported names is 145e4b17023SJohn Marino // asm (".symver name1,exportedname@GLIBCXX_3.4") 146e4b17023SJohn Marino // asm (".symver name2,exportedname@@GLIBCXX_3.4.5") 147e4b17023SJohn Marino // In the future, GLIBCXX_ABI > 6 should remove all uses of 148e4b17023SJohn Marino // _GLIBCXX_*_SYMVER macros in this file. 149e4b17023SJohn Marino 150*5ce9237cSJohn Marino #if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \ 151e4b17023SJohn Marino && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \ 152e4b17023SJohn Marino && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT) 153e4b17023SJohn Marino 154e4b17023SJohn Marino #define _GLIBCXX_ASM_SYMVER(cur, old, version) \ 155e4b17023SJohn Marino asm (".symver " #cur "," #old "@@" #version); 156e4b17023SJohn Marino 157e4b17023SJohn Marino _GLIBCXX_ASM_SYMVER(_ZNSt9__atomic011atomic_flag5clearESt12memory_order, _ZNVSt9__atomic011atomic_flag5clearESt12memory_order, GLIBCXX_3.4.11) 158e4b17023SJohn Marino 159e4b17023SJohn Marino _GLIBCXX_ASM_SYMVER(_ZNSt9__atomic011atomic_flag12test_and_setESt12memory_order, _ZNVSt9__atomic011atomic_flag12test_and_setESt12memory_order, GLIBCXX_3.4.11) 160e4b17023SJohn Marino 161e4b17023SJohn Marino #endif 162