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]

[PATCH] Fix PR target/24071


Hi Mark,

You may recall the glitch that happened for the 4.0.2 release on Solaris (a 
late patch for libstd++-v3 slightly broke the C++ compiler there because of a 
quirk of the OS, then Benjamin devised a workaround but it eventually did not 
make it into the release).

The scenario has just been replayed on the 4.2 branch: the fix for PR 29426 
totally breaks the C++ compiler on Solaris 2.6 and probably damages it on 
Solaris 7, 8 and 9 too.  So I think it's time to tackle the underlying 
problem, i.e. that __gthread_active_p () is not accurate on Solaris; Benjamin 
summarized the problem in the PR.

Tested on SPARC/Solaris 2.5.1, 2.6, 7, 8, 9 and 10.  OK for mainline and 4.2 
branch?


2006-10-28  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR target/24071
	* gthr-posix.h (__gthread_active_p): New implementation on Solaris.
	* gthr-posix95.h (__gthread_active_p): Likewise.


-- 
Eric Botcazou
Index: gthr-posix95.h
===================================================================
--- gthr-posix95.h	(revision 117947)
+++ gthr-posix95.h	(working copy)
@@ -109,6 +109,48 @@ __gthrw(pthread_setschedparam)
 
 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
 
+/* On Solaris 2.6 up to version 9, the libc exposes a POSIX threads interface
+   even if -pthreads (or -threads) is not specified.  It is dummy and most
+   functions return an error value.   However pthread_once returns 0 without
+   invoking the routine it is passed so we cannot simply pretend that the
+   interface is active if -pthreads is not specified.  On Solaris 2.5.1,
+   the interface is not exposed so we need to play the usual game with
+   weak symbols.  On Solaris 10 and up, a working interface is exposed.  */
+
+#if defined(__sun) && defined(__svr4__)
+
+static int __gthread_active = -1;
+
+static void
+__gthread_trigger (void)
+{
+  __gthread_active = 1;
+}
+
+static inline int
+__gthread_active_p (void)
+{
+  static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
+  static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
+
+  if (__gthread_active < 0)
+    {
+      if (__gthrw_(pthread_once))
+	{
+	  /* Ironically enough we cannot let several threads concurrently
+	     run precisely because pthread_once wouldn't behave evenly.  */
+	  __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
+	  __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
+	  __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
+	}
+      __gthread_active++;
+    }
+
+  return __gthread_active != 0;
+}
+
+#else /* not Solaris */
+
 static inline int
 __gthread_active_p (void)
 {
@@ -117,6 +159,8 @@ __gthread_active_p (void)
   return __gthread_active_ptr != 0;
 }
 
+#endif /* Solaris */
+
 #else /* not SUPPORTS_WEAK */
 
 static inline int
Index: gthr-posix.h
===================================================================
--- gthr-posix.h	(revision 117947)
+++ gthr-posix.h	(working copy)
@@ -142,6 +142,48 @@ __gthrw(pthread_setschedparam)
 
 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
 
+/* On Solaris 2.6 up to version 9, the libc exposes a POSIX threads interface
+   even if -pthreads (or -threads) is not specified.  It is dummy and most
+   functions return an error value.   However pthread_once returns 0 without
+   invoking the routine it is passed so we cannot simply pretend that the
+   interface is active if -pthreads is not specified.  On Solaris 2.5.1,
+   the interface is not exposed so we need to play the usual game with
+   weak symbols.  On Solaris 10 and up, a working interface is exposed.  */
+
+#if defined(__sun) && defined(__svr4__)
+
+static int __gthread_active = -1;
+
+static void
+__gthread_trigger (void)
+{
+  __gthread_active = 1;
+}
+
+static inline int
+__gthread_active_p (void)
+{
+  static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
+  static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
+
+  if (__gthread_active < 0)
+    {
+      if (__gthrw_(pthread_once))
+	{
+	  /* Ironically enough we cannot let several threads concurrently
+	     run precisely because pthread_once wouldn't behave evenly.  */
+	  __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
+	  __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
+	  __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
+	}
+      __gthread_active++;
+    }
+
+  return __gthread_active != 0;
+}
+
+#else /* not Solaris */
+
 static inline int
 __gthread_active_p (void)
 {
@@ -150,6 +192,8 @@ __gthread_active_p (void)
   return __gthread_active_ptr != 0;
 }
 
+#endif /* Solaris */
+
 #else /* not SUPPORTS_WEAK */
 
 static inline int

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