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   static void *const __gthread_active_ptr
00243     = __extension__ (void *) &__gthrw_(
00244 /* Android's C library does not provide pthread_cancel, check for
00245    `pthread_create' instead.  */
00246 #ifndef __BIONIC__
00247                        pthread_cancel
00248 #else
00249                        pthread_create
00250 #endif
00251                        );
00252   return __gthread_active_ptr != 0;
00253 }
00254 
00255 #endif /* FreeBSD or Solaris */
00256 
00257 #else /* not __GXX_WEAK__ */
00258 
00259 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
00260    calls in shared flavors of the HP-UX C library.  Most of the stubs
00261    have no functionality.  The details are described in the "libc cumulative
00262    patch" for each subversion of HP-UX 11.  There are two special interfaces
00263    provided for checking whether an application is linked to a shared pthread
00264    library or not.  However, these interfaces aren't available in early
00265    libpthread libraries.  We also need a test that works for archive
00266    libraries.  We can't use pthread_once as some libc versions call the
00267    init function.  We also can't use pthread_create or pthread_attr_init
00268    as these create a thread and thereby prevent changing the default stack
00269    size.  The function pthread_default_stacksize_np is available in both
00270    the archive and shared versions of libpthread.   It can be used to
00271    determine the default pthread stack size.  There is a stub in some
00272    shared libc versions which returns a zero size if pthreads are not
00273    active.  We provide an equivalent stub to handle cases where libc
00274    doesn't provide one.  */
00275 
00276 #if defined(__hppa__) && defined(__hpux__)
00277 
00278 static volatile int __gthread_active = -1;
00279 
00280 static inline int
00281 __gthread_active_p (void)
00282 {
00283   /* Avoid reading __gthread_active twice on the main code path.  */
00284   int __gthread_active_latest_value = __gthread_active;
00285   size_t __s;
00286 
00287   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00288     {
00289       pthread_default_stacksize_np (0, &__s);
00290       __gthread_active = __s ? 1 : 0;
00291       __gthread_active_latest_value = __gthread_active;
00292     }
00293 
00294   return __gthread_active_latest_value != 0;
00295 }
00296 
00297 #else /* not hppa-hpux */
00298 
00299 static inline int
00300 __gthread_active_p (void)
00301 {
00302   return 1;
00303 }
00304 
00305 #endif /* hppa-hpux */
00306 
00307 #endif /* __GXX_WEAK__ */
00308 
00309 #ifdef _LIBOBJC
00310 
00311 /* This is the config.h file in libobjc/ */
00312 #include <config.h>
00313 
00314 #ifdef HAVE_SCHED_H
00315 # include <sched.h>
00316 #endif
00317 
00318 /* Key structure for maintaining thread specific storage */
00319 static pthread_key_t _objc_thread_storage;
00320 static pthread_attr_t _objc_thread_attribs;
00321 
00322 /* Thread local storage for a single thread */
00323 static void *thread_local_storage = NULL;
00324 
00325 /* Backend initialization functions */
00326 
00327 /* Initialize the threads subsystem.  */
00328 static inline int
00329 __gthread_objc_init_thread_system (void)
00330 {
00331   if (__gthread_active_p ())
00332     {
00333       /* Initialize the thread storage key.  */
00334       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
00335     {
00336       /* The normal default detach state for threads is
00337        * PTHREAD_CREATE_JOINABLE which causes threads to not die
00338        * when you think they should.  */
00339       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
00340           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
00341                           PTHREAD_CREATE_DETACHED) == 0)
00342         return 0;
00343     }
00344     }
00345 
00346   return -1;
00347 }
00348 
00349 /* Close the threads subsystem.  */
00350 static inline int
00351 __gthread_objc_close_thread_system (void)
00352 {
00353   if (__gthread_active_p ()
00354       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
00355       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
00356     return 0;
00357 
00358   return -1;
00359 }
00360 
00361 /* Backend thread functions */
00362 
00363 /* Create a new thread of execution.  */
00364 static inline objc_thread_t
00365 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00366 {
00367   objc_thread_t thread_id;
00368   pthread_t new_thread_handle;
00369 
00370   if (!__gthread_active_p ())
00371     return NULL;
00372 
00373   if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
00374                   (void *) func, arg)))
00375     thread_id = (objc_thread_t) new_thread_handle;
00376   else
00377     thread_id = NULL;
00378 
00379   return thread_id;
00380 }
00381 
00382 /* Set the current thread's priority.  */
00383 static inline int
00384 __gthread_objc_thread_set_priority (int priority)
00385 {
00386   if (!__gthread_active_p ())
00387     return -1;
00388   else
00389     {
00390 #ifdef _POSIX_PRIORITY_SCHEDULING
00391 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00392       pthread_t thread_id = __gthrw_(pthread_self) ();
00393       int policy;
00394       struct sched_param params;
00395       int priority_min, priority_max;
00396 
00397       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
00398     {
00399       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
00400         return -1;
00401 
00402       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
00403         return -1;
00404 
00405       if (priority > priority_max)
00406         priority = priority_max;
00407       else if (priority < priority_min)
00408         priority = priority_min;
00409       params.sched_priority = priority;
00410 
00411       /*
00412        * The solaris 7 and several other man pages incorrectly state that
00413        * this should be a pointer to policy but pthread.h is universally
00414        * at odds with this.
00415        */
00416       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
00417         return 0;
00418     }
00419 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00420 #endif /* _POSIX_PRIORITY_SCHEDULING */
00421       return -1;
00422     }
00423 }
00424 
00425 /* Return the current thread's priority.  */
00426 static inline int
00427 __gthread_objc_thread_get_priority (void)
00428 {
00429 #ifdef _POSIX_PRIORITY_SCHEDULING
00430 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00431   if (__gthread_active_p ())
00432     {
00433       int policy;
00434       struct sched_param params;
00435 
00436       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
00437     return params.sched_priority;
00438       else
00439     return -1;
00440     }
00441   else
00442 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00443 #endif /* _POSIX_PRIORITY_SCHEDULING */
00444     return OBJC_THREAD_INTERACTIVE_PRIORITY;
00445 }
00446 
00447 /* Yield our process time to another thread.  */
00448 static inline void
00449 __gthread_objc_thread_yield (void)
00450 {
00451   if (__gthread_active_p ())
00452     __gthrw_(sched_yield) ();
00453 }
00454 
00455 /* Terminate the current thread.  */
00456 static inline int
00457 __gthread_objc_thread_exit (void)
00458 {
00459   if (__gthread_active_p ())
00460     /* exit the thread */
00461     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
00462 
00463   /* Failed if we reached here */
00464   return -1;
00465 }
00466 
00467 /* Returns an integer value which uniquely describes a thread.  */
00468 static inline objc_thread_t
00469 __gthread_objc_thread_id (void)
00470 {
00471   if (__gthread_active_p ())
00472     return (objc_thread_t) __gthrw_(pthread_self) ();
00473   else
00474     return (objc_thread_t) 1;
00475 }
00476 
00477 /* Sets the thread's local storage pointer.  */
00478 static inline int
00479 __gthread_objc_thread_set_data (void *value)
00480 {
00481   if (__gthread_active_p ())
00482     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
00483   else
00484     {
00485       thread_local_storage = value;
00486       return 0;
00487     }
00488 }
00489 
00490 /* Returns the thread's local storage pointer.  */
00491 static inline void *
00492 __gthread_objc_thread_get_data (void)
00493 {
00494   if (__gthread_active_p ())
00495     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
00496   else
00497     return thread_local_storage;
00498 }
00499 
00500 /* Backend mutex functions */
00501 
00502 /* Allocate a mutex.  */
00503 static inline int
00504 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00505 {
00506   if (__gthread_active_p ())
00507     {
00508       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
00509 
00510       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
00511     {
00512       objc_free (mutex->backend);
00513       mutex->backend = NULL;
00514       return -1;
00515     }
00516     }
00517 
00518   return 0;
00519 }
00520 
00521 /* Deallocate a mutex.  */
00522 static inline int
00523 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00524 {
00525   if (__gthread_active_p ())
00526     {
00527       int count;
00528 
00529       /*
00530        * Posix Threads specifically require that the thread be unlocked
00531        * for __gthrw_(pthread_mutex_destroy) to work.
00532        */
00533 
00534       do
00535     {
00536       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
00537       if (count < 0)
00538         return -1;
00539     }
00540       while (count);
00541 
00542       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
00543     return -1;
00544 
00545       objc_free (mutex->backend);
00546       mutex->backend = NULL;
00547     }
00548   return 0;
00549 }
00550 
00551 /* Grab a lock on a mutex.  */
00552 static inline int
00553 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00554 {
00555   if (__gthread_active_p ()
00556       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
00557     {
00558       return -1;
00559     }
00560 
00561   return 0;
00562 }
00563 
00564 /* Try to grab a lock on a mutex.  */
00565 static inline int
00566 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00567 {
00568   if (__gthread_active_p ()
00569       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
00570     {
00571       return -1;
00572     }
00573 
00574   return 0;
00575 }
00576 
00577 /* Unlock the mutex */
00578 static inline int
00579 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00580 {
00581   if (__gthread_active_p ()
00582       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
00583     {
00584       return -1;
00585     }
00586 
00587   return 0;
00588 }
00589 
00590 /* Backend condition mutex functions */
00591 
00592 /* Allocate a condition.  */
00593 static inline int
00594 __gthread_objc_condition_allocate (objc_condition_t condition)
00595 {
00596   if (__gthread_active_p ())
00597     {
00598       condition->backend = objc_malloc (sizeof (pthread_cond_t));
00599 
00600       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
00601     {
00602       objc_free (condition->backend);
00603       condition->backend = NULL;
00604       return -1;
00605     }
00606     }
00607 
00608   return 0;
00609 }
00610 
00611 /* Deallocate a condition.  */
00612 static inline int
00613 __gthread_objc_condition_deallocate (objc_condition_t condition)
00614 {
00615   if (__gthread_active_p ())
00616     {
00617       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
00618     return -1;
00619 
00620       objc_free (condition->backend);
00621       condition->backend = NULL;
00622     }
00623   return 0;
00624 }
00625 
00626 /* Wait on the condition */
00627 static inline int
00628 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00629 {
00630   if (__gthread_active_p ())
00631     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
00632                   (pthread_mutex_t *) mutex->backend);
00633   else
00634     return 0;
00635 }
00636 
00637 /* Wake up all threads waiting on this condition.  */
00638 static inline int
00639 __gthread_objc_condition_broadcast (objc_condition_t condition)
00640 {
00641   if (__gthread_active_p ())
00642     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
00643   else
00644     return 0;
00645 }
00646 
00647 /* Wake up one thread waiting on this condition.  */
00648 static inline int
00649 __gthread_objc_condition_signal (objc_condition_t condition)
00650 {
00651   if (__gthread_active_p ())
00652     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
00653   else
00654     return 0;
00655 }
00656 
00657 #else /* _LIBOBJC */
00658 
00659 static inline int
00660 __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
00661           void *__args)
00662 {
00663   return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
00664 }
00665 
00666 static inline int
00667 __gthread_join (__gthread_t __threadid, void **__value_ptr)
00668 {
00669   return __gthrw_(pthread_join) (__threadid, __value_ptr);
00670 }
00671 
00672 static inline int
00673 __gthread_detach (__gthread_t __threadid)
00674 {
00675   return __gthrw_(pthread_detach) (__threadid);
00676 }
00677 
00678 static inline int
00679 __gthread_equal (__gthread_t __t1, __gthread_t __t2)
00680 {
00681   return __gthrw_(pthread_equal) (__t1, __t2);
00682 }
00683 
00684 static inline __gthread_t
00685 __gthread_self (void)
00686 {
00687   return __gthrw_(pthread_self) ();
00688 }
00689 
00690 static inline int
00691 __gthread_yield (void)
00692 {
00693   return __gthrw_(sched_yield) ();
00694 }
00695 
00696 static inline int
00697 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
00698 {
00699   if (__gthread_active_p ())
00700     return __gthrw_(pthread_once) (__once, __func);
00701   else
00702     return -1;
00703 }
00704 
00705 static inline int
00706 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
00707 {
00708   return __gthrw_(pthread_key_create) (__key, __dtor);
00709 }
00710 
00711 static inline int
00712 __gthread_key_delete (__gthread_key_t __key)
00713 {
00714   return __gthrw_(pthread_key_delete) (__key);
00715 }
00716 
00717 static inline void *
00718 __gthread_getspecific (__gthread_key_t __key)
00719 {
00720   return __gthrw_(pthread_getspecific) (__key);
00721 }
00722 
00723 static inline int
00724 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
00725 {
00726   return __gthrw_(pthread_setspecific) (__key, __ptr);
00727 }
00728 
00729 static inline int
00730 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
00731 {
00732   if (__gthread_active_p ())
00733     return __gthrw_(pthread_mutex_destroy) (__mutex);
00734   else
00735     return 0;
00736 }
00737 
00738 static inline int
00739 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
00740 {
00741   if (__gthread_active_p ())
00742     return __gthrw_(pthread_mutex_lock) (__mutex);
00743   else
00744     return 0;
00745 }
00746 
00747 static inline int
00748 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
00749 {
00750   if (__gthread_active_p ())
00751     return __gthrw_(pthread_mutex_trylock) (__mutex);
00752   else
00753     return 0;
00754 }
00755 
00756 #ifdef _POSIX_TIMEOUTS
00757 #if _POSIX_TIMEOUTS >= 0
00758 static inline int
00759 __gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
00760                const __gthread_time_t *__abs_timeout)
00761 {
00762   if (__gthread_active_p ())
00763     return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
00764   else
00765     return 0;
00766 }
00767 #endif
00768 #endif
00769 
00770 static inline int
00771 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
00772 {
00773   if (__gthread_active_p ())
00774     return __gthrw_(pthread_mutex_unlock) (__mutex);
00775   else
00776     return 0;
00777 }
00778 
00779 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00780 static inline int
00781 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
00782 {
00783   if (__gthread_active_p ())
00784     {
00785       pthread_mutexattr_t __attr;
00786       int __r;
00787 
00788       __r = __gthrw_(pthread_mutexattr_init) (&__attr);
00789       if (!__r)
00790     __r = __gthrw_(pthread_mutexattr_settype) (&__attr,
00791                            PTHREAD_MUTEX_RECURSIVE);
00792       if (!__r)
00793     __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
00794       if (!__r)
00795     __r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
00796       return __r;
00797     }
00798   return 0;
00799 }
00800 #endif
00801 
00802 static inline int
00803 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
00804 {
00805   return __gthread_mutex_lock (__mutex);
00806 }
00807 
00808 static inline int
00809 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
00810 {
00811   return __gthread_mutex_trylock (__mutex);
00812 }
00813 
00814 #ifdef _POSIX_TIMEOUTS
00815 #if _POSIX_TIMEOUTS >= 0
00816 static inline int
00817 __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
00818                      const __gthread_time_t *__abs_timeout)
00819 {
00820   return __gthread_mutex_timedlock (__mutex, __abs_timeout);
00821 }
00822 #endif
00823 #endif
00824 
00825 static inline int
00826 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
00827 {
00828   return __gthread_mutex_unlock (__mutex);
00829 }
00830 
00831 static inline int
00832 __gthread_cond_broadcast (__gthread_cond_t *__cond)
00833 {
00834   return __gthrw_(pthread_cond_broadcast) (__cond);
00835 }
00836 
00837 static inline int
00838 __gthread_cond_signal (__gthread_cond_t *__cond)
00839 {
00840   return __gthrw_(pthread_cond_signal) (__cond);
00841 }
00842 
00843 static inline int
00844 __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
00845 {
00846   return __gthrw_(pthread_cond_wait) (__cond, __mutex);
00847 }
00848 
00849 static inline int
00850 __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
00851               const __gthread_time_t *__abs_timeout)
00852 {
00853   return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
00854 }
00855 
00856 static inline int
00857 __gthread_cond_wait_recursive (__gthread_cond_t *__cond,
00858                    __gthread_recursive_mutex_t *__mutex)
00859 {
00860   return __gthread_cond_wait (__cond, __mutex);
00861 }
00862 
00863 static inline int
00864 __gthread_cond_timedwait_recursive (__gthread_cond_t *__cond,
00865                     __gthread_recursive_mutex_t *__mutex,
00866                     const __gthread_time_t *__abs_timeout)
00867 {
00868   return __gthread_cond_timedwait (__cond, __mutex, __abs_timeout);
00869 }
00870 
00871 static inline int
00872 __gthread_cond_destroy (__gthread_cond_t* __cond)
00873 {
00874   return __gthrw_(pthread_cond_destroy) (__cond);
00875 }
00876 
00877 #endif /* _LIBOBJC */
00878 
00879 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */