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