Home | History | Annotate | Line # | Download | only in libgcc
      1  1.1       mrg /* Threads compatibility routines for libgcc2 and libobjc.  */
      2  1.1       mrg /* Compile this one with gcc.  */
      3  1.8       mrg /* Copyright (C) 1997-2024 Free Software Foundation, Inc.
      4  1.1       mrg 
      5  1.1       mrg This file is part of GCC.
      6  1.1       mrg 
      7  1.1       mrg GCC is free software; you can redistribute it and/or modify it under
      8  1.1       mrg the terms of the GNU General Public License as published by the Free
      9  1.1       mrg Software Foundation; either version 3, or (at your option) any later
     10  1.1       mrg version.
     11  1.1       mrg 
     12  1.1       mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1       mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  1.1       mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  1.1       mrg for more details.
     16  1.1       mrg 
     17  1.1       mrg Under Section 7 of GPL version 3, you are granted additional
     18  1.1       mrg permissions described in the GCC Runtime Library Exception, version
     19  1.1       mrg 3.1, as published by the Free Software Foundation.
     20  1.1       mrg 
     21  1.1       mrg You should have received a copy of the GNU General Public License and
     22  1.1       mrg a copy of the GCC Runtime Library Exception along with this program;
     23  1.1       mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24  1.1       mrg <http://www.gnu.org/licenses/>.  */
     25  1.1       mrg 
     26  1.1       mrg #ifndef GCC_GTHR_POSIX_H
     27  1.1       mrg #define GCC_GTHR_POSIX_H
     28  1.1       mrg 
     29  1.1       mrg /* POSIX threads specific definitions.
     30  1.1       mrg    Easy, since the interface is just one-to-one mapping.  */
     31  1.1       mrg 
     32  1.1       mrg #define __GTHREADS 1
     33  1.1       mrg #define __GTHREADS_CXX0X 1
     34  1.1       mrg 
     35  1.1       mrg #include <pthread.h>
     36  1.1       mrg 
     37  1.1       mrg #if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \
     38  1.1       mrg      || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK))
     39  1.1       mrg # include <unistd.h>
     40  1.1       mrg # if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0
     41  1.1       mrg #  define _GTHREAD_USE_MUTEX_TIMEDLOCK 1
     42  1.1       mrg # else
     43  1.1       mrg #  define _GTHREAD_USE_MUTEX_TIMEDLOCK 0
     44  1.1       mrg # endif
     45  1.1       mrg #endif
     46  1.1       mrg 
     47  1.1       mrg typedef pthread_t __gthread_t;
     48  1.1       mrg typedef pthread_key_t __gthread_key_t;
     49  1.1       mrg typedef pthread_once_t __gthread_once_t;
     50  1.1       mrg typedef pthread_mutex_t __gthread_mutex_t;
     51  1.8       mrg #ifndef __cplusplus
     52  1.8       mrg typedef pthread_rwlock_t __gthread_rwlock_t;
     53  1.8       mrg #endif
     54  1.1       mrg typedef pthread_mutex_t __gthread_recursive_mutex_t;
     55  1.1       mrg typedef pthread_cond_t __gthread_cond_t;
     56  1.1       mrg typedef struct timespec __gthread_time_t;
     57  1.1       mrg 
     58  1.1       mrg /* POSIX like conditional variables are supported.  Please look at comments
     59  1.1       mrg    in gthr.h for details. */
     60  1.1       mrg #define __GTHREAD_HAS_COND	1
     61  1.1       mrg 
     62  1.1       mrg #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
     63  1.1       mrg #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
     64  1.8       mrg #ifndef __cplusplus
     65  1.8       mrg #define __GTHREAD_RWLOCK_INIT PTHREAD_RWLOCK_INITIALIZER
     66  1.8       mrg #endif
     67  1.1       mrg #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
     68  1.1       mrg #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
     69  1.1       mrg #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
     70  1.1       mrg #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
     71  1.1       mrg #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
     72  1.1       mrg #else
     73  1.1       mrg #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
     74  1.1       mrg #endif
     75  1.1       mrg #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
     76  1.1       mrg #define __GTHREAD_TIME_INIT {0,0}
     77  1.1       mrg 
     78  1.1       mrg #ifdef _GTHREAD_USE_MUTEX_INIT_FUNC
     79  1.1       mrg # undef __GTHREAD_MUTEX_INIT
     80  1.1       mrg #endif
     81  1.1       mrg #ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
     82  1.1       mrg # undef __GTHREAD_RECURSIVE_MUTEX_INIT
     83  1.1       mrg # undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
     84  1.1       mrg # define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
     85  1.1       mrg #endif
     86  1.1       mrg #ifdef _GTHREAD_USE_COND_INIT_FUNC
     87  1.1       mrg # undef __GTHREAD_COND_INIT
     88  1.1       mrg # define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
     89  1.1       mrg #endif
     90  1.1       mrg 
     91  1.1       mrg #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
     92  1.1       mrg # ifndef __gthrw_pragma
     93  1.1       mrg #  define __gthrw_pragma(pragma)
     94  1.1       mrg # endif
     95  1.1       mrg # define __gthrw2(name,name2,type) \
     96  1.5       mrg   static __typeof(type) name \
     97  1.5       mrg     __attribute__ ((__weakref__(#name2), __copy__ (type))); \
     98  1.1       mrg   __gthrw_pragma(weak type)
     99  1.1       mrg # define __gthrw_(name) __gthrw_ ## name
    100  1.1       mrg #else
    101  1.1       mrg # define __gthrw2(name,name2,type)
    102  1.1       mrg # define __gthrw_(name) name
    103  1.1       mrg #endif
    104  1.1       mrg 
    105  1.1       mrg /* Typically, __gthrw_foo is a weak reference to symbol foo.  */
    106  1.1       mrg #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
    107  1.1       mrg 
    108  1.1       mrg __gthrw(pthread_once)
    109  1.1       mrg __gthrw(pthread_getspecific)
    110  1.1       mrg __gthrw(pthread_setspecific)
    111  1.1       mrg 
    112  1.1       mrg __gthrw(pthread_create)
    113  1.1       mrg __gthrw(pthread_join)
    114  1.1       mrg __gthrw(pthread_equal)
    115  1.1       mrg __gthrw(pthread_self)
    116  1.1       mrg __gthrw(pthread_detach)
    117  1.1       mrg #ifndef __BIONIC__
    118  1.1       mrg __gthrw(pthread_cancel)
    119  1.1       mrg #endif
    120  1.1       mrg __gthrw(sched_yield)
    121  1.1       mrg 
    122  1.1       mrg __gthrw(pthread_mutex_lock)
    123  1.1       mrg __gthrw(pthread_mutex_trylock)
    124  1.1       mrg #if _GTHREAD_USE_MUTEX_TIMEDLOCK
    125  1.1       mrg __gthrw(pthread_mutex_timedlock)
    126  1.1       mrg #endif
    127  1.1       mrg __gthrw(pthread_mutex_unlock)
    128  1.1       mrg __gthrw(pthread_mutex_init)
    129  1.1       mrg __gthrw(pthread_mutex_destroy)
    130  1.1       mrg 
    131  1.1       mrg __gthrw(pthread_cond_init)
    132  1.1       mrg __gthrw(pthread_cond_broadcast)
    133  1.1       mrg __gthrw(pthread_cond_signal)
    134  1.1       mrg __gthrw(pthread_cond_wait)
    135  1.1       mrg __gthrw(pthread_cond_timedwait)
    136  1.1       mrg __gthrw(pthread_cond_destroy)
    137  1.1       mrg 
    138  1.1       mrg __gthrw(pthread_key_create)
    139  1.1       mrg __gthrw(pthread_key_delete)
    140  1.1       mrg __gthrw(pthread_mutexattr_init)
    141  1.1       mrg __gthrw(pthread_mutexattr_settype)
    142  1.1       mrg __gthrw(pthread_mutexattr_destroy)
    143  1.1       mrg 
    144  1.8       mrg #ifndef __cplusplus
    145  1.8       mrg __gthrw(pthread_rwlock_rdlock)
    146  1.8       mrg __gthrw(pthread_rwlock_tryrdlock)
    147  1.8       mrg __gthrw(pthread_rwlock_wrlock)
    148  1.8       mrg __gthrw(pthread_rwlock_trywrlock)
    149  1.8       mrg __gthrw(pthread_rwlock_unlock)
    150  1.8       mrg #endif
    151  1.1       mrg 
    152  1.1       mrg #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
    153  1.1       mrg /* Objective-C.  */
    154  1.1       mrg __gthrw(pthread_exit)
    155  1.1       mrg #ifdef _POSIX_PRIORITY_SCHEDULING
    156  1.1       mrg #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    157  1.1       mrg __gthrw(sched_get_priority_max)
    158  1.1       mrg __gthrw(sched_get_priority_min)
    159  1.1       mrg #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    160  1.1       mrg #endif /* _POSIX_PRIORITY_SCHEDULING */
    161  1.1       mrg __gthrw(pthread_attr_destroy)
    162  1.1       mrg __gthrw(pthread_attr_init)
    163  1.1       mrg __gthrw(pthread_attr_setdetachstate)
    164  1.1       mrg #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    165  1.1       mrg __gthrw(pthread_getschedparam)
    166  1.1       mrg __gthrw(pthread_setschedparam)
    167  1.1       mrg #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    168  1.1       mrg #endif /* _LIBOBJC || _LIBOBJC_WEAK */
    169  1.1       mrg 
    170  1.1       mrg #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
    171  1.1       mrg 
    172  1.1       mrg /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
    173  1.1       mrg    -pthreads is not specified.  The functions are dummies and most return an
    174  1.1       mrg    error value.  However pthread_once returns 0 without invoking the routine
    175  1.1       mrg    it is passed so we cannot pretend that the interface is active if -pthreads
    176  1.1       mrg    is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
    177  1.1       mrg    we need to play the usual game with weak symbols.  On Solaris 10 and up, a
    178  1.1       mrg    working interface is always exposed.  On FreeBSD 6 and later, libc also
    179  1.1       mrg    exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
    180  1.1       mrg    to 9 does.  FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
    181  1.2  christos    which means the alternate __gthread_active_p below cannot be used there.
    182  1.2  christos    On NetBSD, linking with pthreads but without calling pthread_create()
    183  1.2  christos    makes std::call_once() so we do the same.
    184  1.2  christos */
    185  1.1       mrg 
    186  1.3       mrg #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) || defined(__NetBSD__)
    187  1.1       mrg 
    188  1.1       mrg static volatile int __gthread_active = -1;
    189  1.1       mrg 
    190  1.1       mrg static void
    191  1.1       mrg __gthread_trigger (void)
    192  1.1       mrg {
    193  1.1       mrg   __gthread_active = 1;
    194  1.1       mrg }
    195  1.1       mrg 
    196  1.1       mrg static inline int
    197  1.1       mrg __gthread_active_p (void)
    198  1.1       mrg {
    199  1.1       mrg   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
    200  1.1       mrg   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
    201  1.1       mrg 
    202  1.1       mrg   /* Avoid reading __gthread_active twice on the main code path.  */
    203  1.1       mrg   int __gthread_active_latest_value = __gthread_active;
    204  1.1       mrg 
    205  1.1       mrg   /* This test is not protected to avoid taking a lock on the main code
    206  1.1       mrg      path so every update of __gthread_active in a threaded program must
    207  1.1       mrg      be atomic with regard to the result of the test.  */
    208  1.1       mrg   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
    209  1.1       mrg     {
    210  1.1       mrg       if (__gthrw_(pthread_once))
    211  1.1       mrg 	{
    212  1.1       mrg 	  /* If this really is a threaded program, then we must ensure that
    213  1.1       mrg 	     __gthread_active has been set to 1 before exiting this block.  */
    214  1.1       mrg 	  __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
    215  1.1       mrg 	  __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
    216  1.1       mrg 	  __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
    217  1.1       mrg 	}
    218  1.1       mrg 
    219  1.1       mrg       /* Make sure we'll never enter this block again.  */
    220  1.1       mrg       if (__gthread_active < 0)
    221  1.1       mrg 	__gthread_active = 0;
    222  1.1       mrg 
    223  1.1       mrg       __gthread_active_latest_value = __gthread_active;
    224  1.1       mrg     }
    225  1.1       mrg 
    226  1.1       mrg   return __gthread_active_latest_value != 0;
    227  1.1       mrg }
    228  1.1       mrg 
    229  1.2  christos #else /* neither FreeBSD nor Solaris nor NetBSD */
    230  1.1       mrg 
    231  1.1       mrg /* For a program to be multi-threaded the only thing that it certainly must
    232  1.1       mrg    be using is pthread_create.  However, there may be other libraries that
    233  1.1       mrg    intercept pthread_create with their own definitions to wrap pthreads
    234  1.1       mrg    functionality for some purpose.  In those cases, pthread_create being
    235  1.1       mrg    defined might not necessarily mean that libpthread is actually linked
    236  1.1       mrg    in.
    237  1.1       mrg 
    238  1.1       mrg    For the GNU C library, we can use a known internal name.  This is always
    239  1.1       mrg    available in the ABI, but no other library would define it.  That is
    240  1.1       mrg    ideal, since any public pthread function might be intercepted just as
    241  1.1       mrg    pthread_create might be.  __pthread_key_create is an "internal"
    242  1.1       mrg    implementation symbol, but it is part of the public exported ABI.  Also,
    243  1.1       mrg    it's among the symbols that the static libpthread.a always links in
    244  1.1       mrg    whenever pthread_create is used, so there is no danger of a false
    245  1.1       mrg    negative result in any statically-linked, multi-threaded program.
    246  1.1       mrg 
    247  1.1       mrg    For others, we choose pthread_cancel as a function that seems unlikely
    248  1.1       mrg    to be redefined by an interceptor library.  The bionic (Android) C
    249  1.1       mrg    library does not provide pthread_cancel, so we do use pthread_create
    250  1.1       mrg    there (and interceptor libraries lose).  */
    251  1.1       mrg 
    252  1.1       mrg #ifdef __GLIBC__
    253  1.1       mrg __gthrw2(__gthrw_(__pthread_key_create),
    254  1.1       mrg 	 __pthread_key_create,
    255  1.1       mrg 	 pthread_key_create)
    256  1.1       mrg # define GTHR_ACTIVE_PROXY	__gthrw_(__pthread_key_create)
    257  1.1       mrg #elif defined (__BIONIC__)
    258  1.1       mrg # define GTHR_ACTIVE_PROXY	__gthrw_(pthread_create)
    259  1.1       mrg #else
    260  1.1       mrg # define GTHR_ACTIVE_PROXY	__gthrw_(pthread_cancel)
    261  1.1       mrg #endif
    262  1.1       mrg 
    263  1.1       mrg static inline int
    264  1.1       mrg __gthread_active_p (void)
    265  1.1       mrg {
    266  1.1       mrg   static void *const __gthread_active_ptr
    267  1.1       mrg     = __extension__ (void *) &GTHR_ACTIVE_PROXY;
    268  1.1       mrg   return __gthread_active_ptr != 0;
    269  1.1       mrg }
    270  1.1       mrg 
    271  1.2  christos #endif /* FreeBSD or Solaris or NetBSD */
    272  1.1       mrg 
    273  1.1       mrg #else /* not SUPPORTS_WEAK */
    274  1.1       mrg 
    275  1.1       mrg /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
    276  1.1       mrg    calls in shared flavors of the HP-UX C library.  Most of the stubs
    277  1.1       mrg    have no functionality.  The details are described in the "libc cumulative
    278  1.1       mrg    patch" for each subversion of HP-UX 11.  There are two special interfaces
    279  1.1       mrg    provided for checking whether an application is linked to a shared pthread
    280  1.1       mrg    library or not.  However, these interfaces aren't available in early
    281  1.1       mrg    libpthread libraries.  We also need a test that works for archive
    282  1.1       mrg    libraries.  We can't use pthread_once as some libc versions call the
    283  1.1       mrg    init function.  We also can't use pthread_create or pthread_attr_init
    284  1.1       mrg    as these create a thread and thereby prevent changing the default stack
    285  1.1       mrg    size.  The function pthread_default_stacksize_np is available in both
    286  1.1       mrg    the archive and shared versions of libpthread.   It can be used to
    287  1.1       mrg    determine the default pthread stack size.  There is a stub in some
    288  1.1       mrg    shared libc versions which returns a zero size if pthreads are not
    289  1.1       mrg    active.  We provide an equivalent stub to handle cases where libc
    290  1.1       mrg    doesn't provide one.  */
    291  1.1       mrg 
    292  1.1       mrg #if defined(__hppa__) && defined(__hpux__)
    293  1.1       mrg 
    294  1.1       mrg static volatile int __gthread_active = -1;
    295  1.1       mrg 
    296  1.1       mrg static inline int
    297  1.1       mrg __gthread_active_p (void)
    298  1.1       mrg {
    299  1.1       mrg   /* Avoid reading __gthread_active twice on the main code path.  */
    300  1.1       mrg   int __gthread_active_latest_value = __gthread_active;
    301  1.1       mrg   size_t __s;
    302  1.1       mrg 
    303  1.1       mrg   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
    304  1.1       mrg     {
    305  1.1       mrg       pthread_default_stacksize_np (0, &__s);
    306  1.1       mrg       __gthread_active = __s ? 1 : 0;
    307  1.1       mrg       __gthread_active_latest_value = __gthread_active;
    308  1.1       mrg     }
    309  1.1       mrg 
    310  1.1       mrg   return __gthread_active_latest_value != 0;
    311  1.1       mrg }
    312  1.1       mrg 
    313  1.1       mrg #else /* not hppa-hpux */
    314  1.1       mrg 
    315  1.1       mrg static inline int
    316  1.1       mrg __gthread_active_p (void)
    317  1.1       mrg {
    318  1.1       mrg   return 1;
    319  1.1       mrg }
    320  1.1       mrg 
    321  1.1       mrg #endif /* hppa-hpux */
    322  1.1       mrg 
    323  1.1       mrg #endif /* SUPPORTS_WEAK */
    324  1.1       mrg 
    325  1.1       mrg #ifdef _LIBOBJC
    326  1.1       mrg 
    327  1.1       mrg /* This is the config.h file in libobjc/ */
    328  1.1       mrg #include <config.h>
    329  1.1       mrg 
    330  1.1       mrg #ifdef HAVE_SCHED_H
    331  1.1       mrg # include <sched.h>
    332  1.1       mrg #endif
    333  1.1       mrg 
    334  1.1       mrg /* Key structure for maintaining thread specific storage */
    335  1.1       mrg static pthread_key_t _objc_thread_storage;
    336  1.1       mrg static pthread_attr_t _objc_thread_attribs;
    337  1.1       mrg 
    338  1.1       mrg /* Thread local storage for a single thread */
    339  1.1       mrg static void *thread_local_storage = NULL;
    340  1.1       mrg 
    341  1.1       mrg /* Backend initialization functions */
    342  1.1       mrg 
    343  1.1       mrg /* Initialize the threads subsystem.  */
    344  1.1       mrg static inline int
    345  1.1       mrg __gthread_objc_init_thread_system (void)
    346  1.1       mrg {
    347  1.1       mrg   if (__gthread_active_p ())
    348  1.1       mrg     {
    349  1.1       mrg       /* Initialize the thread storage key.  */
    350  1.1       mrg       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
    351  1.1       mrg 	{
    352  1.1       mrg 	  /* The normal default detach state for threads is
    353  1.1       mrg 	   * PTHREAD_CREATE_JOINABLE which causes threads to not die
    354  1.1       mrg 	   * when you think they should.  */
    355  1.1       mrg 	  if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
    356  1.1       mrg 	      && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
    357  1.1       mrg 					      PTHREAD_CREATE_DETACHED) == 0)
    358  1.1       mrg 	    return 0;
    359  1.1       mrg 	}
    360  1.1       mrg     }
    361  1.1       mrg 
    362  1.1       mrg   return -1;
    363  1.1       mrg }
    364  1.1       mrg 
    365  1.1       mrg /* Close the threads subsystem.  */
    366  1.1       mrg static inline int
    367  1.1       mrg __gthread_objc_close_thread_system (void)
    368  1.1       mrg {
    369  1.1       mrg   if (__gthread_active_p ()
    370  1.1       mrg       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
    371  1.1       mrg       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
    372  1.1       mrg     return 0;
    373  1.1       mrg 
    374  1.1       mrg   return -1;
    375  1.1       mrg }
    376  1.1       mrg 
    377  1.1       mrg /* Backend thread functions */
    378  1.1       mrg 
    379  1.1       mrg /* Create a new thread of execution.  */
    380  1.1       mrg static inline objc_thread_t
    381  1.1       mrg __gthread_objc_thread_detach (void (*func)(void *), void *arg)
    382  1.1       mrg {
    383  1.1       mrg   objc_thread_t thread_id;
    384  1.1       mrg   pthread_t new_thread_handle;
    385  1.1       mrg 
    386  1.1       mrg   if (!__gthread_active_p ())
    387  1.1       mrg     return NULL;
    388  1.1       mrg 
    389  1.1       mrg   if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
    390  1.1       mrg 				  (void *) func, arg)))
    391  1.1       mrg     thread_id = (objc_thread_t) new_thread_handle;
    392  1.1       mrg   else
    393  1.1       mrg     thread_id = NULL;
    394  1.1       mrg 
    395  1.1       mrg   return thread_id;
    396  1.1       mrg }
    397  1.1       mrg 
    398  1.1       mrg /* Set the current thread's priority.  */
    399  1.1       mrg static inline int
    400  1.1       mrg __gthread_objc_thread_set_priority (int priority)
    401  1.1       mrg {
    402  1.1       mrg   if (!__gthread_active_p ())
    403  1.1       mrg     return -1;
    404  1.1       mrg   else
    405  1.1       mrg     {
    406  1.1       mrg #ifdef _POSIX_PRIORITY_SCHEDULING
    407  1.1       mrg #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    408  1.1       mrg       pthread_t thread_id = __gthrw_(pthread_self) ();
    409  1.1       mrg       int policy;
    410  1.1       mrg       struct sched_param params;
    411  1.1       mrg       int priority_min, priority_max;
    412  1.1       mrg 
    413  1.1       mrg       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
    414  1.1       mrg 	{
    415  1.1       mrg 	  if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
    416  1.1       mrg 	    return -1;
    417  1.1       mrg 
    418  1.1       mrg 	  if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
    419  1.1       mrg 	    return -1;
    420  1.1       mrg 
    421  1.1       mrg 	  if (priority > priority_max)
    422  1.1       mrg 	    priority = priority_max;
    423  1.1       mrg 	  else if (priority < priority_min)
    424  1.1       mrg 	    priority = priority_min;
    425  1.1       mrg 	  params.sched_priority = priority;
    426  1.1       mrg 
    427  1.1       mrg 	  /*
    428  1.1       mrg 	   * The solaris 7 and several other man pages incorrectly state that
    429  1.1       mrg 	   * this should be a pointer to policy but pthread.h is universally
    430  1.1       mrg 	   * at odds with this.
    431  1.1       mrg 	   */
    432  1.1       mrg 	  if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
    433  1.1       mrg 	    return 0;
    434  1.1       mrg 	}
    435  1.1       mrg #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    436  1.1       mrg #endif /* _POSIX_PRIORITY_SCHEDULING */
    437  1.1       mrg       return -1;
    438  1.1       mrg     }
    439  1.1       mrg }
    440  1.1       mrg 
    441  1.1       mrg /* Return the current thread's priority.  */
    442  1.1       mrg static inline int
    443  1.1       mrg __gthread_objc_thread_get_priority (void)
    444  1.1       mrg {
    445  1.1       mrg #ifdef _POSIX_PRIORITY_SCHEDULING
    446  1.1       mrg #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    447  1.1       mrg   if (__gthread_active_p ())
    448  1.1       mrg     {
    449  1.1       mrg       int policy;
    450  1.1       mrg       struct sched_param params;
    451  1.1       mrg 
    452  1.1       mrg       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
    453  1.1       mrg 	return params.sched_priority;
    454  1.1       mrg       else
    455  1.1       mrg 	return -1;
    456  1.1       mrg     }
    457  1.1       mrg   else
    458  1.1       mrg #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    459  1.1       mrg #endif /* _POSIX_PRIORITY_SCHEDULING */
    460  1.1       mrg     return OBJC_THREAD_INTERACTIVE_PRIORITY;
    461  1.1       mrg }
    462  1.1       mrg 
    463  1.1       mrg /* Yield our process time to another thread.  */
    464  1.1       mrg static inline void
    465  1.1       mrg __gthread_objc_thread_yield (void)
    466  1.1       mrg {
    467  1.1       mrg   if (__gthread_active_p ())
    468  1.1       mrg     __gthrw_(sched_yield) ();
    469  1.1       mrg }
    470  1.1       mrg 
    471  1.1       mrg /* Terminate the current thread.  */
    472  1.1       mrg static inline int
    473  1.1       mrg __gthread_objc_thread_exit (void)
    474  1.1       mrg {
    475  1.1       mrg   if (__gthread_active_p ())
    476  1.1       mrg     /* exit the thread */
    477  1.1       mrg     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
    478  1.1       mrg 
    479  1.1       mrg   /* Failed if we reached here */
    480  1.1       mrg   return -1;
    481  1.1       mrg }
    482  1.1       mrg 
    483  1.1       mrg /* Returns an integer value which uniquely describes a thread.  */
    484  1.1       mrg static inline objc_thread_t
    485  1.1       mrg __gthread_objc_thread_id (void)
    486  1.1       mrg {
    487  1.1       mrg   if (__gthread_active_p ())
    488  1.1       mrg     return (objc_thread_t) __gthrw_(pthread_self) ();
    489  1.1       mrg   else
    490  1.1       mrg     return (objc_thread_t) 1;
    491  1.1       mrg }
    492  1.1       mrg 
    493  1.1       mrg /* Sets the thread's local storage pointer.  */
    494  1.1       mrg static inline int
    495  1.1       mrg __gthread_objc_thread_set_data (void *value)
    496  1.1       mrg {
    497  1.1       mrg   if (__gthread_active_p ())
    498  1.1       mrg     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
    499  1.1       mrg   else
    500  1.1       mrg     {
    501  1.1       mrg       thread_local_storage = value;
    502  1.1       mrg       return 0;
    503  1.1       mrg     }
    504  1.1       mrg }
    505  1.1       mrg 
    506  1.1       mrg /* Returns the thread's local storage pointer.  */
    507  1.1       mrg static inline void *
    508  1.1       mrg __gthread_objc_thread_get_data (void)
    509  1.1       mrg {
    510  1.1       mrg   if (__gthread_active_p ())
    511  1.1       mrg     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
    512  1.1       mrg   else
    513  1.1       mrg     return thread_local_storage;
    514  1.1       mrg }
    515  1.1       mrg 
    516  1.1       mrg /* Backend mutex functions */
    517  1.1       mrg 
    518  1.1       mrg /* Allocate a mutex.  */
    519  1.1       mrg static inline int
    520  1.1       mrg __gthread_objc_mutex_allocate (objc_mutex_t mutex)
    521  1.1       mrg {
    522  1.1       mrg   if (__gthread_active_p ())
    523  1.1       mrg     {
    524  1.1       mrg       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
    525  1.1       mrg 
    526  1.1       mrg       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
    527  1.1       mrg 	{
    528  1.1       mrg 	  objc_free (mutex->backend);
    529  1.1       mrg 	  mutex->backend = NULL;
    530  1.1       mrg 	  return -1;
    531  1.1       mrg 	}
    532  1.1       mrg     }
    533  1.1       mrg 
    534  1.1       mrg   return 0;
    535  1.1       mrg }
    536  1.1       mrg 
    537  1.1       mrg /* Deallocate a mutex.  */
    538  1.1       mrg static inline int
    539  1.1       mrg __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
    540  1.1       mrg {
    541  1.1       mrg   if (__gthread_active_p ())
    542  1.1       mrg     {
    543  1.1       mrg       int count;
    544  1.1       mrg 
    545  1.1       mrg       /*
    546  1.1       mrg        * Posix Threads specifically require that the thread be unlocked
    547  1.1       mrg        * for __gthrw_(pthread_mutex_destroy) to work.
    548  1.1       mrg        */
    549  1.1       mrg 
    550  1.1       mrg       do
    551  1.1       mrg 	{
    552  1.1       mrg 	  count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
    553  1.1       mrg 	  if (count < 0)
    554  1.1       mrg 	    return -1;
    555  1.1       mrg 	}
    556  1.1       mrg       while (count);
    557  1.1       mrg 
    558  1.1       mrg       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
    559  1.1       mrg 	return -1;
    560  1.1       mrg 
    561  1.1       mrg       objc_free (mutex->backend);
    562  1.1       mrg       mutex->backend = NULL;
    563  1.1       mrg     }
    564  1.1       mrg   return 0;
    565  1.1       mrg }
    566  1.1       mrg 
    567  1.1       mrg /* Grab a lock on a mutex.  */
    568  1.1       mrg static inline int
    569  1.1       mrg __gthread_objc_mutex_lock (objc_mutex_t mutex)
    570  1.1       mrg {
    571  1.1       mrg   if (__gthread_active_p ()
    572  1.1       mrg       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
    573  1.1       mrg     {
    574  1.1       mrg       return -1;
    575  1.1       mrg     }
    576  1.1       mrg 
    577  1.1       mrg   return 0;
    578  1.1       mrg }
    579  1.1       mrg 
    580  1.1       mrg /* Try to grab a lock on a mutex.  */
    581  1.1       mrg static inline int
    582  1.1       mrg __gthread_objc_mutex_trylock (objc_mutex_t mutex)
    583  1.1       mrg {
    584  1.1       mrg   if (__gthread_active_p ()
    585  1.1       mrg       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
    586  1.1       mrg     {
    587  1.1       mrg       return -1;
    588  1.1       mrg     }
    589  1.1       mrg 
    590  1.1       mrg   return 0;
    591  1.1       mrg }
    592  1.1       mrg 
    593  1.1       mrg /* Unlock the mutex */
    594  1.1       mrg static inline int
    595  1.1       mrg __gthread_objc_mutex_unlock (objc_mutex_t mutex)
    596  1.1       mrg {
    597  1.1       mrg   if (__gthread_active_p ()
    598  1.1       mrg       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
    599  1.1       mrg     {
    600  1.1       mrg       return -1;
    601  1.1       mrg     }
    602  1.1       mrg 
    603  1.1       mrg   return 0;
    604  1.1       mrg }
    605  1.1       mrg 
    606  1.1       mrg /* Backend condition mutex functions */
    607  1.1       mrg 
    608  1.1       mrg /* Allocate a condition.  */
    609  1.1       mrg static inline int
    610  1.1       mrg __gthread_objc_condition_allocate (objc_condition_t condition)
    611  1.1       mrg {
    612  1.1       mrg   if (__gthread_active_p ())
    613  1.1       mrg     {
    614  1.1       mrg       condition->backend = objc_malloc (sizeof (pthread_cond_t));
    615  1.1       mrg 
    616  1.1       mrg       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
    617  1.1       mrg 	{
    618  1.1       mrg 	  objc_free (condition->backend);
    619  1.1       mrg 	  condition->backend = NULL;
    620  1.1       mrg 	  return -1;
    621  1.1       mrg 	}
    622  1.1       mrg     }
    623  1.1       mrg 
    624  1.1       mrg   return 0;
    625  1.1       mrg }
    626  1.1       mrg 
    627  1.1       mrg /* Deallocate a condition.  */
    628  1.1       mrg static inline int
    629  1.1       mrg __gthread_objc_condition_deallocate (objc_condition_t condition)
    630  1.1       mrg {
    631  1.1       mrg   if (__gthread_active_p ())
    632  1.1       mrg     {
    633  1.1       mrg       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
    634  1.1       mrg 	return -1;
    635  1.1       mrg 
    636  1.1       mrg       objc_free (condition->backend);
    637  1.1       mrg       condition->backend = NULL;
    638  1.1       mrg     }
    639  1.1       mrg   return 0;
    640  1.1       mrg }
    641  1.1       mrg 
    642  1.1       mrg /* Wait on the condition */
    643  1.1       mrg static inline int
    644  1.1       mrg __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
    645  1.1       mrg {
    646  1.1       mrg   if (__gthread_active_p ())
    647  1.1       mrg     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
    648  1.1       mrg 			      (pthread_mutex_t *) mutex->backend);
    649  1.1       mrg   else
    650  1.1       mrg     return 0;
    651  1.1       mrg }
    652  1.1       mrg 
    653  1.1       mrg /* Wake up all threads waiting on this condition.  */
    654  1.1       mrg static inline int
    655  1.1       mrg __gthread_objc_condition_broadcast (objc_condition_t condition)
    656  1.1       mrg {
    657  1.1       mrg   if (__gthread_active_p ())
    658  1.1       mrg     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
    659  1.1       mrg   else
    660  1.1       mrg     return 0;
    661  1.1       mrg }
    662  1.1       mrg 
    663  1.1       mrg /* Wake up one thread waiting on this condition.  */
    664  1.1       mrg static inline int
    665  1.1       mrg __gthread_objc_condition_signal (objc_condition_t condition)
    666  1.1       mrg {
    667  1.1       mrg   if (__gthread_active_p ())
    668  1.1       mrg     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
    669  1.1       mrg   else
    670  1.1       mrg     return 0;
    671  1.1       mrg }
    672  1.1       mrg 
    673  1.1       mrg #else /* _LIBOBJC */
    674  1.1       mrg 
    675  1.1       mrg static inline int
    676  1.1       mrg __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
    677  1.1       mrg 		  void *__args)
    678  1.1       mrg {
    679  1.1       mrg   return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
    680  1.1       mrg }
    681  1.1       mrg 
    682  1.1       mrg static inline int
    683  1.1       mrg __gthread_join (__gthread_t __threadid, void **__value_ptr)
    684  1.1       mrg {
    685  1.1       mrg   return __gthrw_(pthread_join) (__threadid, __value_ptr);
    686  1.1       mrg }
    687  1.1       mrg 
    688  1.1       mrg static inline int
    689  1.1       mrg __gthread_detach (__gthread_t __threadid)
    690  1.1       mrg {
    691  1.1       mrg   return __gthrw_(pthread_detach) (__threadid);
    692  1.1       mrg }
    693  1.1       mrg 
    694  1.1       mrg static inline int
    695  1.1       mrg __gthread_equal (__gthread_t __t1, __gthread_t __t2)
    696  1.1       mrg {
    697  1.1       mrg   return __gthrw_(pthread_equal) (__t1, __t2);
    698  1.1       mrg }
    699  1.1       mrg 
    700  1.1       mrg static inline __gthread_t
    701  1.1       mrg __gthread_self (void)
    702  1.1       mrg {
    703  1.1       mrg   return __gthrw_(pthread_self) ();
    704  1.1       mrg }
    705  1.1       mrg 
    706  1.1       mrg static inline int
    707  1.1       mrg __gthread_yield (void)
    708  1.1       mrg {
    709  1.1       mrg   return __gthrw_(sched_yield) ();
    710  1.1       mrg }
    711  1.1       mrg 
    712  1.1       mrg static inline int
    713  1.1       mrg __gthread_once (__gthread_once_t *__once, void (*__func) (void))
    714  1.1       mrg {
    715  1.1       mrg   if (__gthread_active_p ())
    716  1.1       mrg     return __gthrw_(pthread_once) (__once, __func);
    717  1.1       mrg   else
    718  1.1       mrg     return -1;
    719  1.1       mrg }
    720  1.1       mrg 
    721  1.1       mrg static inline int
    722  1.1       mrg __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
    723  1.1       mrg {
    724  1.1       mrg   return __gthrw_(pthread_key_create) (__key, __dtor);
    725  1.1       mrg }
    726  1.1       mrg 
    727  1.1       mrg static inline int
    728  1.1       mrg __gthread_key_delete (__gthread_key_t __key)
    729  1.1       mrg {
    730  1.1       mrg   return __gthrw_(pthread_key_delete) (__key);
    731  1.1       mrg }
    732  1.1       mrg 
    733  1.1       mrg static inline void *
    734  1.1       mrg __gthread_getspecific (__gthread_key_t __key)
    735  1.1       mrg {
    736  1.1       mrg   return __gthrw_(pthread_getspecific) (__key);
    737  1.1       mrg }
    738  1.1       mrg 
    739  1.1       mrg static inline int
    740  1.1       mrg __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
    741  1.1       mrg {
    742  1.1       mrg   return __gthrw_(pthread_setspecific) (__key, __ptr);
    743  1.1       mrg }
    744  1.1       mrg 
    745  1.1       mrg static inline void
    746  1.1       mrg __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
    747  1.1       mrg {
    748  1.1       mrg   if (__gthread_active_p ())
    749  1.1       mrg     __gthrw_(pthread_mutex_init) (__mutex, NULL);
    750  1.1       mrg }
    751  1.1       mrg 
    752  1.1       mrg static inline int
    753  1.1       mrg __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
    754  1.1       mrg {
    755  1.1       mrg   if (__gthread_active_p ())
    756  1.1       mrg     return __gthrw_(pthread_mutex_destroy) (__mutex);
    757  1.1       mrg   else
    758  1.1       mrg     return 0;
    759  1.1       mrg }
    760  1.1       mrg 
    761  1.1       mrg static inline int
    762  1.1       mrg __gthread_mutex_lock (__gthread_mutex_t *__mutex)
    763  1.1       mrg {
    764  1.1       mrg   if (__gthread_active_p ())
    765  1.1       mrg     return __gthrw_(pthread_mutex_lock) (__mutex);
    766  1.1       mrg   else
    767  1.1       mrg     return 0;
    768  1.1       mrg }
    769  1.1       mrg 
    770  1.1       mrg static inline int
    771  1.1       mrg __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
    772  1.1       mrg {
    773  1.1       mrg   if (__gthread_active_p ())
    774  1.1       mrg     return __gthrw_(pthread_mutex_trylock) (__mutex);
    775  1.1       mrg   else
    776  1.1       mrg     return 0;
    777  1.1       mrg }
    778  1.1       mrg 
    779  1.1       mrg #if _GTHREAD_USE_MUTEX_TIMEDLOCK
    780  1.1       mrg static inline int
    781  1.1       mrg __gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
    782  1.1       mrg 			   const __gthread_time_t *__abs_timeout)
    783  1.1       mrg {
    784  1.1       mrg   if (__gthread_active_p ())
    785  1.1       mrg     return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
    786  1.1       mrg   else
    787  1.1       mrg     return 0;
    788  1.1       mrg }
    789  1.1       mrg #endif
    790  1.1       mrg 
    791  1.1       mrg static inline int
    792  1.1       mrg __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
    793  1.1       mrg {
    794  1.1       mrg   if (__gthread_active_p ())
    795  1.1       mrg     return __gthrw_(pthread_mutex_unlock) (__mutex);
    796  1.1       mrg   else
    797  1.1       mrg     return 0;
    798  1.1       mrg }
    799  1.1       mrg 
    800  1.1       mrg #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \
    801  1.1       mrg   || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC)
    802  1.1       mrg static inline int
    803  1.1       mrg __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
    804  1.1       mrg {
    805  1.1       mrg   if (__gthread_active_p ())
    806  1.1       mrg     {
    807  1.1       mrg       pthread_mutexattr_t __attr;
    808  1.1       mrg       int __r;
    809  1.1       mrg 
    810  1.1       mrg       __r = __gthrw_(pthread_mutexattr_init) (&__attr);
    811  1.1       mrg       if (!__r)
    812  1.1       mrg 	__r = __gthrw_(pthread_mutexattr_settype) (&__attr,
    813  1.1       mrg 						   PTHREAD_MUTEX_RECURSIVE);
    814  1.1       mrg       if (!__r)
    815  1.1       mrg 	__r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
    816  1.1       mrg       if (!__r)
    817  1.1       mrg 	__r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
    818  1.1       mrg       return __r;
    819  1.1       mrg     }
    820  1.1       mrg   return 0;
    821  1.1       mrg }
    822  1.1       mrg #endif
    823  1.1       mrg 
    824  1.1       mrg static inline int
    825  1.1       mrg __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
    826  1.1       mrg {
    827  1.1       mrg   return __gthread_mutex_lock (__mutex);
    828  1.1       mrg }
    829  1.1       mrg 
    830  1.1       mrg static inline int
    831  1.1       mrg __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
    832  1.1       mrg {
    833  1.1       mrg   return __gthread_mutex_trylock (__mutex);
    834  1.1       mrg }
    835  1.1       mrg 
    836  1.1       mrg #if _GTHREAD_USE_MUTEX_TIMEDLOCK
    837  1.1       mrg static inline int
    838  1.1       mrg __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
    839  1.1       mrg 				     const __gthread_time_t *__abs_timeout)
    840  1.1       mrg {
    841  1.1       mrg   return __gthread_mutex_timedlock (__mutex, __abs_timeout);
    842  1.1       mrg }
    843  1.1       mrg #endif
    844  1.1       mrg 
    845  1.1       mrg static inline int
    846  1.1       mrg __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
    847  1.1       mrg {
    848  1.1       mrg   return __gthread_mutex_unlock (__mutex);
    849  1.1       mrg }
    850  1.1       mrg 
    851  1.1       mrg static inline int
    852  1.1       mrg __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
    853  1.1       mrg {
    854  1.1       mrg   return __gthread_mutex_destroy (__mutex);
    855  1.1       mrg }
    856  1.1       mrg 
    857  1.1       mrg #ifdef _GTHREAD_USE_COND_INIT_FUNC
    858  1.1       mrg static inline void
    859  1.1       mrg __gthread_cond_init_function (__gthread_cond_t *__cond)
    860  1.1       mrg {
    861  1.1       mrg   if (__gthread_active_p ())
    862  1.1       mrg     __gthrw_(pthread_cond_init) (__cond, NULL);
    863  1.1       mrg }
    864  1.1       mrg #endif
    865  1.1       mrg 
    866  1.1       mrg static inline int
    867  1.1       mrg __gthread_cond_broadcast (__gthread_cond_t *__cond)
    868  1.1       mrg {
    869  1.1       mrg   return __gthrw_(pthread_cond_broadcast) (__cond);
    870  1.1       mrg }
    871  1.1       mrg 
    872  1.1       mrg static inline int
    873  1.1       mrg __gthread_cond_signal (__gthread_cond_t *__cond)
    874  1.1       mrg {
    875  1.1       mrg   return __gthrw_(pthread_cond_signal) (__cond);
    876  1.1       mrg }
    877  1.1       mrg 
    878  1.1       mrg static inline int
    879  1.1       mrg __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
    880  1.1       mrg {
    881  1.1       mrg   return __gthrw_(pthread_cond_wait) (__cond, __mutex);
    882  1.1       mrg }
    883  1.1       mrg 
    884  1.1       mrg static inline int
    885  1.1       mrg __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
    886  1.1       mrg 			  const __gthread_time_t *__abs_timeout)
    887  1.1       mrg {
    888  1.1       mrg   return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
    889  1.1       mrg }
    890  1.1       mrg 
    891  1.1       mrg static inline int
    892  1.1       mrg __gthread_cond_wait_recursive (__gthread_cond_t *__cond,
    893  1.1       mrg 			       __gthread_recursive_mutex_t *__mutex)
    894  1.1       mrg {
    895  1.1       mrg   return __gthread_cond_wait (__cond, __mutex);
    896  1.1       mrg }
    897  1.1       mrg 
    898  1.1       mrg static inline int
    899  1.1       mrg __gthread_cond_destroy (__gthread_cond_t* __cond)
    900  1.1       mrg {
    901  1.1       mrg   return __gthrw_(pthread_cond_destroy) (__cond);
    902  1.1       mrg }
    903  1.1       mrg 
    904  1.8       mrg #ifndef __cplusplus
    905  1.8       mrg static inline int
    906  1.8       mrg __gthread_rwlock_rdlock (__gthread_rwlock_t *__rwlock)
    907  1.8       mrg {
    908  1.8       mrg   if (__gthread_active_p ())
    909  1.8       mrg     return __gthrw_(pthread_rwlock_rdlock) (__rwlock);
    910  1.8       mrg   else
    911  1.8       mrg     return 0;
    912  1.8       mrg }
    913  1.8       mrg 
    914  1.8       mrg static inline int
    915  1.8       mrg __gthread_rwlock_tryrdlock (__gthread_rwlock_t *__rwlock)
    916  1.8       mrg {
    917  1.8       mrg   if (__gthread_active_p ())
    918  1.8       mrg     return __gthrw_(pthread_rwlock_tryrdlock) (__rwlock);
    919  1.8       mrg   else
    920  1.8       mrg     return 0;
    921  1.8       mrg }
    922  1.8       mrg 
    923  1.8       mrg static inline int
    924  1.8       mrg __gthread_rwlock_wrlock (__gthread_rwlock_t *__rwlock)
    925  1.8       mrg {
    926  1.8       mrg   if (__gthread_active_p ())
    927  1.8       mrg     return __gthrw_(pthread_rwlock_wrlock) (__rwlock);
    928  1.8       mrg   else
    929  1.8       mrg     return 0;
    930  1.8       mrg }
    931  1.8       mrg 
    932  1.8       mrg static inline int
    933  1.8       mrg __gthread_rwlock_trywrlock (__gthread_rwlock_t *__rwlock)
    934  1.8       mrg {
    935  1.8       mrg   if (__gthread_active_p ())
    936  1.8       mrg     return __gthrw_(pthread_rwlock_trywrlock) (__rwlock);
    937  1.8       mrg   else
    938  1.8       mrg     return 0;
    939  1.8       mrg }
    940  1.8       mrg 
    941  1.8       mrg static inline int
    942  1.8       mrg __gthread_rwlock_unlock (__gthread_rwlock_t *__rwlock)
    943  1.8       mrg {
    944  1.8       mrg   if (__gthread_active_p ())
    945  1.8       mrg     return __gthrw_(pthread_rwlock_unlock) (__rwlock);
    946  1.8       mrg   else
    947  1.8       mrg     return 0;
    948  1.8       mrg }
    949  1.8       mrg #endif
    950  1.8       mrg 
    951  1.1       mrg #endif /* _LIBOBJC */
    952  1.1       mrg 
    953  1.1       mrg #endif /* ! GCC_GTHR_POSIX_H */
    954