For GNU systems, the fact that libgcc/libstdc++ refers to pthread_cancel is
utterly bizarre.  I don't know of any rationale for this that has ever
applied to glibc.  AFAICT the choice was made based on the foibles of
various non-glibc systems.

In practice, things are working fine on GNU systems now, of course.  But
they'd work just as well for all extant glibc versions if the reference
were to pthread_create instead.  That's what makes clear sense on its face:
if the program is multithreaded, pthread_create is the one function that
certainly must have been linked in.

It is actively troublesome for the case of static linking.  It necessitates
linking in a lot of dead code in a program that uses pthreads but doesn't
use pthread_cancel.  It only actually works right at all because glibc
added a special hack to cope with this bizarre reference to pthread_cancel.
It would be nice if we could remove that someday.  (I don't intend to start
any general discussion here about the level of support for static linking.
It's just an example of what's nonsensical about this usage.)

With any kind of linking, it has whatever side effects linking in
pthread_cancel has.  There is at least one port of glibc (to a non-GNU
system) where pthread_cancel has a link-time warning because it's not fully
supported.  Getting this warning on every link that uses C++ at all is
rather bewildering, especially to application developers who don't use
pthreads directly at all or don't have any idea what pthread_cancel is.

What do folks think about this change?  It obviously should have no effect
whatsoever on builds not using glibc.  I'm pretty confident that it won't
have any bad effect on a build using any extant version of glibc that had
pthreads at all.


2012-01-26  Roland McGrath  <>

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

diff --git a/libgcc/gthr-posix.h b/libgcc/gthr-posix.h
index 46054f6..688253d 100644
--- a/libgcc/gthr-posix.h
+++ b/libgcc/gthr-posix.h
@@ -241,18 +241,24 @@ __gthread_active_p (void)
 #else /* neither FreeBSD nor Solaris */
+/* The bionic (Android) C library does not provide pthread_cancel.
+   The GNU C library provides pthread_cancel, but it is a poor
+   choice there.  For static linking, referring to pthread_cancel
+   causes it to be linked in even when it's never actually used.
+   For a program to be multi-threaded the only thing that it
+   certainly must be using is pthread_create.  */
+#if defined(__GLIBC__) || defined(__BIONIC__)
+# define GTHR_ACTIVE_PROXY     __gthrw_(pthread_create)
+# define GTHR_ACTIVE_PROXY     __gthrw_(pthread_cancel)
 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);
-  static void *const __gthread_active_ptr
-    = __extension__ (void *) &__gthrw_(pthread_create);
+    = __extension__ (void *) &GTHR_ACTIVE_PROXY;
   return __gthread_active_ptr != 0;

Reply via email to