[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: llvm-toolchain-3.8 on lower arm targets



On Wed, 5 Oct 2016 23:33:49 +1300, Bruce Hoult wrote:
> On Wed, Oct 5, 2016 at 7:46 AM, Tim Northover via llvm-dev <
> llvm-dev@lists.llvm.org> wrote:
>
> > Hi Emilio,
> >
> > On 4 October 2016 at 11:14, Emilio Pozuelo Monfort via llvm-dev
> > <llvm-dev@lists.llvm.org> wrote:
> > > In file included from /«PKGBUILDDIR»/lib/Support/ThreadPool.cpp:14:0:
> > > /«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h: In member function
> > > 'std::shared_future<void> llvm::ThreadPool::async(Function&&, Args&&
> > ...)':
> > > /«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h:78:77: error: return
> > type
> > > 'class std::shared_future<void>' is incomplete
> > >    inline std::shared_future<VoidTy> async(Function &&F, Args &&...
> > ArgList) {
> > >
> >     ^
> > >
> > > Any idea about this failure?
> > >
> > > For the Debian armel porters, we're switching to LLVM 3.8, so this
> > failure
> > > (which happens on 3.8, 3.9 and llvm-toolchain-snapshot) is likely going
> > to cause
> > > some package removals on armel as we try to get rid of older LLVM
> > versions.
> > > Helping fixing this issue would be appreciated to prevent that.
> >
> > This looks like the kind of failure you get when your host toolchain
> > doesn't support C++11 properly (specifically lock-free atomics in this
> > case).  When I've seen it before GCC was defaulting to a CPU that's
> > too old to do atomics properly, and that configuration is very
> > unlikely to be supported by LLVM ever (any more).
> >
>
> This seems bogus.
>
> C++11 allows atomic variables to be implemented using mutexes if the CPU
> doesn't support atomic operations on a given data type in some other way.
>
> If you don't call atomic_is_lock_free(&var) then everything should work
> correctly, albeit perhaps more slowly than you might like.
>
> It seems to me that atomic_is_lock_free() (or precomputed shortcuts such as
> ATOMIC_INT_LOCK_FREE) is there to enable you the possibility to use a
> different algorithm (if one is available), not to throw up your hands and
> say you don't support that architecture at all!
>
> If it's the standard library going out of its way to
> check ATOMIC_INT_LOCK_FREE  and then throwing up its hands and giving up
> then I'd say that's a bug. Simply taking out that check should produce
> working, correct code on anything that supports mutexes at all.

Attached patch to debian libstdc++ package is supposed to fix clang
compilation.I'm still waiting compilation to complete before I can
test it. The compilation will take long time in an armel vm. I decided
to share it in case someone else has faster test environment than I
have.

The patch has extra src directory that needs to be striped with
s/\([ab]\)\/src/\1/g if someone tries to apply it to upstream sources.

Pauli
From 805f44b797bf23b1c2cd95ab8cd9c748c7bdb8ea Mon Sep 17 00:00:00 2001
From: Pauli <suokkos@gmail.com>
Date: Sat, 5 Nov 2016 17:33:20 +0200
Subject: [PATCH] libstdc++: Fix future header for targets without atomic int
 instructions

---
 libstdc++-v3/include/std/future            |  4 +---
 libstdc++-v3/libsupc++/eh_ptr.cc           | 28 ++++++++++++++++------------
 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, 18 insertions(+), 27 deletions(-)

