See http://gcc.gnu.org/ml/gcc-patches/2012-01/msg01427.html for the
previous discussion about the motivation for this patch and the choice
of __pthread_key_create (also the comment added in the code by this patch).

This had no effect on testsuite results on x86_64-linux-gnu 
(Ubuntu EGLIBC 2.11.1-0ubuntu7.10).


Thanks,
Roland


libgcc/
2012-06-08  Roland McGrath  <mcgra...@google.com>

        * gthr-posix.h [neither FreeBSD nor Solaris] (__gthread_active_p):
        If __GLIBC__ is defined, refer to __pthread_key_create instead of
        pthread_cancel.

diff --git a/libgcc/gthr-posix.h b/libgcc/gthr-posix.h
index b5b1611..cc4e518 100644
--- a/libgcc/gthr-posix.h
+++ b/libgcc/gthr-posix.h
@@ -212,18 +212,43 @@ __gthread_active_p (void)
 
 #else /* neither FreeBSD nor Solaris */
 
+/* For a program to be multi-threaded the only thing that it certainly must
+   be using is pthread_create.  However, there may be other libraries that
+   intercept pthread_create with their own definitions to wrap pthreads
+   functionality for some purpose.  In those cases, pthread_create being
+   defined might not necessarily mean that libpthread is actually linked
+   in.
+
+   For the GNU C library, we can use a known internal name.  This is always
+   available in the ABI, but no other library would define it.  That is
+   ideal, since any public pthread function might be intercepted just as
+   pthread_create might be.  __pthread_key_create is an "internal"
+   implementation symbol, but it is part of the public exported ABI.  Also,
+   it's among the symbols that the static libpthread.a always links in
+   whenever pthread_create is used, so there is no danger of a false
+   negative result in any statically-linked, multi-threaded program.
+
+   For others, we choose pthread_cancel as a function that seems unlikely
+   to be redefined by an interceptor library.  The bionic (Android) C
+   library does not provide pthread_cancel, so we do use pthread_create
+   there (and interceptor libraries lose).  */
+
+#ifdef __GLIBC__
+__gthrw2(__gthrw_(__pthread_key_create),
+        __pthread_key_create,
+        pthread_key_create)
+# define GTHR_ACTIVE_PROXY     __gthrw_(__pthread_key_create)
+#elif defined (__BIONIC__)
+# define GTHR_ACTIVE_PROXY     __gthrw_(pthread_create)
+#else
+# define GTHR_ACTIVE_PROXY     __gthrw_(pthread_cancel)
+#endif
+
 static inline int
 __gthread_active_p (void)
 {
-/* Android's C library does not provide pthread_cancel, check for
-   `pthread_create' instead.  */
-#ifndef __BIONIC__
   static void *const __gthread_active_ptr
-    = __extension__ (void *) &__gthrw_(pthread_cancel);
-#else
-  static void *const __gthread_active_ptr
-    = __extension__ (void *) &__gthrw_(pthread_create);
-#endif
+    = __extension__ (void *) &GTHR_ACTIVE_PROXY;
   return __gthread_active_ptr != 0;
 }
 

Reply via email to