summaryrefslogtreecommitdiff
path: root/libgcc/gthr-posix.h
diff options
context:
space:
mode:
authorRoland McGrath <mcgrathr@google.com>2012-06-11 21:15:38 +0000
committerRichard Henderson <rth@gcc.gnu.org>2012-06-11 14:15:38 -0700
commit67a218c536ea9df14dbfdf5f4d8c208b64e2225d (patch)
treee6c3bc6e891d604f2856261072188f5d68597d40 /libgcc/gthr-posix.h
parentd3843c672639d3bdd8242e2eb72572855d97216d (diff)
gthr-posix.h [...] (__gthread_active_p): If __GLIBC__ is defined, refer to __pthread_key_create instead of pthread_cancel.
* gthr-posix.h [neither FreeBSD nor Solaris] (__gthread_active_p): If __GLIBC__ is defined, refer to __pthread_key_create instead of pthread_cancel. From-SVN: r188400
Diffstat (limited to 'libgcc/gthr-posix.h')
-rw-r--r--libgcc/gthr-posix.h41
1 files changed, 33 insertions, 8 deletions
diff --git a/libgcc/gthr-posix.h b/libgcc/gthr-posix.h
index b5b161184f4..cc4e518f5b9 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;
}