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