libstdc++

gthr-posix.h

00001 /* Threads compatibility routines for libgcc2 and libobjc.  */
00002 /* Compile this one with gcc.  */
00003 /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
00004    2008, 2009, 2010 Free Software Foundation, Inc.
00005 
00006 This file is part of GCC.
00007 
00008 GCC is free software; you can redistribute it and/or modify it under
00009 the terms of the GNU General Public License as published by the Free
00010 Software Foundation; either version 3, or (at your option) any later
00011 version.
00012 
00013 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
00014 WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 Under Section 7 of GPL version 3, you are granted additional
00019 permissions described in the GCC Runtime Library Exception, version
00020 3.1, as published by the Free Software Foundation.
00021 
00022 You should have received a copy of the GNU General Public License and
00023 a copy of the GCC Runtime Library Exception along with this program;
00024 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00025 <http://www.gnu.org/licenses/>.  */
00026 
00027 #ifndef _GLIBCXX_GCC_GTHR_POSIX_H
00028 #define _GLIBCXX_GCC_GTHR_POSIX_H
00029 
00030 /* POSIX threads specific definitions.
00031    Easy, since the interface is just one-to-one mapping.  */
00032 
00033 #define __GTHREADS 1
00034 #define __GTHREADS_CXX0X 1
00035 
00036 /* Some implementations of <pthread.h> require this to be defined.  */
00037 #if !defined(_REENTRANT) && defined(__osf__)
00038 #define _REENTRANT 1
00039 #endif
00040 
00041 #include <pthread.h>
00042 #include <unistd.h>
00043 
00044 typedef pthread_t __gthread_t;
00045 typedef pthread_key_t __gthread_key_t;
00046 typedef pthread_once_t __gthread_once_t;
00047 typedef pthread_mutex_t __gthread_mutex_t;
00048 typedef pthread_mutex_t __gthread_recursive_mutex_t;
00049 typedef pthread_cond_t __gthread_cond_t;
00050 typedef struct timespec __gthread_time_t;
00051 
00052 /* POSIX like conditional variables are supported.  Please look at comments
00053    in gthr.h for details. */
00054 #define __GTHREAD_HAS_COND  1
00055 
00056 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
00057 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
00058 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
00059 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
00060 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
00061 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00062 #else
00063 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
00064 #endif
00065 #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
00066 #define __GTHREAD_TIME_INIT {0,0}
00067 
00068 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
00069 # ifndef __gthrw_pragma
00070 #  define __gthrw_pragma(pragma)
00071 # endif
00072 # define __gthrw2(name,name2,type) \
00073   static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
00074   __gthrw_pragma(weak type)
00075 # define __gthrw_(name) __gthrw_ ## name
00076 #else
00077 # define __gthrw2(name,name2,type)
00078 # define __gthrw_(name) name
00079 #endif
00080 
00081 /* Typically, __gthrw_foo is a weak reference to symbol foo.  */
00082 #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
00083 
00084 /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
00085    map a subset of the POSIX pthread API to mangled versions of their
00086    names.  */
00087 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
00088 #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
00089 __gthrw3(pthread_once)
00090 __gthrw3(pthread_getspecific)
00091 __gthrw3(pthread_setspecific)
00092 
00093 __gthrw3(pthread_create)
00094 __gthrw3(pthread_join)
00095 __gthrw3(pthread_detach)
00096 __gthrw3(pthread_equal)
00097 __gthrw3(pthread_self)
00098 __gthrw3(pthread_cancel)
00099 __gthrw3(sched_yield)
00100 
00101 __gthrw3(pthread_mutex_lock)
00102 __gthrw3(pthread_mutex_trylock)
00103 #ifdef _POSIX_TIMEOUTS
00104 #if _POSIX_TIMEOUTS >= 0
00105 __gthrw3(pthread_mutex_timedlock)
00106 #endif
00107 #endif /* _POSIX_TIMEOUTS */
00108 __gthrw3(pthread_mutex_unlock)
00109 __gthrw3(pthread_mutex_init)
00110 __gthrw3(pthread_mutex_destroy)
00111 
00112 __gthrw3(pthread_cond_broadcast)
00113 __gthrw3(pthread_cond_signal)
00114 __gthrw3(pthread_cond_wait)
00115 __gthrw3(pthread_cond_timedwait)
00116 __gthrw3(pthread_cond_destroy)
00117 #else
00118 __gthrw(pthread_once)
00119 __gthrw(pthread_getspecific)
00120 __gthrw(pthread_setspecific)
00121 
00122 __gthrw(pthread_create)
00123 __gthrw(pthread_join)
00124 __gthrw(pthread_equal)
00125 __gthrw(pthread_self)
00126 __gthrw(pthread_detach)
00127 #ifndef __BIONIC__
00128 __gthrw(pthread_cancel)
00129 #endif
00130 __gthrw(sched_yield)
00131 
00132 __gthrw(pthread_mutex_lock)
00133 __gthrw(pthread_mutex_trylock)
00134 #ifdef _POSIX_TIMEOUTS
00135 #if _POSIX_TIMEOUTS >= 0
00136 __gthrw(pthread_mutex_timedlock)
00137 #endif
00138 #endif /* _POSIX_TIMEOUTS */
00139 __gthrw(pthread_mutex_unlock)
00140 __gthrw(pthread_mutex_init)
00141 __gthrw(pthread_mutex_destroy)
00142 
00143 __gthrw(pthread_cond_broadcast)
00144 __gthrw(pthread_cond_signal)
00145 __gthrw(pthread_cond_wait)
00146 __gthrw(pthread_cond_timedwait)
00147 __gthrw(pthread_cond_destroy)
00148 #endif
00149 
00150 __gthrw(pthread_key_create)
00151 __gthrw(pthread_key_delete)
00152 __gthrw(pthread_mutexattr_init)
00153 __gthrw(pthread_mutexattr_settype)
00154 __gthrw(pthread_mutexattr_destroy)
00155 
00156 
00157 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
00158 /* Objective-C.  */
00159 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
00160 __gthrw3(pthread_cond_init)
00161 __gthrw3(pthread_exit)
00162 #else
00163 __gthrw(pthread_cond_init)
00164 __gthrw(pthread_exit)
00165 #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
00166 #ifdef _POSIX_PRIORITY_SCHEDULING
00167 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00168 __gthrw(sched_get_priority_max)
00169 __gthrw(sched_get_priority_min)
00170 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00171 #endif /* _POSIX_PRIORITY_SCHEDULING */
00172 __gthrw(pthread_attr_destroy)
00173 __gthrw(pthread_attr_init)
00174 __gthrw(pthread_attr_setdetachstate)
00175 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00176 __gthrw(pthread_getschedparam)
00177 __gthrw(pthread_setschedparam)
00178 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00179 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
00180 
00181 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
00182 
00183 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
00184    -pthreads is not specified.  The functions are dummies and most return an
00185    error value.  However pthread_once returns 0 without invoking the routine
00186    it is passed so we cannot pretend that the interface is active if -pthreads
00187    is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
00188    we need to play the usual game with weak symbols.  On Solaris 10 and up, a
00189    working interface is always exposed.  On FreeBSD 6 and later, libc also
00190    exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
00191    to 9 does.  FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
00192    which means the alternate __gthread_active_p below cannot be used there.  */
00193 
00194 #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
00195 
00196 static volatile int __gthread_active = -1;
00197 
00198 static void
00199 __gthread_trigger (void)
00200 {
00201   __gthread_active = 1;
00202 }
00203 
00204 static inline int
00205 __gthread_active_p (void)
00206 {
00207   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
00208   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
00209 
00210   /* Avoid reading __gthread_active twice on the main code path.  */
00211   int __gthread_active_latest_value = __gthread_active;
00212 
00213   /* This test is not protected to avoid taking a lock on the main code
00214      path so every update of __gthread_active in a threaded program must
00215      be atomic with regard to the result of the test.  */
00216   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00217     {
00218       if (__gthrw_(pthread_once))
00219     {
00220       /* If this really is a threaded program, then we must ensure that
00221          __gthread_active has been set to 1 before exiting this block.  */
00222       __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
00223       __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
00224       __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
00225     }
00226 
00227       /* Make sure we'll never enter this block again.  */
00228       if (__gthread_active < 0)
00229     __gthread_active = 0;
00230 
00231       __gthread_active_latest_value = __gthread_active;
00232     }
00233 
00234   return __gthread_active_latest_value != 0;
00235 }
00236 
00237 #else /* neither FreeBSD nor Solaris */
00238 
00239 static inline int
00240 __gthread_active_p (void)
00241 {
00242 /* Android's C library does not provide pthread_cancel, check for
00243    `pthread_create' instead.  */
00244 #ifndef __BIONIC__
00245   static void *const __gthread_active_ptr
00246     = __extension__ (void *) &__gthrw_(pthread_cancel);
00247 #else
00248   static void *const __gthread_active_ptr
00249     = __extension__ (void *) &__gthrw_(pthread_create);
00250 #endif
00251   return __gthread_active_ptr != 0;
00252 }
00253 
00254 #endif /* FreeBSD or Solaris */
00255 
00256 #else /* not __GXX_WEAK__ */
00257 
00258 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
00259    calls in shared flavors of the HP-UX C library.  Most of the stubs
00260    have no functionality.  The details are described in the "libc cumulative
00261    patch" for each subversion of HP-UX 11.  There are two special interfaces
00262    provided for checking whether an application is linked to a shared pthread
00263    library or not.  However, these interfaces aren't available in early
00264    libpthread libraries.  We also need a test that works for archive
00265    libraries.  We can't use pthread_once as some libc versions call the
00266    init function.  We also can't use pthread_create or pthread_attr_init
00267    as these create a thread and thereby prevent changing the default stack
00268    size.  The function pthread_default_stacksize_np is available in both
00269    the archive and shared versions of libpthread.   It can be used to
00270    determine the default pthread stack size.  There is a stub in some
00271    shared libc versions which returns a zero size if pthreads are not
00272    active.  We provide an equivalent stub to handle cases where libc
00273    doesn't provide one.  */
00274 
00275 #if defined(__hppa__) && defined(__hpux__)
00276 
00277 static volatile int __gthread_active = -1;
00278 
00279 static inline int
00280 __gthread_active_p (void)
00281 {
00282   /* Avoid reading __gthread_active twice on the main code path.  */
00283   int __gthread_active_latest_value = __gthread_active;
00284   size_t __s;
00285 
00286   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00287     {
00288       pthread_default_stacksize_np (0, &__s);
00289       __gthread_active = __s ? 1 : 0;
00290       __gthread_active_latest_value = __gthread_active;
00291     }
00292 
00293   return __gthread_active_latest_value != 0;
00294 }
00295 
00296 #else /* not hppa-hpux */
00297 
00298 static inline int
00299 __gthread_active_p (void)
00300 {
00301   return 1;
00302 }
00303 
00304 #endif /* hppa-hpux */
00305 
00306 #endif /* __GXX_WEAK__ */
00307 
00308 #ifdef _LIBOBJC
00309 
00310 /* This is the config.h file in libobjc/ */
00311 #include <config.h>
00312 
00313 #ifdef HAVE_SCHED_H
00314 # include <sched.h>
00315 #endif
00316 
00317 /* Key structure for maintaining thread specific storage */
00318 static pthread_key_t _objc_thread_storage;
00319 static pthread_attr_t _objc_thread_attribs;
00320 
00321 /* Thread local storage for a single thread */
00322 static void *thread_local_storage = NULL;
00323 
00324 /* Backend initialization functions */
00325 
00326 /* Initialize the threads subsystem.  */
00327 static inline int
00328 __gthread_objc_init_thread_system (void)
00329 {
00330   if (__gthread_active_p ())
00331     {
00332       /* Initialize the thread storage key.  */
00333       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
00334     {
00335       /* The normal default detach state for threads is
00336        * PTHREAD_CREATE_JOINABLE which causes threads to not die
00337        * when you think they should.  */
00338       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
00339           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
00340                           PTHREAD_CREATE_DETACHED) == 0)
00341         return 0;
00342     }
00343     }
00344 
00345   return -1;
00346 }
00347 
00348 /* Close the threads subsystem.  */
00349 static inline int
00350 __gthread_objc_close_thread_system (void)
00351 {
00352   if (__gthread_active_p ()
00353       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
00354       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
00355     return 0;
00356 
00357   return -1;
00358 }
00359 
00360 /* Backend thread functions */
00361 
00362 /* Create a new thread of execution.  */
00363 static inline objc_thread_t
00364 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00365 {
00366   objc_thread_t thread_id;
00367   pthread_t new_thread_handle;
00368 
00369   if (!__gthread_active_p ())
00370     return NULL;
00371 
00372   if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
00373                   (void *) func, arg)))
00374     thread_id = (objc_thread_t) new_thread_handle;
00375   else
00376     thread_id = NULL;
00377 
00378   return thread_id;
00379 }
00380 
00381 /* Set the current thread's priority.  */
00382 static inline int
00383 __gthread_objc_thread_set_priority (int priority)
00384 {
00385   if (!__gthread_active_p ())
00386     return -1;
00387   else
00388     {
00389 #ifdef _POSIX_PRIORITY_SCHEDULING
00390 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00391       pthread_t thread_id = __gthrw_(pthread_self) ();
00392       int policy;
00393       struct sched_param params;
00394       int priority_min, priority_max;
00395 
00396       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
00397     {
00398       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
00399         return -1;
00400 
00401       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
00402         return -1;
00403 
00404       if (priority > priority_max)
00405         priority = priority_max;
00406       else if (priority < priority_min)
00407         priority = priority_min;
00408       params.sched_priority = priority;
00409 
00410       /*
00411        * The solaris 7 and several other man pages incorrectly state that
00412        * this should be a pointer to policy but pthread.h is universally
00413        * at odds with this.
00414        */
00415       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
00416         return 0;
00417     }
00418 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00419 #endif /* _POSIX_PRIORITY_SCHEDULING */
00420       return -1;
00421     }
00422 }
00423 
00424 /* Return the current thread's priority.  */
00425 static inline int
00426 __gthread_objc_thread_get_priority (void)
00427 {
00428 #ifdef _POSIX_PRIORITY_SCHEDULING
00429 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00430   if (__gthread_active_p ())
00431     {
00432       int policy;
00433       struct sched_param params;
00434 
00435       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
00436     return params.sched_priority;
00437       else
00438     return -1;
00439     }
00440   else
00441 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00442 #endif /* _POSIX_PRIORITY_SCHEDULING */
00443     return OBJC_THREAD_INTERACTIVE_PRIORITY;
00444 }
00445 
00446 /* Yield our process time to another thread.  */
00447 static inline void
00448 __gthread_objc_thread_yield (void)
00449 {
00450   if (__gthread_active_p ())
00451     __gthrw_(sched_yield) ();
00452 }
00453 
00454 /* Terminate the current thread.  */
00455 static inline int
00456 __gthread_objc_thread_exit (void)
00457 {
00458   if (__gthread_active_p ())
00459     /* exit the thread */
00460     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
00461 
00462   /* Failed if we reached here */
00463   return -1;
00464 }
00465 
00466 /* Returns an integer value which uniquely describes a thread.  */
00467 static inline objc_thread_t
00468 __gthread_objc_thread_id (void)
00469 {
00470   if (__gthread_active_p ())
00471     return (objc_thread_t) __gthrw_(pthread_self) ();
00472   else
00473     return (objc_thread_t) 1;
00474 }
00475 
00476 /* Sets the thread's local storage pointer.  */
00477 static inline int
00478 __gthread_objc_thread_set_data (void *value)
00479 {
00480   if (__gthread_active_p ())
00481     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
00482   else
00483     {
00484       thread_local_storage = value;
00485       return 0;
00486     }
00487 }
00488 
00489 /* Returns the thread's local storage pointer.  */
00490 static inline void *
00491 __gthread_objc_thread_get_data (void)
00492 {
00493   if (__gthread_active_p ())
00494     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
00495   else
00496     return thread_local_storage;
00497 }
00498 
00499 /* Backend mutex functions */
00500 
00501 /* Allocate a mutex.  */
00502 static inline int
00503 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00504 {
00505   if (__gthread_active_p ())
00506     {
00507       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
00508 
00509       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
00510     {
00511       objc_free (mutex->backend);
00512       mutex->backend = NULL;
00513       return -1;
00514     }
00515     }
00516 
00517   return 0;
00518 }
00519 
00520 /* Deallocate a mutex.  */
00521 static inline int
00522 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00523 {
00524   if (__gthread_active_p ())
00525     {
00526       int count;
00527 
00528       /*
00529        * Posix Threads specifically require that the thread be unlocked
00530        * for __gthrw_(pthread_mutex_destroy) to work.
00531        */
00532 
00533       do
00534     {
00535       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
00536       if (count < 0)
00537         return -1;
00538     }
00539       while (count);
00540 
00541       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
00542     return -1;
00543 
00544       objc_free (mutex->backend);
00545       mutex->backend = NULL;
00546     }
00547   return 0;
00548 }
00549 
00550 /* Grab a lock on a mutex.  */
00551 static inline int
00552 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00553 {
00554   if (__gthread_active_p ()
00555       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
00556     {
00557       return -1;
00558     }
00559 
00560   return 0;
00561 }
00562 
00563 /* Try to grab a lock on a mutex.  */
00564 static inline int
00565 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00566 {
00567   if (__gthread_active_p ()
00568       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
00569     {
00570       return -1;
00571     }
00572 
00573   return 0;
00574 }
00575 
00576 /* Unlock the mutex */
00577 static inline int
00578 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00579 {
00580   if (__gthread_active_p ()
00581       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
00582     {
00583       return -1;
00584     }
00585 
00586   return 0;
00587 }
00588 
00589 /* Backend condition mutex functions */
00590 
00591 /* Allocate a condition.  */
00592 static inline int
00593 __gthread_objc_condition_allocate (objc_condition_t condition)
00594 {
00595   if (__gthread_active_p ())
00596     {
00597       condition->backend = objc_malloc (sizeof (pthread_cond_t));
00598 
00599       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
00600     {
00601       objc_free (condition->backend);
00602       condition->backend = NULL;
00603       return -1;
00604     }
00605     }
00606 
00607   return 0;
00608 }
00609 
00610 /* Deallocate a condition.  */
00611 static inline int
00612 __gthread_objc_condition_deallocate (objc_condition_t condition)
00613 {
00614   if (__gthread_active_p ())
00615     {
00616       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
00617     return -1;
00618 
00619       objc_free (condition->backend);
00620       condition->backend = NULL;
00621     }
00622   return 0;
00623 }
00624 
00625 /* Wait on the condition */
00626 static inline int
00627 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00628 {
00629   if (__gthread_active_p ())
00630     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
00631                   (pthread_mutex_t *) mutex->backend);
00632   else
00633     return 0;
00634 }
00635 
00636 /* Wake up all threads waiting on this condition.  */
00637 static inline int
00638 __gthread_objc_condition_broadcast (objc_condition_t condition)
00639 {
00640   if (__gthread_active_p ())
00641     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
00642   else
00643     return 0;
00644 }
00645 
00646 /* Wake up one thread waiting on this condition.  */
00647 static inline int
00648 __gthread_objc_condition_signal (objc_condition_t condition)
00649 {
00650   if (__gthread_active_p ())
00651     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
00652   else
00653     return 0;
00654 }
00655 
00656 #else /* _LIBOBJC */
00657 
00658 static inline int
00659 __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
00660           void *__args)
00661 {
00662   return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
00663 }
00664 
00665 static inline int
00666 __gthread_join (__gthread_t __threadid, void **__value_ptr)
00667 {
00668   return __gthrw_(pthread_join) (__threadid, __value_ptr);
00669 }
00670 
00671 static inline int
00672 __gthread_detach (__gthread_t __threadid)
00673 {
00674   return __gthrw_(pthread_detach) (__threadid);
00675 }
00676 
00677 static inline int
00678 __gthread_equal (__gthread_t __t1, __gthread_t __t2)
00679 {
00680   return __gthrw_(pthread_equal) (__t1, __t2);
00681 }
00682 
00683 static inline __gthread_t
00684 __gthread_self (void)
00685 {
00686   return __gthrw_(pthread_self) ();
00687 }
00688 
00689 static inline int
00690 __gthread_yield (void)
00691 {
00692   return __gthrw_(sched_yield) ();
00693 }
00694 
00695 static inline int
00696 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
00697 {
00698   if (__gthread_active_p ())
00699     return __gthrw_(pthread_once) (__once, __func);
00700   else
00701     return -1;
00702 }
00703 
00704 static inline int
00705 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
00706 {
00707   return __gthrw_(pthread_key_create) (__key, __dtor);
00708 }
00709 
00710 static inline int
00711 __gthread_key_delete (__gthread_key_t __key)
00712 {
00713   return __gthrw_(pthread_key_delete) (__key);
00714 }
00715 
00716 static inline void *
00717 __gthread_getspecific (__gthread_key_t __key)
00718 {
00719   return __gthrw_(pthread_getspecific) (__key);
00720 }
00721 
00722 static inline int
00723 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
00724 {
00725   return __gthrw_(pthread_setspecific) (__key, __ptr);
00726 }
00727 
00728 static inline int
00729 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
00730 {
00731   if (__gthread_active_p ())
00732     return __gthrw_(pthread_mutex_destroy) (__mutex);
00733   else
00734     return 0;
00735 }
00736 
00737 static inline int
00738 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
00739 {
00740   if (__gthread_active_p ())
00741     return __gthrw_(pthread_mutex_lock) (__mutex);
00742   else
00743     return 0;
00744 }
00745 
00746 static inline int
00747 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
00748 {
00749   if (__gthread_active_p ())
00750     return __gthrw_(pthread_mutex_trylock) (__mutex);
00751   else
00752     return 0;
00753 }
00754 
00755 #ifdef _POSIX_TIMEOUTS
00756 #if _POSIX_TIMEOUTS >= 0
00757 static inline int
00758 __gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
00759                const __gthread_time_t *__abs_timeout)
00760 {
00761   if (__gthread_active_p ())
00762     return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
00763   else
00764     return 0;
00765 }
00766 #endif
00767 #endif
00768 
00769 static inline int
00770 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
00771 {
00772   if (__gthread_active_p ())
00773     return __gthrw_(pthread_mutex_unlock) (__mutex);
00774   else
00775     return 0;
00776 }
00777 
00778 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00779 static inline int
00780 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
00781 {
00782   if (__gthread_active_p ())
00783     {
00784       pthread_mutexattr_t __attr;
00785       int __r;
00786 
00787       __r = __gthrw_(pthread_mutexattr_init) (&__attr);
00788       if (!__r)
00789     __r = __gthrw_(pthread_mutexattr_settype) (&__attr,
00790                            PTHREAD_MUTEX_RECURSIVE);
00791       if (!__r)
00792     __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
00793       if (!__r)
00794     __r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
00795       return __r;
00796     }
00797   return 0;
00798 }
00799 #endif
00800 
00801 static inline int
00802 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
00803 {
00804   return __gthread_mutex_lock (__mutex);
00805 }
00806 
00807 static inline int
00808 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
00809 {
00810   return __gthread_mutex_trylock (__mutex);
00811 }
00812 
00813 #ifdef _POSIX_TIMEOUTS
00814 #if _POSIX_TIMEOUTS >= 0
00815 static inline int
00816 __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
00817                      const __gthread_time_t *__abs_timeout)
00818 {
00819   return __gthread_mutex_timedlock (__mutex, __abs_timeout);
00820 }
00821 #endif
00822 #endif
00823 
00824 static inline int
00825 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
00826 {
00827   return __gthread_mutex_unlock (__mutex);
00828 }
00829 
00830 static inline int
00831 __gthread_cond_broadcast (__gthread_cond_t *__cond)
00832 {
00833   return __gthrw_(pthread_cond_broadcast) (__cond);
00834 }
00835 
00836 static inline int
00837 __gthread_cond_signal (__gthread_cond_t *__cond)
00838 {
00839   return __gthrw_(pthread_cond_signal) (__cond);
00840 }
00841 
00842 static inline int
00843 __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
00844 {
00845   return __gthrw_(pthread_cond_wait) (__cond, __mutex);
00846 }
00847 
00848 static inline int
00849 __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
00850               const __gthread_time_t *__abs_timeout)
00851 {
00852   return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
00853 }
00854 
00855 static inline int
00856 __gthread_cond_wait_recursive (__gthread_cond_t *__cond,
00857                    __gthread_recursive_mutex_t *__mutex)
00858 {
00859   return __gthread_cond_wait (__cond, __mutex);
00860 }
00861 
00862 static inline int
00863 __gthread_cond_timedwait_recursive (__gthread_cond_t *__cond,
00864                     __gthread_recursive_mutex_t *__mutex,
00865                     const __gthread_time_t *__abs_timeout)
00866 {
00867   return __gthread_cond_timedwait (__cond, __mutex, __abs_timeout);
00868 }
00869 
00870 static inline int
00871 __gthread_cond_destroy (__gthread_cond_t* __cond)
00872 {
00873   return __gthrw_(pthread_cond_destroy) (__cond);
00874 }
00875 
00876 #endif /* _LIBOBJC */
00877 
00878 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */