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