Index: gcc-6-6.2.0/src/libstdc++-v3/include/std/future
===================================================================
--- gcc-6-6.2.0.orig/src/libstdc++-v3/include/std/future
+++ gcc-6-6.2.0/src/libstdc++-v3/include/std/future
@@ -182,8 +182,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
@@ -1745,7 +1744,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
Index: gcc-6-6.2.0/src/libstdc++-v3/libsupc++/eh_ptr.cc
===================================================================
--- gcc-6-6.2.0.orig/src/libstdc++-v3/libsupc++/eh_ptr.cc
+++ gcc-6-6.2.0/src/libstdc++-v3/libsupc++/eh_ptr.cc
@@ -23,14 +23,12 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/c++config.h>
-#include <bits/atomic_lockfree_defines.h>
-
-#if ATOMIC_INT_LOCK_FREE > 1
 
 #define _GLIBCXX_EH_PTR_COMPAT
 
 #include <exception>
 #include <bits/exception_ptr.h>
+#include <ext/atomicity.h>
 #include "unwind-cxx.h"
 
 using namespace __cxxabiv1;
@@ -103,7 +101,9 @@ std::__exception_ptr::exception_ptr::_M_
     {
       __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);
     }
 }
 
@@ -114,11 +114,13 @@ std::__exception_ptr::exception_ptr::_M_
   if (_M_exception_object)
     {
       __cxa_refcounted_exception *eh =
-	__get_refcounted_exception_header_from_obj (_M_exception_object);
-      if (__atomic_sub_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL) == 0)
+        __get_refcounted_exception_header_from_obj (_M_exception_object);
+      _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;
@@ -219,8 +221,10 @@ __gxx_dependent_exception_cleanup(_Unwin
 
   __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);
 
@@ -238,7 +242,9 @@ std::rethrow_exception(std::exception_pt
 
   __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 ();
@@ -260,5 +266,3 @@ std::rethrow_exception(std::exception_pt
 }
 
 #undef _GLIBCXX_EH_PTR_COMPAT
-
-#endif
Index: gcc-6-6.2.0/src/libstdc++-v3/libsupc++/exception
===================================================================
--- gcc-6-6.2.0.orig/src/libstdc++-v3/libsupc++/exception
+++ gcc-6-6.2.0/src/libstdc++-v3/libsupc++/exception
@@ -35,7 +35,6 @@
 #pragma GCC visibility push(default)
 
 #include <bits/c++config.h>
-#include <bits/atomic_lockfree_defines.h>
 
 extern "C++" {
 
@@ -166,7 +165,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 #pragma GCC visibility pop
 
-#if (__cplusplus >= 201103L) && (ATOMIC_INT_LOCK_FREE > 1)
+#if (__cplusplus >= 201103L)
 #include <bits/exception_ptr.h>
 #include <bits/nested_exception.h>
 #endif
Index: gcc-6-6.2.0/src/libstdc++-v3/libsupc++/exception_ptr.h
===================================================================
--- gcc-6-6.2.0.orig/src/libstdc++-v3/libsupc++/exception_ptr.h
+++ gcc-6-6.2.0/src/libstdc++-v3/libsupc++/exception_ptr.h
@@ -36,10 +36,6 @@
 #include <bits/c++config.h>
 #include <bits/exception_defines.h>
 
-#if ATOMIC_INT_LOCK_FREE < 2
-#  error This platform does not support exception propagation.
-#endif
-
 extern "C++" {
 
 namespace std 
Index: gcc-6-6.2.0/src/libstdc++-v3/libsupc++/nested_exception.cc
===================================================================
--- gcc-6-6.2.0.orig/src/libstdc++-v3/libsupc++/nested_exception.cc
+++ gcc-6-6.2.0/src/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
Index: gcc-6-6.2.0/src/libstdc++-v3/libsupc++/nested_exception.h
===================================================================
--- gcc-6-6.2.0.orig/src/libstdc++-v3/libsupc++/nested_exception.h
+++ gcc-6-6.2.0/src/libstdc++-v3/libsupc++/nested_exception.h
@@ -39,10 +39,6 @@
 #include <bits/c++config.h>
 #include <bits/move.h>
 
-#if ATOMIC_INT_LOCK_FREE < 2
-#  error This platform does not support exception propagation.
-#endif
-
 extern "C++" {
 
 namespace std

Reply to: