From a886ff259a27703516a50d2c05b632644a6a2157 Mon Sep 17 00:00:00 2001 From: Pauli Date: Sat, 5 Nov 2016 17:33:20 +0200 Subject: [PATCH] libstdc++: Fix future header without lock free atomic int Compiling programs using std::future for old arm processors fails. The problem is caused by preprocessor check for atomic lock free int. Future can be changed to work correctly without lock free atomics with minor changes to exception_ptr implementation. --- libstdc++-v3/include/std/future | 4 +--- libstdc++-v3/libsupc++/eh_ptr.cc | 26 +++++++++++++++----------- libstdc++-v3/libsupc++/exception | 3 +-- libstdc++-v3/libsupc++/exception_ptr.h | 4 ---- libstdc++-v3/libsupc++/nested_exception.cc | 2 -- libstdc++-v3/libsupc++/nested_exception.h | 4 ---- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index fea915b..1f247fa 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -183,8 +183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION future<__async_result_of<_Fn, _Args...>> async(_Fn&& __fn, _Args&&... __args); -#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ - && (ATOMIC_INT_LOCK_FREE > 1) +#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) /// Base class and enclosing scope. struct __future_base @@ -1740,7 +1739,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // _GLIBCXX_ASYNC_ABI_COMPAT #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 - // && ATOMIC_INT_LOCK_FREE // @} group futures _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index f3c910b..96a2e6d 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -23,14 +23,12 @@ // . #include -#include - -#if ATOMIC_INT_LOCK_FREE > 1 #define _GLIBCXX_EH_PTR_COMPAT #include #include +#include #include "unwind-cxx.h" using namespace __cxxabiv1; @@ -101,7 +99,9 @@ std::__exception_ptr::exception_ptr::_M_addref() noexcept { __cxa_refcounted_exception *eh = __get_refcounted_exception_header_from_obj (_M_exception_object); - __atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL); + _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&eh->referenceCount); + __gnu_cxx::__atomic_add_dispatch(&eh->referenceCount, 1); + _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&eh->referenceCount); } } @@ -113,10 +113,12 @@ std::__exception_ptr::exception_ptr::_M_release() noexcept { __cxa_refcounted_exception *eh = __get_refcounted_exception_header_from_obj (_M_exception_object); - if (__atomic_sub_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) + _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&eh->referenceCount); + if (__gnu_cxx::__exchange_and_add_dispatch(&eh->referenceCount, -1) == 1) { - if (eh->exc.exceptionDestructor) - eh->exc.exceptionDestructor (_M_exception_object); + _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&eh->referenceCount); + if (eh->exc.exceptionDestructor) + eh->exc.exceptionDestructor (_M_exception_object); __cxa_free_exception (_M_exception_object); _M_exception_object = 0; @@ -211,8 +213,10 @@ __gxx_dependent_exception_cleanup(_Unwind_Reason_Code code, __cxa_free_dependent_exception (dep); - if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) + _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&header->referenceCount); + if (__gnu_cxx::__exchange_and_add_dispatch(&header->referenceCount, -1) == 1) { + _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&header->referenceCount); if (header->exc.exceptionDestructor) header->exc.exceptionDestructor (header + 1); @@ -230,7 +234,9 @@ std::rethrow_exception(std::exception_ptr ep) __cxa_dependent_exception *dep = __cxa_allocate_dependent_exception (); dep->primaryException = obj; - __atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL); + _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&eh->referenceCount); + __gnu_cxx::__atomic_add_dispatch(&eh->referenceCount, 1); + _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&eh->referenceCount); dep->unexpectedHandler = get_unexpected (); dep->terminateHandler = get_terminate (); @@ -252,5 +258,3 @@ std::rethrow_exception(std::exception_ptr ep) } #undef _GLIBCXX_EH_PTR_COMPAT - -#endif diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception index 8be903b..021d70e 100644 --- a/libstdc++-v3/libsupc++/exception +++ b/libstdc++-v3/libsupc++/exception @@ -35,7 +35,6 @@ #pragma GCC visibility push(default) #include -#include #include extern "C++" { @@ -139,7 +138,7 @@ _GLIBCXX_END_NAMESPACE_VERSION #pragma GCC visibility pop -#if (__cplusplus >= 201103L) && (ATOMIC_INT_LOCK_FREE > 1) +#if (__cplusplus >= 201103L) #include #include #endif diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h index a47a585..cce156a 100644 --- a/libstdc++-v3/libsupc++/exception_ptr.h +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -39,10 +39,6 @@ #include #include -#if ATOMIC_INT_LOCK_FREE < 2 -# error This platform does not support exception propagation. -#endif - extern "C++" { namespace std diff --git a/libstdc++-v3/libsupc++/nested_exception.cc b/libstdc++-v3/libsupc++/nested_exception.cc index c1a7b7a..82dddb1 100644 --- a/libstdc++-v3/libsupc++/nested_exception.cc +++ b/libstdc++-v3/libsupc++/nested_exception.cc @@ -25,7 +25,5 @@ namespace std { -#if ATOMIC_INT_LOCK_FREE > 1 nested_exception::~nested_exception() noexcept = default; -#endif } // namespace std diff --git a/libstdc++-v3/libsupc++/nested_exception.h b/libstdc++-v3/libsupc++/nested_exception.h index 078af0e..48bdabb 100644 --- a/libstdc++-v3/libsupc++/nested_exception.h +++ b/libstdc++-v3/libsupc++/nested_exception.h @@ -39,10 +39,6 @@ #include #include -#if ATOMIC_INT_LOCK_FREE < 2 -# error This platform does not support exception propagation. -#endif - extern "C++" { namespace std -- 2.9.3