This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR target/24071
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Mark Mitchell <mark at codesourcery dot com>
- Date: Sat, 28 Oct 2006 12:13:05 +0200
- Subject: [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