From 75cee7c62ab4a51c1e9c18f1c06febbd38b8021b Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Fri, 10 Feb 2012 18:20:43 +0000 Subject: PR libstdc++/51798 continued. 2012-02-10 Benjamin Kosnik Jonathan Wakely PR libstdc++/51798 continued. * acinclude.m4 (GLIBCXX_ENABLE_ATOMIC_BUILTINS): Use __atomic_* builtins instead of __sync_* builtins for atomic functionality. * include/bits/shared_ptr_base.h: Same. * include/parallel/compatibility.h: Same. * include/profile/impl/profiler_state.h: Same. * include/tr1/shared_ptr.h: Same. * libsupc++/eh_ptr.cc: Same. * libsupc++/eh_throw.cc: Same. * libsupc++/eh_tm.cc: Same. * libsupc++/guard.cc: Same. * configure: Regenerated. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line numbers. Co-Authored-By: Jonathan Wakely From-SVN: r184110 --- libstdc++-v3/libsupc++/eh_ptr.cc | 10 ++++---- libstdc++-v3/libsupc++/eh_throw.cc | 4 +-- libstdc++-v3/libsupc++/eh_tm.cc | 4 +-- libstdc++-v3/libsupc++/guard.cc | 50 ++++++++++++++++++++++---------------- 4 files changed, 38 insertions(+), 30 deletions(-) (limited to 'libstdc++-v3/libsupc++') diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 684580f..82ebb0b 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Implement the members of exception_ptr. -// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -75,7 +75,7 @@ std::__exception_ptr::exception_ptr::_M_addref() _GLIBCXX_USE_NOEXCEPT { __cxa_refcounted_exception *eh = __get_refcounted_exception_header_from_obj (_M_exception_object); - __sync_add_and_fetch (&eh->referenceCount, 1); + __atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL); } } @@ -87,7 +87,7 @@ std::__exception_ptr::exception_ptr::_M_release() _GLIBCXX_USE_NOEXCEPT { __cxa_refcounted_exception *eh = __get_refcounted_exception_header_from_obj (_M_exception_object); - if (__sync_sub_and_fetch (&eh->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) { if (eh->exc.exceptionDestructor) eh->exc.exceptionDestructor (_M_exception_object); @@ -191,7 +191,7 @@ __gxx_dependent_exception_cleanup(_Unwind_Reason_Code code, __cxa_free_dependent_exception (dep); - if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) { if (header->exc.exceptionDestructor) header->exc.exceptionDestructor (header + 1); @@ -210,7 +210,7 @@ std::rethrow_exception(std::exception_ptr ep) __cxa_dependent_exception *dep = __cxa_allocate_dependent_exception (); dep->primaryException = obj; - __sync_add_and_fetch (&eh->referenceCount, 1); + __atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL); dep->unexpectedHandler = __unexpected_handler; dep->terminateHandler = __terminate_handler; diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index a3d2b0d..de00602 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -1,6 +1,6 @@ // -*- C++ -*- Exception handling routines for throwing. // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, -// 2011 Free Software Foundation, Inc. +// 2011, 2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -44,7 +44,7 @@ __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) __terminate (header->exc.terminateHandler); #if ATOMIC_INT_LOCK_FREE > 1 - if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) { #endif if (header->exc.exceptionDestructor) diff --git a/libstdc++-v3/libsupc++/eh_tm.cc b/libstdc++-v3/libsupc++/eh_tm.cc index 1df8644..bd9de6c 100644 --- a/libstdc++-v3/libsupc++/eh_tm.cc +++ b/libstdc++-v3/libsupc++/eh_tm.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling routines for Transactional Memory. -// Copyright (C) 2009, 2011 Free Software Foundation, Inc. +// Copyright (C) 2009, 2011, 2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -46,7 +46,7 @@ free_any_cxa_exception (_Unwind_Exception *eo) } #if __GCC_ATOMIC_INT_LOCK_FREE > 1 - if (__sync_sub_and_fetch (&h->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&h->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) #endif __cxa_free_exception (h + 1); } diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc index 643ecd7..b7b8d3f 100644 --- a/libstdc++-v3/libsupc++/guard.cc +++ b/libstdc++-v3/libsupc++/guard.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010, 2011 +// Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010, 2011, 2012 // Free Software Foundation, Inc. // // This file is part of GCC. @@ -239,34 +239,42 @@ namespace __cxxabiv1 return 0; # ifdef _GLIBCXX_USE_FUTEX - // If __sync_* and futex syscall are supported, don't use any global + // If __atomic_* and futex syscall are supported, don't use any global // mutex. if (__gthread_active_p ()) { int *gi = (int *) (void *) g; + int expected(0); const int guard_bit = _GLIBCXX_GUARD_BIT; const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT; const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; while (1) { - int old = __sync_val_compare_and_swap (gi, 0, pending_bit); - if (old == 0) - return 1; // This thread should do the initialization. - - if (old == guard_bit) - return 0; // Already initialized. - - if (old == pending_bit) + if (__atomic_compare_exchange_n(gi, &expected, pending_bit, true, + __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) { - int newv = old | waiting_bit; - if (__sync_val_compare_and_swap (gi, old, newv) != old) - continue; - - old = newv; + // This thread should do the initialization. + return 1; } - - syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, old, 0); + + if (expected == guard_bit) + { + // Already initialized. + return 0; + } + if (expected == pending_bit) + { + int newv = expected | waiting_bit; + if (!__atomic_compare_exchange_n(gi, &expected, newv, true, + __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED)) + continue; + + expected = newv; + } + + syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, expected, 0); } } # else @@ -316,13 +324,13 @@ namespace __cxxabiv1 void __cxa_guard_abort (__guard *g) throw () { #ifdef _GLIBCXX_USE_FUTEX - // If __sync_* and futex syscall are supported, don't use any global + // If __atomic_* and futex syscall are supported, don't use any global // mutex. if (__gthread_active_p ()) { int *gi = (int *) (void *) g; const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; - int old = __sync_lock_test_and_set (gi, 0); + int old = __atomic_exchange_n (gi, 0, __ATOMIC_ACQ_REL); if ((old & waiting_bit) != 0) syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX); @@ -355,14 +363,14 @@ namespace __cxxabiv1 void __cxa_guard_release (__guard *g) throw () { #ifdef _GLIBCXX_USE_FUTEX - // If __sync_* and futex syscall are supported, don't use any global + // If __atomic_* and futex syscall are supported, don't use any global // mutex. if (__gthread_active_p ()) { int *gi = (int *) (void *) g; const int guard_bit = _GLIBCXX_GUARD_BIT; const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; - int old = __sync_lock_test_and_set (gi, guard_bit); + int old = __atomic_exchange_n (gi, guard_bit, __ATOMIC_ACQ_REL); if ((old & waiting_bit) != 0) syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX); -- cgit v1.1