From: Eric Botcazou Date: Tue, 31 Oct 2006 17:54:58 +0000 (+0100) Subject: re PR target/24071 (__gthread_active_p vs __gthread_once) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=efd6ef80ca7d6de864faeb5835712729da984b62;p=gcc.git re PR target/24071 (__gthread_active_p vs __gthread_once) PR target/24071 * gthr-posix.h (__gthread_active_p): New implementation on Solaris. * gthr-posix95.h (__gthread_active_p): Likewise. From-SVN: r118259 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c037f0733f..bb44011e05c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-10-31 Eric Botcazou + + 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 * config/i386/i386.md (asindf2, asinsf2, asinxf2, acosdf2, diff --git a/gcc/gthr-posix.h b/gcc/gthr-posix.h index 62f83b3ffbc..fb58be94ea6 100644 --- a/gcc/gthr-posix.h +++ b/gcc/gthr-posix.h @@ -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 diff --git a/gcc/gthr-posix95.h b/gcc/gthr-posix95.h index 3a853eafd44..fde264594f8 100644 --- a/gcc/gthr-posix95.h +++ b/gcc/gthr-posix95.h @@ -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