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