Index: include/ext/atomicity.h =================================================================== --- include/ext/atomicity.h (revision 182825) +++ include/ext/atomicity.h (working copy) @@ -1,6 +1,6 @@ // Support for atomic operations -*- C++ -*- -// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 +// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -45,16 +45,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef _GLIBCXX_ATOMIC_BUILTINS static inline _Atomic_word __exchange_and_add(volatile _Atomic_word* __mem, int __val) - { return __sync_fetch_and_add(__mem, __val); } + { return __atomic_fetch_add(__mem, __val, 2); } + + static inline _Atomic_word + __exchange_and_sub(volatile _Atomic_word* __mem, int __val) + { return __atomic_fetch_sub(__mem, __val, 3); } static inline void __atomic_add(volatile _Atomic_word* __mem, int __val) - { __sync_fetch_and_add(__mem, __val); } + { __atomic_fetch_add(__mem, __val, 2); } #else _Atomic_word __attribute__ ((__unused__)) __exchange_and_add(volatile _Atomic_word*, int) throw (); + _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_sub(volatile _Atomic_word*, int) throw (); + void __attribute__ ((__unused__)) __atomic_add(volatile _Atomic_word*, int) throw (); @@ -68,6 +76,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __result; } + static inline _Atomic_word + __exchange_and_sub_single(_Atomic_word* __mem, int __val) + { + _Atomic_word __result = *__mem; + *__mem -= __val; + return __result; + } + static inline void __atomic_add_single(_Atomic_word* __mem, int __val) { *__mem += __val; } @@ -86,6 +102,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } + static inline _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_sub_dispatch(_Atomic_word* __mem, int __val) + { +#ifdef __GTHREADS + if (__gthread_active_p()) + return __exchange_and_sub(__mem, __val); + else + return __exchange_and_sub_single(__mem, __val); +#else + return __exchange_and_sub_single(__mem, __val); +#endif + } + static inline void __attribute__ ((__unused__)) __atomic_add_dispatch(_Atomic_word* __mem, int __val) Index: include/bits/locale_classes.h =================================================================== --- include/bits/locale_classes.h (revision 182825) +++ include/bits/locale_classes.h (working copy) @@ -1,7 +1,7 @@ // Locale support -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -// 2006, 2007, 2008, 2009, 2010, 2011 +// 2006, 2007, 2008, 2009, 2010, 2011, 2012 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -407,7 +407,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount); - if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) + if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_refcount, 1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount); __try @@ -516,7 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount); - if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) + if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_refcount, 1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount); __try Index: include/bits/basic_string.h =================================================================== --- include/bits/basic_string.h (revision 182825) +++ include/bits/basic_string.h (working copy) @@ -1,7 +1,7 @@ // Components for manipulating sequences of characters -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -// 2006, 2007, 2008, 2009, 2010, 2011 +// 2006, 2007, 2008, 2009, 2010, 2011, 2012 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -239,8 +239,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); - if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, - -1) <= 0) + if (__gnu_cxx::__exchange_and_sub_dispatch(&this->_M_refcount, + 1) <= 0) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); _M_destroy(__a); Index: include/bits/ios_base.h =================================================================== --- include/bits/ios_base.h (revision 182825) +++ include/bits/ios_base.h (working copy) @@ -1,7 +1,7 @@ // Iostreams base classes -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -// 2006, 2007, 2008, 2009, 2010 +// 2006, 2007, 2008, 2009, 2010, 2012 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -480,7 +480,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount); - int __res = __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1); + int __res = __gnu_cxx::__exchange_and_sub_dispatch(&_M_refcount, 1); if (__res == 0) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount); Index: include/bits/shared_ptr_base.h =================================================================== --- include/bits/shared_ptr_base.h (revision 182825) +++ include/bits/shared_ptr_base.h (working copy) @@ -1,6 +1,7 @@ // shared_ptr and weak_ptr implementation details -*- C++ -*- -// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -140,7 +141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); - if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) + if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_use_count, 1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); _M_dispose(); @@ -156,8 +157,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); - if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, - -1) == 1) + if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_weak_count, + 1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); _M_destroy(); @@ -174,7 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); - if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) + if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_weak_count, 1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); if (_Mutex_base<_Lp>::_S_need_barriers)