diff options
Diffstat (limited to 'libstdc++-v3/src/atomic.cc')
-rw-r--r-- | libstdc++-v3/src/atomic.cc | 125 |
1 files changed, 64 insertions, 61 deletions
diff --git a/libstdc++-v3/src/atomic.cc b/libstdc++-v3/src/atomic.cc index 228f92f91d0..5cb39191361 100644 --- a/libstdc++-v3/src/atomic.cc +++ b/libstdc++-v3/src/atomic.cc @@ -1,6 +1,6 @@ // Support for atomic operations -*- C++ -*- -// Copyright (C) 2008 +// Copyright (C) 2008, 2009 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -30,12 +30,22 @@ #include "gstdint.h" #include <cstdatomic> +#include <mutex> #define LOGSIZE 4 namespace { - atomic_flag volatile __atomic_flag_anon_table__[ 1 << LOGSIZE ] = +#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) + std::mutex& + get_atomic_mutex() + { + static std::mutex atomic_mutex; + return atomic_mutex; + } +#endif + + std::__atomic_flag_base volatile flag_table[ 1 << LOGSIZE ] = { ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, @@ -46,73 +56,66 @@ namespace namespace std { - extern "C" { - - const atomic_flag atomic_global_fence_compatibility = ATOMIC_FLAG_INIT; - - bool - atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, - memory_order __x - __attribute__ ((__unused__))) + namespace __atomic0 { -#ifdef _GLIBCXX_ATOMIC_BUILTINS_1 - if (__x >= memory_order_acq_rel) - __sync_synchronize(); - return __sync_lock_test_and_set(&(__a->_M_base._M_b), 1); -#else - bool result = __a->_M_base._M_b; - __a->_M_base._M_b = true; - return result; + bool + atomic_flag::test_and_set(memory_order) volatile + { +#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) + lock_guard<mutex> __lock(get_atomic_mutex()); #endif - } + bool result = _M_i; + _M_i = true; + return result; + } - bool - atomic_flag_test_and_set(volatile atomic_flag* __a) - { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } - - void - atomic_flag_clear_explicit(volatile atomic_flag* __a, - memory_order __x __attribute__ ((__unused__))) - { -#ifdef _GLIBCXX_ATOMIC_BUILTINS_1 - __sync_lock_release(&(__a->_M_base._M_b)); - if (__x >= memory_order_acq_rel) - __sync_synchronize(); -#else - __a->_M_base._M_b = false; + void + atomic_flag::clear(memory_order) volatile + { +#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) + lock_guard<mutex> __lock(get_atomic_mutex()); #endif - } + _M_i = false; + } + } - void - atomic_flag_clear(volatile atomic_flag* __a) - { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } - - void - atomic_flag_fence(const volatile atomic_flag*, memory_order) + extern "C" { -#ifdef _GLIBCXX_ATOMIC_BUILTINS_1 - __sync_synchronize(); -#endif - } + bool + atomic_flag_test_and_set_explicit(volatile __atomic_flag_base* __a, + memory_order __m) + { + volatile atomic_flag d(__a->_M_i); + return d.test_and_set(__m); + } - void - __atomic_flag_wait_explicit(volatile atomic_flag* __a, memory_order __x) - { - while (atomic_flag_test_and_set_explicit(__a, __x)) - { }; - } + void + atomic_flag_clear_explicit(volatile __atomic_flag_base* __a, + memory_order __m) + { + volatile atomic_flag d(__a->_M_i); + return d.clear(__m); + } - volatile atomic_flag* - __atomic_flag_for_address(const volatile void* __z) - { - uintptr_t __u = reinterpret_cast<uintptr_t>(__z); - __u += (__u >> 2) + (__u << 4); - __u += (__u >> 7) + (__u << 5); - __u += (__u >> 17) + (__u << 13); - if (sizeof(uintptr_t) > 4) __u += (__u >> 31); - __u &= ~((~uintptr_t(0)) << LOGSIZE); - return __atomic_flag_anon_table__ + __u; - } + void + __atomic_flag_wait_explicit(volatile __atomic_flag_base* __a, + memory_order __x) + { + while (atomic_flag_test_and_set_explicit(__a, __x)) + { }; + } + volatile __atomic_flag_base* + __atomic_flag_for_address(const volatile void* __z) + { + uintptr_t __u = reinterpret_cast<uintptr_t>(__z); + __u += (__u >> 2) + (__u << 4); + __u += (__u >> 7) + (__u << 5); + __u += (__u >> 17) + (__u << 13); + if (sizeof(uintptr_t) > 4) + __u += (__u >> 31); + __u &= ~((~uintptr_t(0)) << LOGSIZE); + return flag_table + __u; + } } // extern "C" } // namespace std |