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