aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/libsupc++
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2012-02-10 18:20:43 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2012-02-10 18:20:43 +0000
commit75cee7c62ab4a51c1e9c18f1c06febbd38b8021b (patch)
tree0dbe6745de2f1b55e6c7f809f4157e564668753a /libstdc++-v3/libsupc++
parent6c9b75b06175c0859a7c340600069c58e083d7c3 (diff)
downloadgcc-75cee7c62ab4a51c1e9c18f1c06febbd38b8021b.zip
gcc-75cee7c62ab4a51c1e9c18f1c06febbd38b8021b.tar.gz
gcc-75cee7c62ab4a51c1e9c18f1c06febbd38b8021b.tar.bz2
PR libstdc++/51798 continued.
2012-02-10 Benjamin Kosnik <bkoz@redhat.com> Jonathan Wakely <jwakely.gcc@gmail.com> 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 <jwakely.gcc@gmail.com> From-SVN: r184110
Diffstat (limited to 'libstdc++-v3/libsupc++')
-rw-r--r--libstdc++-v3/libsupc++/eh_ptr.cc10
-rw-r--r--libstdc++-v3/libsupc++/eh_throw.cc4
-rw-r--r--libstdc++-v3/libsupc++/eh_tm.cc4
-rw-r--r--libstdc++-v3/libsupc++/guard.cc50
4 files changed, 38 insertions, 30 deletions
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);