# 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    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 2, 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 You should have received a copy of the GNU General Public License
    00019 along with GCC; see the file COPYING.  If not, write to the Free
    00020 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    00021 02110-1301, USA.  */
    00022
    00023 /* As a special exception, if you link this library with other files,
    00024    some of which are compiled with GCC, to produce an executable,
    00025    this library does not by itself cause the resulting executable
    00026    to be covered by the GNU General Public License.
    00027    This exception does not however invalidate any other reasons why
    00028    the executable file might be covered by the GNU General Public License.  */
    00029
    00030 #ifndef _GLIBCXX_GCC_GTHR_POSIX_H
    00031 #define _GLIBCXX_GCC_GTHR_POSIX_H
    00032
    00033 /* POSIX threads specific definitions.
    00034    Easy, since the interface is just one-to-one mapping.  */
    00035
    00036 #define __GTHREADS 1
    00037
    00038 /* Some implementations of <pthread.h> require this to be defined.  */
    00039 #if !defined(_REENTRANT) && defined(__osf__)
    00040 #define _REENTRANT 1
    00041 #endif
    00042
    00043 #include <pthread.h>
    00044 #include <unistd.h>
    00045
    00046 typedef pthread_key_t __gthread_key_t;
    00047 typedef pthread_once_t __gthread_once_t;
    00048 typedef pthread_mutex_t __gthread_mutex_t;
    00049 typedef pthread_mutex_t __gthread_recursive_mutex_t;
    00050 typedef pthread_cond_t __gthread_cond_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
    00067 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
    00068 # ifndef __gthrw_pragma
    00069 #  define __gthrw_pragma(pragma)
    00070 # endif
    00071 # define __gthrw2(name,name2,type) \
    00072   static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
    00073   __gthrw_pragma(weak type)
    00074 # define __gthrw_(name) __gthrw_ ## name
    00075 #else
    00076 # define __gthrw2(name,name2,type)
    00077 # define __gthrw_(name) name
    00078 #endif
    00079
    00080 /* Typically, __gthrw_foo is a weak reference to symbol foo.  */
    00081 #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
    00082
    00083 /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
    00084    map a subset of the POSIX pthread API to mangled versions of their
    00085    names.  */
    00086 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
    00087 #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
    00088 __gthrw3(pthread_once)
    00089 __gthrw3(pthread_getspecific)
    00090 __gthrw3(pthread_setspecific)
    00091 __gthrw3(pthread_create)
    00092 __gthrw3(pthread_cancel)
    00093 __gthrw3(pthread_mutex_lock)
    00094 __gthrw3(pthread_mutex_trylock)
    00095 __gthrw3(pthread_mutex_unlock)
    00096 __gthrw3(pthread_mutex_init)
    00097 __gthrw3(pthread_cond_broadcast)
    00098 __gthrw3(pthread_cond_wait)
    00099 #else
    00100 __gthrw(pthread_once)
    00101 __gthrw(pthread_getspecific)
    00102 __gthrw(pthread_setspecific)
    00103 __gthrw(pthread_create)
    00104 __gthrw(pthread_cancel)
    00105 __gthrw(pthread_mutex_lock)
    00106 __gthrw(pthread_mutex_trylock)
    00107 __gthrw(pthread_mutex_unlock)
    00108 __gthrw(pthread_mutex_init)
    00109 __gthrw(pthread_cond_broadcast)
    00110 __gthrw(pthread_cond_wait)
    00111 #endif
    00112
    00113 __gthrw(pthread_key_create)
    00114 __gthrw(pthread_key_delete)
    00115 __gthrw(pthread_mutexattr_init)
    00116 __gthrw(pthread_mutexattr_settype)
    00117 __gthrw(pthread_mutexattr_destroy)
    00118
    00119
    00120 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
    00121 /* Objective-C.  */
    00122 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
    00123 __gthrw3(pthread_cond_destroy)
    00124 __gthrw3(pthread_cond_init)
    00125 __gthrw3(pthread_cond_signal)
    00126 __gthrw3(pthread_exit)
    00127 __gthrw3(pthread_mutex_destroy)
    00128 __gthrw3(pthread_self)
    00129 #else
    00130 __gthrw(pthread_cond_destroy)
    00131 __gthrw(pthread_cond_init)
    00132 __gthrw(pthread_cond_signal)
    00133 __gthrw(pthread_exit)
    00134 __gthrw(pthread_mutex_destroy)
    00135 __gthrw(pthread_self)
    00136 #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
    00137 #ifdef _POSIX_PRIORITY_SCHEDULING
    00138 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00139 __gthrw(sched_get_priority_max)
    00140 __gthrw(sched_get_priority_min)
    00141 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00142 #endif /* _POSIX_PRIORITY_SCHEDULING */
    00143 __gthrw(sched_yield)
    00144 __gthrw(pthread_attr_destroy)
    00145 __gthrw(pthread_attr_init)
    00146 __gthrw(pthread_attr_setdetachstate)
    00147 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00148 __gthrw(pthread_getschedparam)
    00149 __gthrw(pthread_setschedparam)
    00150 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00151 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
    00152
    00153 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
    00154
    00155 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
    00156    -pthreads is not specified.  The functions are dummies and most return an
    00157    error value.  However pthread_once returns 0 without invoking the routine
    00158    it is passed so we cannot pretend that the interface is active if -pthreads
    00159    is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
    00160    we need to play the usual game with weak symbols.  On Solaris 10 and up, a
    00161    working interface is always exposed.  */
    00162
    00163 #if defined(__sun) && defined(__svr4__)
    00164
    00165 static volatile int __gthread_active = -1;
    00166
    00167 static void
    00168 __gthread_trigger (void)
    00169 {
    00170   __gthread_active = 1;
    00171 }
    00172
    00173 static inline int
    00174 __gthread_active_p (void)
    00175 {
    00176   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
    00177   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
    00178
    00179   /* Avoid reading __gthread_active twice on the main code path.  */
    00180   int __gthread_active_latest_value = __gthread_active;
    00181
    00182   /* This test is not protected to avoid taking a lock on the main code
    00183      path so every update of __gthread_active in a threaded program must
    00184      be atomic with regard to the result of the test.  */
    00185   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
    00186     {
    00187       if (__gthrw_(pthread_once))
    00188     {
    00189       /* If this really is a threaded program, then we must ensure that
    00190          __gthread_active has been set to 1 before exiting this block.  */
    00191       __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
    00192       __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
    00193       __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
    00194     }
    00195
    00196       /* Make sure we'll never enter this block again.  */
    00197       if (__gthread_active < 0)
    00198     __gthread_active = 0;
    00199
    00200       __gthread_active_latest_value = __gthread_active;
    00201     }
    00202
    00203   return __gthread_active_latest_value != 0;
    00204 }
    00205
    00206 #else /* not Solaris */
    00207
    00208 static inline int
    00209 __gthread_active_p (void)
    00210 {
    00211   static void *const __gthread_active_ptr
    00212     = __extension__ (void *) &__gthrw_(pthread_cancel);
    00213   return __gthread_active_ptr != 0;
    00214 }
    00215
    00216 #endif /* Solaris */
    00217
    00218 #else /* not __GXX_WEAK__ */
    00219
    00220 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
    00221    calls in shared flavors of the HP-UX C library.  Most of the stubs
    00222    have no functionality.  The details are described in the "libc cumulative
    00223    patch" for each subversion of HP-UX 11.  There are two special interfaces
    00224    provided for checking whether an application is linked to a pthread
    00225    library or not.  However, these interfaces aren't available in early
    00226    libc versions.  We also can't use pthread_once as some libc versions
    00227    call the init function.  So, we use pthread_create to check whether it
    00228    is possible to create a thread or not.  The stub implementation returns
    00229    the error number ENOSYS.  */
    00230
    00231 #if defined(__hppa__) && defined(__hpux__)
    00232
    00233 #include <errno.h>
    00234
    00235 static volatile int __gthread_active = -1;
    00236
    00237 static void *
    00238 __gthread_start (void *arg __attribute__((unused)))
    00239 {
    00240   return NULL;
    00241 }
    00242
    00243 static void __gthread_active_init (void) __attribute__((noinline));
    00244 static void
    00245 __gthread_active_init (void)
    00246 {
    00247   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
    00248   pthread_t t;
    00249   pthread_attr_t a;
    00250   int result;
    00251
    00252   __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
    00253   if (__gthread_active < 0)
    00254     {
    00255       __gthrw_(pthread_attr_init) (&a);
    00256       __gthrw_(pthread_attr_setdetachstate) (&a, PTHREAD_CREATE_DETACHED);
    00257       result = __gthrw_(pthread_create) (&t, &a, __gthread_start, NULL);
    00258       if (result != ENOSYS)
    00259     __gthread_active = 1;
    00260       else
    00261     __gthread_active = 0;
    00262       __gthrw_(pthread_attr_destroy) (&a);
    00263     }
    00264   __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
    00265 }
    00266
    00267 static inline int
    00268 __gthread_active_p (void)
    00269 {
    00270   /* Avoid reading __gthread_active twice on the main code path.  */
    00271   int __gthread_active_latest_value = __gthread_active;
    00272
    00273   /* This test is not protected to avoid taking a lock on the main code
    00274      path so every update of __gthread_active in a threaded program must
    00275      be atomic with regard to the result of the test.  */
    00276   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
    00277     {
    00278       __gthread_active_init ();
    00279       __gthread_active_latest_value = __gthread_active;
    00280     }
    00281
    00282   return __gthread_active_latest_value != 0;
    00283 }
    00284
    00285 #else /* not hppa-hpux */
    00286
    00287 static inline int
    00288 __gthread_active_p (void)
    00289 {
    00290   return 1;
    00291 }
    00292
    00293 #endif /* hppa-hpux */
    00294
    00295 #endif /* __GXX_WEAK__ */
    00296
    00297 #ifdef _LIBOBJC
    00298
    00299 /* This is the config.h file in libobjc/ */
    00300 #include <config.h>
    00301
    00302 #ifdef HAVE_SCHED_H
    00303 # include <sched.h>
    00304 #endif
    00305
    00306 /* Key structure for maintaining thread specific storage */
    00307 static pthread_key_t _objc_thread_storage;
    00308 static pthread_attr_t _objc_thread_attribs;
    00309
    00310 /* Thread local storage for a single thread */
    00311 static void *thread_local_storage = NULL;
    00312
    00313 /* Backend initialization functions */
    00314
    00315 /* Initialize the threads subsystem.  */
    00316 static inline int
    00317 __gthread_objc_init_thread_system (void)
    00318 {
    00319   if (__gthread_active_p ())
    00320     {
    00321       /* Initialize the thread storage key.  */
    00322       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
    00323     {
    00324       /* The normal default detach state for threads is
    00325        * PTHREAD_CREATE_JOINABLE which causes threads to not die
    00326        * when you think they should.  */
    00327       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
    00328           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
    00329                           PTHREAD_CREATE_DETACHED) == 0)
    00330         return 0;
    00331     }
    00332     }
    00333
    00334   return -1;
    00335 }
    00336
    00337 /* Close the threads subsystem.  */
    00338 static inline int
    00339 __gthread_objc_close_thread_system (void)
    00340 {
    00341   if (__gthread_active_p ()
    00342       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
    00343       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
    00344     return 0;
    00345
    00346   return -1;
    00347 }
    00348
    00349 /* Backend thread functions */
    00350
    00351 /* Create a new thread of execution.  */
    00352 static inline objc_thread_t
    00353 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
    00354 {
    00355   objc_thread_t thread_id;
    00356   pthread_t new_thread_handle;
    00357
    00358   if (!__gthread_active_p ())
    00359     return NULL;
    00360
    00361   if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
    00362     thread_id = (objc_thread_t) new_thread_handle;
    00363   else
    00364     thread_id = NULL;
    00365
    00366   return thread_id;
    00367 }
    00368
    00369 /* Set the current thread's priority.  */
    00370 static inline int
    00371 __gthread_objc_thread_set_priority (int priority)
    00372 {
    00373   if (!__gthread_active_p ())
    00374     return -1;
    00375   else
    00376     {
    00377 #ifdef _POSIX_PRIORITY_SCHEDULING
    00378 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00379       pthread_t thread_id = __gthrw_(pthread_self) ();
    00380       int policy;
    00381       struct sched_param params;
    00382       int priority_min, priority_max;
    00383
    00384       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
    00385     {
    00386       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
    00387         return -1;
    00388
    00389       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
    00390         return -1;
    00391
    00392       if (priority > priority_max)
    00393         priority = priority_max;
    00394       else if (priority < priority_min)
    00395         priority = priority_min;
    00396       params.sched_priority = priority;
    00397
    00398       /*
    00399        * The solaris 7 and several other man pages incorrectly state that
    00400        * this should be a pointer to policy but pthread.h is universally
    00401        * at odds with this.
    00402        */
    00403       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
    00404         return 0;
    00405     }
    00406 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00407 #endif /* _POSIX_PRIORITY_SCHEDULING */
    00408       return -1;
    00409     }
    00410 }
    00411
    00412 /* Return the current thread's priority.  */
    00413 static inline int
    00414 __gthread_objc_thread_get_priority (void)
    00415 {
    00416 #ifdef _POSIX_PRIORITY_SCHEDULING
    00417 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00418   if (__gthread_active_p ())
    00419     {
    00420       int policy;
    00421       struct sched_param params;
    00422
    00423       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
    00424     return params.sched_priority;
    00425       else
    00426     return -1;
    00427     }
    00428   else
    00429 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00430 #endif /* _POSIX_PRIORITY_SCHEDULING */
    00431     return OBJC_THREAD_INTERACTIVE_PRIORITY;
    00432 }
    00433
    00434 /* Yield our process time to another thread.  */
    00435 static inline void
    00436 __gthread_objc_thread_yield (void)
    00437 {
    00438   if (__gthread_active_p ())
    00439     __gthrw_(sched_yield) ();
    00440 }
    00441
    00442 /* Terminate the current thread.  */
    00443 static inline int
    00444 __gthread_objc_thread_exit (void)
    00445 {
    00446   if (__gthread_active_p ())
    00447     /* exit the thread */
    00448     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
    00449
    00450   /* Failed if we reached here */
    00451   return -1;
    00452 }
    00453
    00454 /* Returns an integer value which uniquely describes a thread.  */
    00455 static inline objc_thread_t
    00456 __gthread_objc_thread_id (void)
    00457 {
    00458   if (__gthread_active_p ())
    00459     return (objc_thread_t) __gthrw_(pthread_self) ();
    00460   else
    00461     return (objc_thread_t) 1;
    00462 }
    00463
    00464 /* Sets the thread's local storage pointer.  */
    00465 static inline int
    00466 __gthread_objc_thread_set_data (void *value)
    00467 {
    00468   if (__gthread_active_p ())
    00469     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
    00470   else
    00471     {
    00472       thread_local_storage = value;
    00473       return 0;
    00474     }
    00475 }
    00476
    00477 /* Returns the thread's local storage pointer.  */
    00478 static inline void *
    00479 __gthread_objc_thread_get_data (void)
    00480 {
    00481   if (__gthread_active_p ())
    00482     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
    00483   else
    00484     return thread_local_storage;
    00485 }
    00486
    00487 /* Backend mutex functions */
    00488
    00489 /* Allocate a mutex.  */
    00490 static inline int
    00491 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
    00492 {
    00493   if (__gthread_active_p ())
    00494     {
    00495       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
    00496
    00497       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
    00498     {
    00499       objc_free (mutex->backend);
    00500       mutex->backend = NULL;
    00501       return -1;
    00502     }
    00503     }
    00504
    00505   return 0;
    00506 }
    00507
    00508 /* Deallocate a mutex.  */
    00509 static inline int
    00510 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
    00511 {
    00512   if (__gthread_active_p ())
    00513     {
    00514       int count;
    00515
    00516       /*
    00517        * Posix Threads specifically require that the thread be unlocked
    00518        * for __gthrw_(pthread_mutex_destroy) to work.
    00519        */
    00520
    00521       do
    00522     {
    00523       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
    00524       if (count < 0)
    00525         return -1;
    00526     }
    00527       while (count);
    00528
    00529       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
    00530     return -1;
    00531
    00532       objc_free (mutex->backend);
    00533       mutex->backend = NULL;
    00534     }
    00535   return 0;
    00536 }
    00537
    00538 /* Grab a lock on a mutex.  */
    00539 static inline int
    00540 __gthread_objc_mutex_lock (objc_mutex_t mutex)
    00541 {
    00542   if (__gthread_active_p ()
    00543       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
    00544     {
    00545       return -1;
    00546     }
    00547
    00548   return 0;
    00549 }
    00550
    00551 /* Try to grab a lock on a mutex.  */
    00552 static inline int
    00553 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
    00554 {
    00555   if (__gthread_active_p ()
    00556       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
    00557     {
    00558       return -1;
    00559     }
    00560
    00561   return 0;
    00562 }
    00563
    00564 /* Unlock the mutex */
    00565 static inline int
    00566 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
    00567 {
    00568   if (__gthread_active_p ()
    00569       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
    00570     {
    00571       return -1;
    00572     }
    00573
    00574   return 0;
    00575 }
    00576
    00577 /* Backend condition mutex functions */
    00578
    00579 /* Allocate a condition.  */
    00580 static inline int
    00581 __gthread_objc_condition_allocate (objc_condition_t condition)
    00582 {
    00583   if (__gthread_active_p ())
    00584     {
    00585       condition->backend = objc_malloc (sizeof (pthread_cond_t));
    00586
    00587       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
    00588     {
    00589       objc_free (condition->backend);
    00590       condition->backend = NULL;
    00591       return -1;
    00592     }
    00593     }
    00594
    00595   return 0;
    00596 }
    00597
    00598 /* Deallocate a condition.  */
    00599 static inline int
    00600 __gthread_objc_condition_deallocate (objc_condition_t condition)
    00601 {
    00602   if (__gthread_active_p ())
    00603     {
    00604       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
    00605     return -1;
    00606
    00607       objc_free (condition->backend);
    00608       condition->backend = NULL;
    00609     }
    00610   return 0;
    00611 }
    00612
    00613 /* Wait on the condition */
    00614 static inline int
    00615 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
    00616 {
    00617   if (__gthread_active_p ())
    00618     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
    00619                   (pthread_mutex_t *) mutex->backend);
    00620   else
    00621     return 0;
    00622 }
    00623
    00624 /* Wake up all threads waiting on this condition.  */
    00625 static inline int
    00626 __gthread_objc_condition_broadcast (objc_condition_t condition)
    00627 {
    00628   if (__gthread_active_p ())
    00629     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
    00630   else
    00631     return 0;
    00632 }
    00633
    00634 /* Wake up one thread waiting on this condition.  */
    00635 static inline int
    00636 __gthread_objc_condition_signal (objc_condition_t condition)
    00637 {
    00638   if (__gthread_active_p ())
    00639     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
    00640   else
    00641     return 0;
    00642 }
    00643
    00644 #else /* _LIBOBJC */
    00645
    00646 static inline int
    00647 __gthread_once (__gthread_once_t *once, void (*func) (void))
    00648 {
    00649   if (__gthread_active_p ())
    00650     return __gthrw_(pthread_once) (once, func);
    00651   else
    00652     return -1;
    00653 }
    00654
    00655 static inline int
    00656 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
    00657 {
    00658   return __gthrw_(pthread_key_create) (key, dtor);
    00659 }
    00660
    00661 static inline int
    00662 __gthread_key_delete (__gthread_key_t key)
    00663 {
    00664   return __gthrw_(pthread_key_delete) (key);
    00665 }
    00666
    00667 static inline void *
    00668 __gthread_getspecific (__gthread_key_t key)
    00669 {
    00670   return __gthrw_(pthread_getspecific) (key);
    00671 }
    00672
    00673 static inline int
    00674 __gthread_setspecific (__gthread_key_t key, const void *ptr)
    00675 {
    00676   return __gthrw_(pthread_setspecific) (key, ptr);
    00677 }
    00678
    00679 static inline int
    00680 __gthread_mutex_lock (__gthread_mutex_t *mutex)
    00681 {
    00682   if (__gthread_active_p ())
    00683     return __gthrw_(pthread_mutex_lock) (mutex);
    00684   else
    00685     return 0;
    00686 }
    00687
    00688 static inline int
    00689 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
    00690 {
    00691   if (__gthread_active_p ())
    00692     return __gthrw_(pthread_mutex_trylock) (mutex);
    00693   else
    00694     return 0;
    00695 }
    00696
    00697 static inline int
    00698 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
    00699 {
    00700   if (__gthread_active_p ())
    00701     return __gthrw_(pthread_mutex_unlock) (mutex);
    00702   else
    00703     return 0;
    00704 }
    00705
    00706 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
    00707 static inline int
    00708 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
    00709 {
    00710   if (__gthread_active_p ())
    00711     {
    00712       pthread_mutexattr_t attr;
    00713       int r;
    00714
    00715       r = __gthrw_(pthread_mutexattr_init) (&attr);
    00716       if (!r)
    00717     r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
    00718       if (!r)
    00719     r = __gthrw_(pthread_mutex_init) (mutex, &attr);
    00720       if (!r)
    00721     r = __gthrw_(pthread_mutexattr_destroy) (&attr);
    00722       return r;
    00723     }
    00724   return 0;
    00725 }
    00726 #endif
    00727
    00728 static inline int
    00729 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
    00730 {
    00731   return __gthread_mutex_lock (mutex);
    00732 }
    00733
    00734 static inline int
    00735 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
    00736 {
    00737   return __gthread_mutex_trylock (mutex);
    00738 }
    00739
    00740 static inline int
    00741 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
    00742 {
    00743   return __gthread_mutex_unlock (mutex);
    00744 }
    00745
    00746 static inline int
    00747 __gthread_cond_broadcast (__gthread_cond_t *cond)
    00748 {
    00749   return __gthrw_(pthread_cond_broadcast) (cond);
    00750 }
    00751
    00752 static inline int
    00753 __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex)
    00754 {
    00755   return __gthrw_(pthread_cond_wait) (cond, mutex);
    00756 }
    00757
    00758 static inline int
    00759 __gthread_cond_wait_recursive (__gthread_cond_t *cond,
    00760                    __gthread_recursive_mutex_t *mutex)
    00761 {
    00762   return __gthread_cond_wait (cond, mutex);
    00763 }
    00764
    00765 #endif /* _LIBOBJC */
    00766
    00767 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */