mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-17 18:00:55 +08:00
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
This commit is contained in:
parent
9e5ac75fe2
commit
efd6ef80ca
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user