OSDN Git Service

PR target/24071
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Oct 2006 17:54:58 +0000 (17:54 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Oct 2006 17:54:58 +0000 (17:54 +0000)
* gthr-posix.h (__gthread_active_p): New implementation on Solaris.
* gthr-posix95.h (__gthread_active_p): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@118259 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gthr-posix.h
gcc/gthr-posix95.h

index 3c037f0..bb44011 100644 (file)
@@ -1,3 +1,9 @@
+2006-10-31  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.
+
 2006-10-31  Richard Guenther  <rguenther@suse.de>
 
        * config/i386/i386.md (asindf2, asinsf2, asinxf2, acosdf2,
index 62f83b3..fb58be9 100644 (file)
@@ -142,6 +142,59 @@ __gthrw(pthread_setschedparam)
 
 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
 
+/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
+   -pthreads is not specified.  The functions are dummies and most return an
+   error value.  However pthread_once returns 0 without invoking the routine
+   it is passed so we cannot pretend that the interface is active if -pthreads
+   is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
+   we need to play the usual game with weak symbols.  On Solaris 10 and up, a
+   working interface is always exposed.  */
+
+#if defined(__sun) && defined(__svr4__)
+
+static volatile 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;
+
+  /* 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))
+    {
+      if (__gthrw_(pthread_once))
+       {
+         /* If this really is a threaded program, then we must ensure that
+            __gthread_active has been set to 1 before exiting this block.  */
+         __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
+         __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
+         __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
+       }
+
+      /* Make sure we'll never enter this block again.  */
+      if (__gthread_active < 0)
+       __gthread_active = 0;
+
+      __gthread_active_latest_value = __gthread_active;
+    }
+
+  return __gthread_active_latest_value != 0;
+}
+
+#else /* not Solaris */
+
 static inline int
 __gthread_active_p (void)
 {
@@ -150,6 +203,8 @@ __gthread_active_p (void)
   return __gthread_active_ptr != 0;
 }
 
+#endif /* Solaris */
+
 #else /* not SUPPORTS_WEAK */
 
 static inline int
index 3a853ea..fde2645 100644 (file)
@@ -109,6 +109,59 @@ __gthrw(pthread_setschedparam)
 
 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
 
+/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
+   -pthreads is not specified.  The functions are dummies and most return an
+   error value.  However pthread_once returns 0 without invoking the routine
+   it is passed so we cannot pretend that the interface is active if -pthreads
+   is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
+   we need to play the usual game with weak symbols.  On Solaris 10 and up, a
+   working interface is always exposed.  */
+
+#if defined(__sun) && defined(__svr4__)
+
+static volatile 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;
+
+  /* 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))
+    {
+      if (__gthrw_(pthread_once))
+       {
+         /* If this really is a threaded program, then we must ensure that
+            __gthread_active has been set to 1 before exiting this block.  */
+         __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
+         __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
+         __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
+       }
+
+      /* Make sure we'll never enter this block again.  */
+      if (__gthread_active < 0)
+       __gthread_active = 0;
+
+      __gthread_active_latest_value = __gthread_active;
+    }
+
+  return __gthread_active_latest_value != 0;
+}
+
+#else /* not Solaris */
+
 static inline int
 __gthread_active_p (void)
 {
@@ -117,6 +170,8 @@ __gthread_active_p (void)
   return __gthread_active_ptr != 0;
 }
 
+#endif /* Solaris */
+
 #else /* not SUPPORTS_WEAK */
 
 static inline int