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