This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] PR target/33286: __gthread_active_p bug


The enclosed change fixes PR target/33286.  The dwarf_reg_size_table
wasn't being initialized on hpux11.00 because the stub implementation
of pthread_once doesn't call its init function.

Here we use pthread_create to distinguish whether the application has
been linked with libpthread or not.  The stub implementation of pthread_create
always returns the error number ENOSYS.  The non stub implementations
return with no error or error numbers other than ENOSYS.  The basic
structure of the change is similar to the Solaris implementation which
uses pthread_once.  I believe that this technique works with all hpux11
libc implementations.

The only real choice here is whether to create a joinable (default)
or detachable thread.  Here I went with a default as it was a bit
simpler.

Tested on hppa*-*-hpux11.11 and hppa*-*-hpux11.00 with no observed
regressions.

Committed to trunk.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2007-09-07  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	PR target/33286
	* gthr-posix.h (__gthread_active_p): Add implementation for hppa-hpux.
	(__gthread_active,__gthread_start, __gthread_active_init): New.
	* gthr-posix95.h: Likewise.

Index: gthr-posix.h
===================================================================
--- gthr-posix.h	(revision 128242)
+++ gthr-posix.h	(working copy)
@@ -211,12 +211,81 @@
 
 #else /* not SUPPORTS_WEAK */
 
+/* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
+   calls in shared flavors of the HP-UX C library.  Most of the stubs
+   have no functionality.  The details are described in the "libc cumulative
+   patch" for each subversion of HP-UX 11.  There are two special interfaces
+   provided for checking whether an application is linked to a pthread
+   library or not.  However, these interfaces aren't available in early
+   libc versions.  We also can't use pthread_once as some libc versions
+   call the init function.  So, we use pthread_create to check whether it
+   is possible to create a thread or not.  The stub implementation returns
+   the error number ENOSYS.  */
+
+#if defined(__hppa__) && defined(__hpux__)
+
+#include <errno.h>
+
+static volatile int __gthread_active = -1;
+
+static void *
+__gthread_start (void *arg __attribute__((unused)))
+{
+  return NULL;
+}
+
+static void __gthread_active_init (void) __attribute__((noinline));
+static void
+__gthread_active_init (void)
+{
+  static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
+  pthread_t t;
+  int result;
+
+  __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
+  if (__gthread_active < 0)
+    {
+      result = __gthrw_(pthread_create) (&t, NULL, __gthread_start, NULL);
+      if (result != ENOSYS)
+	{
+	  __gthread_active = 1;
+	  if (!result)
+	    __gthrw_(pthread_join) (t, NULL);
+	}
+      else
+	__gthread_active = 0;
+    }
+  __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
+}
+
 static inline int
 __gthread_active_p (void)
 {
+  /* Avoid reading __gthread_active twice on the main code path.  */
+  int __gthread_active_latest_value = __gthread_active;
+
+  /* This test is not protected to avoid taking a lock on the main code
+     path so every update of __gthread_active in a threaded program must
+     be atomic with regard to the result of the test.  */
+  if (__builtin_expect (__gthread_active_latest_value < 0, 0))
+    {
+      __gthread_active_init ();
+      __gthread_active_latest_value = __gthread_active;
+    }
+
+  return __gthread_active_latest_value != 0;
+}
+
+#else /* not hppa-hpux */
+
+static inline int
+__gthread_active_p (void)
+{
   return 1;
 }
 
+#endif /* hppa-hpux */
+
 #endif /* SUPPORTS_WEAK */
 
 #ifdef _LIBOBJC
Index: gthr-posix95.h
===================================================================
--- gthr-posix95.h	(revision 128242)
+++ gthr-posix95.h	(working copy)
@@ -1,6 +1,6 @@
 /* Threads compatibility routines for libgcc2 and libobjc.  */
 /* Compile this one with gcc.  */
-/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -174,12 +174,81 @@
 
 #else /* not SUPPORTS_WEAK */
 
+/* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
+   calls in shared flavors of the HP-UX C library.  Most of the stubs
+   have no functionality.  The details are described in the "libc cumulative
+   patch" for each subversion of HP-UX 11.  There are two special interfaces
+   provided for checking whether an application is linked to a pthread
+   library or not.  However, these interfaces aren't available in early
+   libc versions.  We also can't use pthread_once as some libc versions
+   call the init function.  So, we use pthread_create to check whether it
+   is possible to create a thread or not.  The stub implementation returns
+   the error number ENOSYS.  */
+
+#if defined(__hppa__) && defined(__hpux__)
+
+#include <errno.h>
+
+static volatile int __gthread_active = -1;
+
+static void *
+__gthread_start (void *arg __attribute__((unused)))
+{
+  return NULL;
+}
+
+static void __gthread_active_init (void) __attribute__((noinline));
+static void
+__gthread_active_init (void)
+{
+  static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
+  pthread_t t;
+  int result;
+
+  __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
+  if (__gthread_active < 0)
+    {
+      result = __gthrw_(pthread_create) (&t, NULL, __gthread_start, NULL);
+      if (result != ENOSYS)
+	{
+	  __gthread_active = 1;
+	  if (!result)
+	    __gthrw_(pthread_join) (t, NULL);
+	}
+      else
+	__gthread_active = 0;
+    }
+  __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
+}
+
 static inline int
 __gthread_active_p (void)
 {
+  /* Avoid reading __gthread_active twice on the main code path.  */
+  int __gthread_active_latest_value = __gthread_active;
+
+  /* This test is not protected to avoid taking a lock on the main code
+     path so every update of __gthread_active in a threaded program must
+     be atomic with regard to the result of the test.  */
+  if (__builtin_expect (__gthread_active_latest_value < 0, 0))
+    {
+      __gthread_active_init ();
+      __gthread_active_latest_value = __gthread_active;
+    }
+
+  return __gthread_active_latest_value != 0;
+}
+
+#else /* not hppa-hpux */
+
+static inline int
+__gthread_active_p (void)
+{
   return 1;
 }
 
+#endif /* hppa-hpux */
+
 #endif /* SUPPORTS_WEAK */
 
 #ifdef _LIBOBJC


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]