1*84d9c625SLionel Sambuc /* This file is automatically generated. DO NOT EDIT! */ 2*84d9c625SLionel Sambuc /* Generated from: NetBSD: mknative-gcc,v 1.57 2011/07/01 02:11:14 mrg Exp */ 3*84d9c625SLionel Sambuc /* Generated from: NetBSD: mknative.common,v 1.9 2007/02/05 18:26:01 apb Exp */ 4*84d9c625SLionel Sambuc 5*84d9c625SLionel Sambuc /* Threads compatibility routines for libgcc2 and libobjc. */ 6*84d9c625SLionel Sambuc /* Compile this one with gcc. */ 7*84d9c625SLionel Sambuc /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 8*84d9c625SLionel Sambuc 2008, 2009, 2011 Free Software Foundation, Inc. 9*84d9c625SLionel Sambuc 10*84d9c625SLionel Sambuc This file is part of GCC. 11*84d9c625SLionel Sambuc 12*84d9c625SLionel Sambuc GCC is free software; you can redistribute it and/or modify it under 13*84d9c625SLionel Sambuc the terms of the GNU General Public License as published by the Free 14*84d9c625SLionel Sambuc Software Foundation; either version 3, or (at your option) any later 15*84d9c625SLionel Sambuc version. 16*84d9c625SLionel Sambuc 17*84d9c625SLionel Sambuc GCC is distributed in the hope that it will be useful, but WITHOUT ANY 18*84d9c625SLionel Sambuc WARRANTY; without even the implied warranty of MERCHANTABILITY or 19*84d9c625SLionel Sambuc FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20*84d9c625SLionel Sambuc for more details. 21*84d9c625SLionel Sambuc 22*84d9c625SLionel Sambuc Under Section 7 of GPL version 3, you are granted additional 23*84d9c625SLionel Sambuc permissions described in the GCC Runtime Library Exception, version 24*84d9c625SLionel Sambuc 3.1, as published by the Free Software Foundation. 25*84d9c625SLionel Sambuc 26*84d9c625SLionel Sambuc You should have received a copy of the GNU General Public License and 27*84d9c625SLionel Sambuc a copy of the GCC Runtime Library Exception along with this program; 28*84d9c625SLionel Sambuc see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 29*84d9c625SLionel Sambuc <http://www.gnu.org/licenses/>. */ 30*84d9c625SLionel Sambuc 31*84d9c625SLionel Sambuc #ifndef _GLIBCXX_GCC_GTHR_POSIX_H 32*84d9c625SLionel Sambuc #define _GLIBCXX_GCC_GTHR_POSIX_H 33*84d9c625SLionel Sambuc 34*84d9c625SLionel Sambuc /* POSIX threads specific definitions. 35*84d9c625SLionel Sambuc Easy, since the interface is just one-to-one mapping. */ 36*84d9c625SLionel Sambuc 37*84d9c625SLionel Sambuc #define __GTHREADS 1 38*84d9c625SLionel Sambuc #define __GTHREADS_CXX0X 1 39*84d9c625SLionel Sambuc 40*84d9c625SLionel Sambuc /* Some implementations of <pthread.h> require this to be defined. */ 41*84d9c625SLionel Sambuc #if !defined(_REENTRANT) && defined(__osf__) 42*84d9c625SLionel Sambuc #define _REENTRANT 1 43*84d9c625SLionel Sambuc #endif 44*84d9c625SLionel Sambuc 45*84d9c625SLionel Sambuc #include <pthread.h> 46*84d9c625SLionel Sambuc #include <unistd.h> 47*84d9c625SLionel Sambuc 48*84d9c625SLionel Sambuc typedef pthread_t __gthread_t; 49*84d9c625SLionel Sambuc typedef pthread_key_t __gthread_key_t; 50*84d9c625SLionel Sambuc typedef pthread_once_t __gthread_once_t; 51*84d9c625SLionel Sambuc typedef pthread_mutex_t __gthread_mutex_t; 52*84d9c625SLionel Sambuc typedef pthread_mutex_t __gthread_recursive_mutex_t; 53*84d9c625SLionel Sambuc typedef pthread_cond_t __gthread_cond_t; 54*84d9c625SLionel Sambuc typedef struct timespec __gthread_time_t; 55*84d9c625SLionel Sambuc 56*84d9c625SLionel Sambuc /* POSIX like conditional variables are supported. Please look at comments 57*84d9c625SLionel Sambuc in gthr.h for details. */ 58*84d9c625SLionel Sambuc #define __GTHREAD_HAS_COND 1 59*84d9c625SLionel Sambuc 60*84d9c625SLionel Sambuc #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER 61*84d9c625SLionel Sambuc #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT 62*84d9c625SLionel Sambuc #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 63*84d9c625SLionel Sambuc #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER 64*84d9c625SLionel Sambuc #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 65*84d9c625SLionel Sambuc #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 66*84d9c625SLionel Sambuc #else 67*84d9c625SLionel Sambuc #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 68*84d9c625SLionel Sambuc #endif 69*84d9c625SLionel Sambuc #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER 70*84d9c625SLionel Sambuc #define __GTHREAD_TIME_INIT {0,0} 71*84d9c625SLionel Sambuc 72*84d9c625SLionel Sambuc #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 73*84d9c625SLionel Sambuc # ifndef __gthrw_pragma 74*84d9c625SLionel Sambuc # define __gthrw_pragma(pragma) 75*84d9c625SLionel Sambuc # endif 76*84d9c625SLionel Sambuc # define __gthrw2(name,name2,type) \ 77*84d9c625SLionel Sambuc static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ 78*84d9c625SLionel Sambuc __gthrw_pragma(weak type) 79*84d9c625SLionel Sambuc # define __gthrw_(name) __gthrw_ ## name 80*84d9c625SLionel Sambuc #else 81*84d9c625SLionel Sambuc # define __gthrw2(name,name2,type) 82*84d9c625SLionel Sambuc # define __gthrw_(name) name 83*84d9c625SLionel Sambuc #endif 84*84d9c625SLionel Sambuc 85*84d9c625SLionel Sambuc /* Typically, __gthrw_foo is a weak reference to symbol foo. */ 86*84d9c625SLionel Sambuc #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) 87*84d9c625SLionel Sambuc 88*84d9c625SLionel Sambuc /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to 89*84d9c625SLionel Sambuc map a subset of the POSIX pthread API to mangled versions of their 90*84d9c625SLionel Sambuc names. */ 91*84d9c625SLionel Sambuc #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) 92*84d9c625SLionel Sambuc #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name) 93*84d9c625SLionel Sambuc __gthrw3(pthread_once) 94*84d9c625SLionel Sambuc __gthrw3(pthread_getspecific) 95*84d9c625SLionel Sambuc __gthrw3(pthread_setspecific) 96*84d9c625SLionel Sambuc 97*84d9c625SLionel Sambuc __gthrw3(pthread_create) 98*84d9c625SLionel Sambuc __gthrw3(pthread_join) 99*84d9c625SLionel Sambuc __gthrw3(pthread_detach) 100*84d9c625SLionel Sambuc __gthrw3(pthread_equal) 101*84d9c625SLionel Sambuc __gthrw3(pthread_self) 102*84d9c625SLionel Sambuc __gthrw3(pthread_cancel) 103*84d9c625SLionel Sambuc __gthrw3(sched_yield) 104*84d9c625SLionel Sambuc 105*84d9c625SLionel Sambuc __gthrw3(pthread_mutex_lock) 106*84d9c625SLionel Sambuc __gthrw3(pthread_mutex_trylock) 107*84d9c625SLionel Sambuc #ifdef _POSIX_TIMEOUTS 108*84d9c625SLionel Sambuc #if _POSIX_TIMEOUTS >= 0 109*84d9c625SLionel Sambuc __gthrw3(pthread_mutex_timedlock) 110*84d9c625SLionel Sambuc #endif 111*84d9c625SLionel Sambuc #endif /* _POSIX_TIMEOUTS */ 112*84d9c625SLionel Sambuc __gthrw3(pthread_mutex_unlock) 113*84d9c625SLionel Sambuc __gthrw3(pthread_mutex_init) 114*84d9c625SLionel Sambuc __gthrw3(pthread_mutex_destroy) 115*84d9c625SLionel Sambuc 116*84d9c625SLionel Sambuc __gthrw3(pthread_cond_broadcast) 117*84d9c625SLionel Sambuc __gthrw3(pthread_cond_signal) 118*84d9c625SLionel Sambuc __gthrw3(pthread_cond_wait) 119*84d9c625SLionel Sambuc __gthrw3(pthread_cond_timedwait) 120*84d9c625SLionel Sambuc __gthrw3(pthread_cond_destroy) 121*84d9c625SLionel Sambuc #else 122*84d9c625SLionel Sambuc __gthrw(pthread_once) 123*84d9c625SLionel Sambuc __gthrw(pthread_getspecific) 124*84d9c625SLionel Sambuc __gthrw(pthread_setspecific) 125*84d9c625SLionel Sambuc 126*84d9c625SLionel Sambuc __gthrw(pthread_create) 127*84d9c625SLionel Sambuc __gthrw(pthread_join) 128*84d9c625SLionel Sambuc __gthrw(pthread_equal) 129*84d9c625SLionel Sambuc __gthrw(pthread_self) 130*84d9c625SLionel Sambuc __gthrw(pthread_detach) 131*84d9c625SLionel Sambuc __gthrw(pthread_cancel) 132*84d9c625SLionel Sambuc __gthrw(sched_yield) 133*84d9c625SLionel Sambuc 134*84d9c625SLionel Sambuc __gthrw(pthread_mutex_lock) 135*84d9c625SLionel Sambuc __gthrw(pthread_mutex_trylock) 136*84d9c625SLionel Sambuc #ifdef _POSIX_TIMEOUTS 137*84d9c625SLionel Sambuc #if _POSIX_TIMEOUTS >= 0 138*84d9c625SLionel Sambuc __gthrw(pthread_mutex_timedlock) 139*84d9c625SLionel Sambuc #endif 140*84d9c625SLionel Sambuc #endif /* _POSIX_TIMEOUTS */ 141*84d9c625SLionel Sambuc __gthrw(pthread_mutex_unlock) 142*84d9c625SLionel Sambuc __gthrw(pthread_mutex_init) 143*84d9c625SLionel Sambuc __gthrw(pthread_mutex_destroy) 144*84d9c625SLionel Sambuc 145*84d9c625SLionel Sambuc __gthrw(pthread_cond_broadcast) 146*84d9c625SLionel Sambuc __gthrw(pthread_cond_signal) 147*84d9c625SLionel Sambuc __gthrw(pthread_cond_wait) 148*84d9c625SLionel Sambuc __gthrw(pthread_cond_timedwait) 149*84d9c625SLionel Sambuc __gthrw(pthread_cond_destroy) 150*84d9c625SLionel Sambuc #endif 151*84d9c625SLionel Sambuc 152*84d9c625SLionel Sambuc __gthrw(pthread_key_create) 153*84d9c625SLionel Sambuc __gthrw(pthread_key_delete) 154*84d9c625SLionel Sambuc __gthrw(pthread_mutexattr_init) 155*84d9c625SLionel Sambuc __gthrw(pthread_mutexattr_settype) 156*84d9c625SLionel Sambuc __gthrw(pthread_mutexattr_destroy) 157*84d9c625SLionel Sambuc 158*84d9c625SLionel Sambuc 159*84d9c625SLionel Sambuc #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) 160*84d9c625SLionel Sambuc /* Objective-C. */ 161*84d9c625SLionel Sambuc #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) 162*84d9c625SLionel Sambuc __gthrw3(pthread_cond_init) 163*84d9c625SLionel Sambuc __gthrw3(pthread_exit) 164*84d9c625SLionel Sambuc #else 165*84d9c625SLionel Sambuc __gthrw(pthread_cond_init) 166*84d9c625SLionel Sambuc __gthrw(pthread_exit) 167*84d9c625SLionel Sambuc #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */ 168*84d9c625SLionel Sambuc #ifdef _POSIX_PRIORITY_SCHEDULING 169*84d9c625SLionel Sambuc #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 170*84d9c625SLionel Sambuc __gthrw(sched_get_priority_max) 171*84d9c625SLionel Sambuc __gthrw(sched_get_priority_min) 172*84d9c625SLionel Sambuc #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 173*84d9c625SLionel Sambuc #endif /* _POSIX_PRIORITY_SCHEDULING */ 174*84d9c625SLionel Sambuc __gthrw(pthread_attr_destroy) 175*84d9c625SLionel Sambuc __gthrw(pthread_attr_init) 176*84d9c625SLionel Sambuc __gthrw(pthread_attr_setdetachstate) 177*84d9c625SLionel Sambuc #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 178*84d9c625SLionel Sambuc __gthrw(pthread_getschedparam) 179*84d9c625SLionel Sambuc __gthrw(pthread_setschedparam) 180*84d9c625SLionel Sambuc #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 181*84d9c625SLionel Sambuc #endif /* _LIBOBJC || _LIBOBJC_WEAK */ 182*84d9c625SLionel Sambuc 183*84d9c625SLionel Sambuc #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 184*84d9c625SLionel Sambuc 185*84d9c625SLionel Sambuc /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if 186*84d9c625SLionel Sambuc -pthreads is not specified. The functions are dummies and most return an 187*84d9c625SLionel Sambuc error value. However pthread_once returns 0 without invoking the routine 188*84d9c625SLionel Sambuc it is passed so we cannot pretend that the interface is active if -pthreads 189*84d9c625SLionel Sambuc is not specified. On Solaris 2.5.1, the interface is not exposed at all so 190*84d9c625SLionel Sambuc we need to play the usual game with weak symbols. On Solaris 10 and up, a 191*84d9c625SLionel Sambuc working interface is always exposed. On FreeBSD 6 and later, libc also 192*84d9c625SLionel Sambuc exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up 193*84d9c625SLionel Sambuc to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, 194*84d9c625SLionel Sambuc which means the alternate __gthread_active_p below cannot be used there. */ 195*84d9c625SLionel Sambuc 196*84d9c625SLionel Sambuc #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) 197*84d9c625SLionel Sambuc 198*84d9c625SLionel Sambuc static volatile int __gthread_active = -1; 199*84d9c625SLionel Sambuc 200*84d9c625SLionel Sambuc static void 201*84d9c625SLionel Sambuc __gthread_trigger (void) 202*84d9c625SLionel Sambuc { 203*84d9c625SLionel Sambuc __gthread_active = 1; 204*84d9c625SLionel Sambuc } 205*84d9c625SLionel Sambuc 206*84d9c625SLionel Sambuc static inline int 207*84d9c625SLionel Sambuc __gthread_active_p (void) 208*84d9c625SLionel Sambuc { 209*84d9c625SLionel Sambuc static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; 210*84d9c625SLionel Sambuc static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; 211*84d9c625SLionel Sambuc 212*84d9c625SLionel Sambuc /* Avoid reading __gthread_active twice on the main code path. */ 213*84d9c625SLionel Sambuc int __gthread_active_latest_value = __gthread_active; 214*84d9c625SLionel Sambuc 215*84d9c625SLionel Sambuc /* This test is not protected to avoid taking a lock on the main code 216*84d9c625SLionel Sambuc path so every update of __gthread_active in a threaded program must 217*84d9c625SLionel Sambuc be atomic with regard to the result of the test. */ 218*84d9c625SLionel Sambuc if (__builtin_expect (__gthread_active_latest_value < 0, 0)) 219*84d9c625SLionel Sambuc { 220*84d9c625SLionel Sambuc if (__gthrw_(pthread_once)) 221*84d9c625SLionel Sambuc { 222*84d9c625SLionel Sambuc /* If this really is a threaded program, then we must ensure that 223*84d9c625SLionel Sambuc __gthread_active has been set to 1 before exiting this block. */ 224*84d9c625SLionel Sambuc __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); 225*84d9c625SLionel Sambuc __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); 226*84d9c625SLionel Sambuc __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); 227*84d9c625SLionel Sambuc } 228*84d9c625SLionel Sambuc 229*84d9c625SLionel Sambuc /* Make sure we'll never enter this block again. */ 230*84d9c625SLionel Sambuc if (__gthread_active < 0) 231*84d9c625SLionel Sambuc __gthread_active = 0; 232*84d9c625SLionel Sambuc 233*84d9c625SLionel Sambuc __gthread_active_latest_value = __gthread_active; 234*84d9c625SLionel Sambuc } 235*84d9c625SLionel Sambuc 236*84d9c625SLionel Sambuc return __gthread_active_latest_value != 0; 237*84d9c625SLionel Sambuc } 238*84d9c625SLionel Sambuc 239*84d9c625SLionel Sambuc #else /* neither FreeBSD nor Solaris */ 240*84d9c625SLionel Sambuc 241*84d9c625SLionel Sambuc static inline int 242*84d9c625SLionel Sambuc __gthread_active_p (void) 243*84d9c625SLionel Sambuc { 244*84d9c625SLionel Sambuc static void *const __gthread_active_ptr 245*84d9c625SLionel Sambuc = __extension__ (void *) &__gthrw_(pthread_cancel); 246*84d9c625SLionel Sambuc return __gthread_active_ptr != 0; 247*84d9c625SLionel Sambuc } 248*84d9c625SLionel Sambuc 249*84d9c625SLionel Sambuc #endif /* FreeBSD or Solaris */ 250*84d9c625SLionel Sambuc 251*84d9c625SLionel Sambuc #else /* not __GXX_WEAK__ */ 252*84d9c625SLionel Sambuc 253*84d9c625SLionel Sambuc /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread 254*84d9c625SLionel Sambuc calls in shared flavors of the HP-UX C library. Most of the stubs 255*84d9c625SLionel Sambuc have no functionality. The details are described in the "libc cumulative 256*84d9c625SLionel Sambuc patch" for each subversion of HP-UX 11. There are two special interfaces 257*84d9c625SLionel Sambuc provided for checking whether an application is linked to a shared pthread 258*84d9c625SLionel Sambuc library or not. However, these interfaces aren't available in early 259*84d9c625SLionel Sambuc libpthread libraries. We also need a test that works for archive 260*84d9c625SLionel Sambuc libraries. We can't use pthread_once as some libc versions call the 261*84d9c625SLionel Sambuc init function. We also can't use pthread_create or pthread_attr_init 262*84d9c625SLionel Sambuc as these create a thread and thereby prevent changing the default stack 263*84d9c625SLionel Sambuc size. The function pthread_default_stacksize_np is available in both 264*84d9c625SLionel Sambuc the archive and shared versions of libpthread. It can be used to 265*84d9c625SLionel Sambuc determine the default pthread stack size. There is a stub in some 266*84d9c625SLionel Sambuc shared libc versions which returns a zero size if pthreads are not 267*84d9c625SLionel Sambuc active. We provide an equivalent stub to handle cases where libc 268*84d9c625SLionel Sambuc doesn't provide one. */ 269*84d9c625SLionel Sambuc 270*84d9c625SLionel Sambuc #if defined(__hppa__) && defined(__hpux__) 271*84d9c625SLionel Sambuc 272*84d9c625SLionel Sambuc static volatile int __gthread_active = -1; 273*84d9c625SLionel Sambuc 274*84d9c625SLionel Sambuc static inline int 275*84d9c625SLionel Sambuc __gthread_active_p (void) 276*84d9c625SLionel Sambuc { 277*84d9c625SLionel Sambuc /* Avoid reading __gthread_active twice on the main code path. */ 278*84d9c625SLionel Sambuc int __gthread_active_latest_value = __gthread_active; 279*84d9c625SLionel Sambuc size_t __s; 280*84d9c625SLionel Sambuc 281*84d9c625SLionel Sambuc if (__builtin_expect (__gthread_active_latest_value < 0, 0)) 282*84d9c625SLionel Sambuc { 283*84d9c625SLionel Sambuc pthread_default_stacksize_np (0, &__s); 284*84d9c625SLionel Sambuc __gthread_active = __s ? 1 : 0; 285*84d9c625SLionel Sambuc __gthread_active_latest_value = __gthread_active; 286*84d9c625SLionel Sambuc } 287*84d9c625SLionel Sambuc 288*84d9c625SLionel Sambuc return __gthread_active_latest_value != 0; 289*84d9c625SLionel Sambuc } 290*84d9c625SLionel Sambuc 291*84d9c625SLionel Sambuc #else /* not hppa-hpux */ 292*84d9c625SLionel Sambuc 293*84d9c625SLionel Sambuc static inline int 294*84d9c625SLionel Sambuc __gthread_active_p (void) 295*84d9c625SLionel Sambuc { 296*84d9c625SLionel Sambuc return 1; 297*84d9c625SLionel Sambuc } 298*84d9c625SLionel Sambuc 299*84d9c625SLionel Sambuc #endif /* hppa-hpux */ 300*84d9c625SLionel Sambuc 301*84d9c625SLionel Sambuc #endif /* __GXX_WEAK__ */ 302*84d9c625SLionel Sambuc 303*84d9c625SLionel Sambuc #ifdef _LIBOBJC 304*84d9c625SLionel Sambuc 305*84d9c625SLionel Sambuc /* This is the config.h file in libobjc/ */ 306*84d9c625SLionel Sambuc #include <config.h> 307*84d9c625SLionel Sambuc 308*84d9c625SLionel Sambuc #ifdef HAVE_SCHED_H 309*84d9c625SLionel Sambuc # include <sched.h> 310*84d9c625SLionel Sambuc #endif 311*84d9c625SLionel Sambuc 312*84d9c625SLionel Sambuc /* Key structure for maintaining thread specific storage */ 313*84d9c625SLionel Sambuc static pthread_key_t _objc_thread_storage; 314*84d9c625SLionel Sambuc static pthread_attr_t _objc_thread_attribs; 315*84d9c625SLionel Sambuc 316*84d9c625SLionel Sambuc /* Thread local storage for a single thread */ 317*84d9c625SLionel Sambuc static void *thread_local_storage = NULL; 318*84d9c625SLionel Sambuc 319*84d9c625SLionel Sambuc /* Backend initialization functions */ 320*84d9c625SLionel Sambuc 321*84d9c625SLionel Sambuc /* Initialize the threads subsystem. */ 322*84d9c625SLionel Sambuc static inline int 323*84d9c625SLionel Sambuc __gthread_objc_init_thread_system (void) 324*84d9c625SLionel Sambuc { 325*84d9c625SLionel Sambuc if (__gthread_active_p ()) 326*84d9c625SLionel Sambuc { 327*84d9c625SLionel Sambuc /* Initialize the thread storage key. */ 328*84d9c625SLionel Sambuc if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) 329*84d9c625SLionel Sambuc { 330*84d9c625SLionel Sambuc /* The normal default detach state for threads is 331*84d9c625SLionel Sambuc * PTHREAD_CREATE_JOINABLE which causes threads to not die 332*84d9c625SLionel Sambuc * when you think they should. */ 333*84d9c625SLionel Sambuc if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 334*84d9c625SLionel Sambuc && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, 335*84d9c625SLionel Sambuc PTHREAD_CREATE_DETACHED) == 0) 336*84d9c625SLionel Sambuc return 0; 337*84d9c625SLionel Sambuc } 338*84d9c625SLionel Sambuc } 339*84d9c625SLionel Sambuc 340*84d9c625SLionel Sambuc return -1; 341*84d9c625SLionel Sambuc } 342*84d9c625SLionel Sambuc 343*84d9c625SLionel Sambuc /* Close the threads subsystem. */ 344*84d9c625SLionel Sambuc static inline int 345*84d9c625SLionel Sambuc __gthread_objc_close_thread_system (void) 346*84d9c625SLionel Sambuc { 347*84d9c625SLionel Sambuc if (__gthread_active_p () 348*84d9c625SLionel Sambuc && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 349*84d9c625SLionel Sambuc && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) 350*84d9c625SLionel Sambuc return 0; 351*84d9c625SLionel Sambuc 352*84d9c625SLionel Sambuc return -1; 353*84d9c625SLionel Sambuc } 354*84d9c625SLionel Sambuc 355*84d9c625SLionel Sambuc /* Backend thread functions */ 356*84d9c625SLionel Sambuc 357*84d9c625SLionel Sambuc /* Create a new thread of execution. */ 358*84d9c625SLionel Sambuc static inline objc_thread_t 359*84d9c625SLionel Sambuc __gthread_objc_thread_detach (void (*func)(void *), void *arg) 360*84d9c625SLionel Sambuc { 361*84d9c625SLionel Sambuc objc_thread_t thread_id; 362*84d9c625SLionel Sambuc pthread_t new_thread_handle; 363*84d9c625SLionel Sambuc 364*84d9c625SLionel Sambuc if (!__gthread_active_p ()) 365*84d9c625SLionel Sambuc return NULL; 366*84d9c625SLionel Sambuc 367*84d9c625SLionel Sambuc if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg))) 368*84d9c625SLionel Sambuc thread_id = (objc_thread_t) new_thread_handle; 369*84d9c625SLionel Sambuc else 370*84d9c625SLionel Sambuc thread_id = NULL; 371*84d9c625SLionel Sambuc 372*84d9c625SLionel Sambuc return thread_id; 373*84d9c625SLionel Sambuc } 374*84d9c625SLionel Sambuc 375*84d9c625SLionel Sambuc /* Set the current thread's priority. */ 376*84d9c625SLionel Sambuc static inline int 377*84d9c625SLionel Sambuc __gthread_objc_thread_set_priority (int priority) 378*84d9c625SLionel Sambuc { 379*84d9c625SLionel Sambuc if (!__gthread_active_p ()) 380*84d9c625SLionel Sambuc return -1; 381*84d9c625SLionel Sambuc else 382*84d9c625SLionel Sambuc { 383*84d9c625SLionel Sambuc #ifdef _POSIX_PRIORITY_SCHEDULING 384*84d9c625SLionel Sambuc #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 385*84d9c625SLionel Sambuc pthread_t thread_id = __gthrw_(pthread_self) (); 386*84d9c625SLionel Sambuc int policy; 387*84d9c625SLionel Sambuc struct sched_param params; 388*84d9c625SLionel Sambuc int priority_min, priority_max; 389*84d9c625SLionel Sambuc 390*84d9c625SLionel Sambuc if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) 391*84d9c625SLionel Sambuc { 392*84d9c625SLionel Sambuc if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) 393*84d9c625SLionel Sambuc return -1; 394*84d9c625SLionel Sambuc 395*84d9c625SLionel Sambuc if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) 396*84d9c625SLionel Sambuc return -1; 397*84d9c625SLionel Sambuc 398*84d9c625SLionel Sambuc if (priority > priority_max) 399*84d9c625SLionel Sambuc priority = priority_max; 400*84d9c625SLionel Sambuc else if (priority < priority_min) 401*84d9c625SLionel Sambuc priority = priority_min; 402*84d9c625SLionel Sambuc params.sched_priority = priority; 403*84d9c625SLionel Sambuc 404*84d9c625SLionel Sambuc /* 405*84d9c625SLionel Sambuc * The solaris 7 and several other man pages incorrectly state that 406*84d9c625SLionel Sambuc * this should be a pointer to policy but pthread.h is universally 407*84d9c625SLionel Sambuc * at odds with this. 408*84d9c625SLionel Sambuc */ 409*84d9c625SLionel Sambuc if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) 410*84d9c625SLionel Sambuc return 0; 411*84d9c625SLionel Sambuc } 412*84d9c625SLionel Sambuc #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 413*84d9c625SLionel Sambuc #endif /* _POSIX_PRIORITY_SCHEDULING */ 414*84d9c625SLionel Sambuc return -1; 415*84d9c625SLionel Sambuc } 416*84d9c625SLionel Sambuc } 417*84d9c625SLionel Sambuc 418*84d9c625SLionel Sambuc /* Return the current thread's priority. */ 419*84d9c625SLionel Sambuc static inline int 420*84d9c625SLionel Sambuc __gthread_objc_thread_get_priority (void) 421*84d9c625SLionel Sambuc { 422*84d9c625SLionel Sambuc #ifdef _POSIX_PRIORITY_SCHEDULING 423*84d9c625SLionel Sambuc #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 424*84d9c625SLionel Sambuc if (__gthread_active_p ()) 425*84d9c625SLionel Sambuc { 426*84d9c625SLionel Sambuc int policy; 427*84d9c625SLionel Sambuc struct sched_param params; 428*84d9c625SLionel Sambuc 429*84d9c625SLionel Sambuc if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) 430*84d9c625SLionel Sambuc return params.sched_priority; 431*84d9c625SLionel Sambuc else 432*84d9c625SLionel Sambuc return -1; 433*84d9c625SLionel Sambuc } 434*84d9c625SLionel Sambuc else 435*84d9c625SLionel Sambuc #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 436*84d9c625SLionel Sambuc #endif /* _POSIX_PRIORITY_SCHEDULING */ 437*84d9c625SLionel Sambuc return OBJC_THREAD_INTERACTIVE_PRIORITY; 438*84d9c625SLionel Sambuc } 439*84d9c625SLionel Sambuc 440*84d9c625SLionel Sambuc /* Yield our process time to another thread. */ 441*84d9c625SLionel Sambuc static inline void 442*84d9c625SLionel Sambuc __gthread_objc_thread_yield (void) 443*84d9c625SLionel Sambuc { 444*84d9c625SLionel Sambuc if (__gthread_active_p ()) 445*84d9c625SLionel Sambuc __gthrw_(sched_yield) (); 446*84d9c625SLionel Sambuc } 447*84d9c625SLionel Sambuc 448*84d9c625SLionel Sambuc /* Terminate the current thread. */ 449*84d9c625SLionel Sambuc static inline int 450*84d9c625SLionel Sambuc __gthread_objc_thread_exit (void) 451*84d9c625SLionel Sambuc { 452*84d9c625SLionel Sambuc if (__gthread_active_p ()) 453*84d9c625SLionel Sambuc /* exit the thread */ 454*84d9c625SLionel Sambuc __gthrw_(pthread_exit) (&__objc_thread_exit_status); 455*84d9c625SLionel Sambuc 456*84d9c625SLionel Sambuc /* Failed if we reached here */ 457*84d9c625SLionel Sambuc return -1; 458*84d9c625SLionel Sambuc } 459*84d9c625SLionel Sambuc 460*84d9c625SLionel Sambuc /* Returns an integer value which uniquely describes a thread. */ 461*84d9c625SLionel Sambuc static inline objc_thread_t 462*84d9c625SLionel Sambuc __gthread_objc_thread_id (void) 463*84d9c625SLionel Sambuc { 464*84d9c625SLionel Sambuc if (__gthread_active_p ()) 465*84d9c625SLionel Sambuc return (objc_thread_t) __gthrw_(pthread_self) (); 466*84d9c625SLionel Sambuc else 467*84d9c625SLionel Sambuc return (objc_thread_t) 1; 468*84d9c625SLionel Sambuc } 469*84d9c625SLionel Sambuc 470*84d9c625SLionel Sambuc /* Sets the thread's local storage pointer. */ 471*84d9c625SLionel Sambuc static inline int 472*84d9c625SLionel Sambuc __gthread_objc_thread_set_data (void *value) 473*84d9c625SLionel Sambuc { 474*84d9c625SLionel Sambuc if (__gthread_active_p ()) 475*84d9c625SLionel Sambuc return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); 476*84d9c625SLionel Sambuc else 477*84d9c625SLionel Sambuc { 478*84d9c625SLionel Sambuc thread_local_storage = value; 479*84d9c625SLionel Sambuc return 0; 480*84d9c625SLionel Sambuc } 481*84d9c625SLionel Sambuc } 482*84d9c625SLionel Sambuc 483*84d9c625SLionel Sambuc /* Returns the thread's local storage pointer. */ 484*84d9c625SLionel Sambuc static inline void * 485*84d9c625SLionel Sambuc __gthread_objc_thread_get_data (void) 486*84d9c625SLionel Sambuc { 487*84d9c625SLionel Sambuc if (__gthread_active_p ()) 488*84d9c625SLionel Sambuc return __gthrw_(pthread_getspecific) (_objc_thread_storage); 489*84d9c625SLionel Sambuc else 490*84d9c625SLionel Sambuc return thread_local_storage; 491*84d9c625SLionel Sambuc } 492*84d9c625SLionel Sambuc 493*84d9c625SLionel Sambuc /* Backend mutex functions */ 494*84d9c625SLionel Sambuc 495*84d9c625SLionel Sambuc /* Allocate a mutex. */ 496*84d9c625SLionel Sambuc static inline int 497*84d9c625SLionel Sambuc __gthread_objc_mutex_allocate (objc_mutex_t mutex) 498*84d9c625SLionel Sambuc { 499*84d9c625SLionel Sambuc if (__gthread_active_p ()) 500*84d9c625SLionel Sambuc { 501*84d9c625SLionel Sambuc mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); 502*84d9c625SLionel Sambuc 503*84d9c625SLionel Sambuc if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) 504*84d9c625SLionel Sambuc { 505*84d9c625SLionel Sambuc objc_free (mutex->backend); 506*84d9c625SLionel Sambuc mutex->backend = NULL; 507*84d9c625SLionel Sambuc return -1; 508*84d9c625SLionel Sambuc } 509*84d9c625SLionel Sambuc } 510*84d9c625SLionel Sambuc 511*84d9c625SLionel Sambuc return 0; 512*84d9c625SLionel Sambuc } 513*84d9c625SLionel Sambuc 514*84d9c625SLionel Sambuc /* Deallocate a mutex. */ 515*84d9c625SLionel Sambuc static inline int 516*84d9c625SLionel Sambuc __gthread_objc_mutex_deallocate (objc_mutex_t mutex) 517*84d9c625SLionel Sambuc { 518*84d9c625SLionel Sambuc if (__gthread_active_p ()) 519*84d9c625SLionel Sambuc { 520*84d9c625SLionel Sambuc int count; 521*84d9c625SLionel Sambuc 522*84d9c625SLionel Sambuc /* 523*84d9c625SLionel Sambuc * Posix Threads specifically require that the thread be unlocked 524*84d9c625SLionel Sambuc * for __gthrw_(pthread_mutex_destroy) to work. 525*84d9c625SLionel Sambuc */ 526*84d9c625SLionel Sambuc 527*84d9c625SLionel Sambuc do 528*84d9c625SLionel Sambuc { 529*84d9c625SLionel Sambuc count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); 530*84d9c625SLionel Sambuc if (count < 0) 531*84d9c625SLionel Sambuc return -1; 532*84d9c625SLionel Sambuc } 533*84d9c625SLionel Sambuc while (count); 534*84d9c625SLionel Sambuc 535*84d9c625SLionel Sambuc if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) 536*84d9c625SLionel Sambuc return -1; 537*84d9c625SLionel Sambuc 538*84d9c625SLionel Sambuc objc_free (mutex->backend); 539*84d9c625SLionel Sambuc mutex->backend = NULL; 540*84d9c625SLionel Sambuc } 541*84d9c625SLionel Sambuc return 0; 542*84d9c625SLionel Sambuc } 543*84d9c625SLionel Sambuc 544*84d9c625SLionel Sambuc /* Grab a lock on a mutex. */ 545*84d9c625SLionel Sambuc static inline int 546*84d9c625SLionel Sambuc __gthread_objc_mutex_lock (objc_mutex_t mutex) 547*84d9c625SLionel Sambuc { 548*84d9c625SLionel Sambuc if (__gthread_active_p () 549*84d9c625SLionel Sambuc && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) 550*84d9c625SLionel Sambuc { 551*84d9c625SLionel Sambuc return -1; 552*84d9c625SLionel Sambuc } 553*84d9c625SLionel Sambuc 554*84d9c625SLionel Sambuc return 0; 555*84d9c625SLionel Sambuc } 556*84d9c625SLionel Sambuc 557*84d9c625SLionel Sambuc /* Try to grab a lock on a mutex. */ 558*84d9c625SLionel Sambuc static inline int 559*84d9c625SLionel Sambuc __gthread_objc_mutex_trylock (objc_mutex_t mutex) 560*84d9c625SLionel Sambuc { 561*84d9c625SLionel Sambuc if (__gthread_active_p () 562*84d9c625SLionel Sambuc && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) 563*84d9c625SLionel Sambuc { 564*84d9c625SLionel Sambuc return -1; 565*84d9c625SLionel Sambuc } 566*84d9c625SLionel Sambuc 567*84d9c625SLionel Sambuc return 0; 568*84d9c625SLionel Sambuc } 569*84d9c625SLionel Sambuc 570*84d9c625SLionel Sambuc /* Unlock the mutex */ 571*84d9c625SLionel Sambuc static inline int 572*84d9c625SLionel Sambuc __gthread_objc_mutex_unlock (objc_mutex_t mutex) 573*84d9c625SLionel Sambuc { 574*84d9c625SLionel Sambuc if (__gthread_active_p () 575*84d9c625SLionel Sambuc && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) 576*84d9c625SLionel Sambuc { 577*84d9c625SLionel Sambuc return -1; 578*84d9c625SLionel Sambuc } 579*84d9c625SLionel Sambuc 580*84d9c625SLionel Sambuc return 0; 581*84d9c625SLionel Sambuc } 582*84d9c625SLionel Sambuc 583*84d9c625SLionel Sambuc /* Backend condition mutex functions */ 584*84d9c625SLionel Sambuc 585*84d9c625SLionel Sambuc /* Allocate a condition. */ 586*84d9c625SLionel Sambuc static inline int 587*84d9c625SLionel Sambuc __gthread_objc_condition_allocate (objc_condition_t condition) 588*84d9c625SLionel Sambuc { 589*84d9c625SLionel Sambuc if (__gthread_active_p ()) 590*84d9c625SLionel Sambuc { 591*84d9c625SLionel Sambuc condition->backend = objc_malloc (sizeof (pthread_cond_t)); 592*84d9c625SLionel Sambuc 593*84d9c625SLionel Sambuc if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) 594*84d9c625SLionel Sambuc { 595*84d9c625SLionel Sambuc objc_free (condition->backend); 596*84d9c625SLionel Sambuc condition->backend = NULL; 597*84d9c625SLionel Sambuc return -1; 598*84d9c625SLionel Sambuc } 599*84d9c625SLionel Sambuc } 600*84d9c625SLionel Sambuc 601*84d9c625SLionel Sambuc return 0; 602*84d9c625SLionel Sambuc } 603*84d9c625SLionel Sambuc 604*84d9c625SLionel Sambuc /* Deallocate a condition. */ 605*84d9c625SLionel Sambuc static inline int 606*84d9c625SLionel Sambuc __gthread_objc_condition_deallocate (objc_condition_t condition) 607*84d9c625SLionel Sambuc { 608*84d9c625SLionel Sambuc if (__gthread_active_p ()) 609*84d9c625SLionel Sambuc { 610*84d9c625SLionel Sambuc if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) 611*84d9c625SLionel Sambuc return -1; 612*84d9c625SLionel Sambuc 613*84d9c625SLionel Sambuc objc_free (condition->backend); 614*84d9c625SLionel Sambuc condition->backend = NULL; 615*84d9c625SLionel Sambuc } 616*84d9c625SLionel Sambuc return 0; 617*84d9c625SLionel Sambuc } 618*84d9c625SLionel Sambuc 619*84d9c625SLionel Sambuc /* Wait on the condition */ 620*84d9c625SLionel Sambuc static inline int 621*84d9c625SLionel Sambuc __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) 622*84d9c625SLionel Sambuc { 623*84d9c625SLionel Sambuc if (__gthread_active_p ()) 624*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, 625*84d9c625SLionel Sambuc (pthread_mutex_t *) mutex->backend); 626*84d9c625SLionel Sambuc else 627*84d9c625SLionel Sambuc return 0; 628*84d9c625SLionel Sambuc } 629*84d9c625SLionel Sambuc 630*84d9c625SLionel Sambuc /* Wake up all threads waiting on this condition. */ 631*84d9c625SLionel Sambuc static inline int 632*84d9c625SLionel Sambuc __gthread_objc_condition_broadcast (objc_condition_t condition) 633*84d9c625SLionel Sambuc { 634*84d9c625SLionel Sambuc if (__gthread_active_p ()) 635*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); 636*84d9c625SLionel Sambuc else 637*84d9c625SLionel Sambuc return 0; 638*84d9c625SLionel Sambuc } 639*84d9c625SLionel Sambuc 640*84d9c625SLionel Sambuc /* Wake up one thread waiting on this condition. */ 641*84d9c625SLionel Sambuc static inline int 642*84d9c625SLionel Sambuc __gthread_objc_condition_signal (objc_condition_t condition) 643*84d9c625SLionel Sambuc { 644*84d9c625SLionel Sambuc if (__gthread_active_p ()) 645*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); 646*84d9c625SLionel Sambuc else 647*84d9c625SLionel Sambuc return 0; 648*84d9c625SLionel Sambuc } 649*84d9c625SLionel Sambuc 650*84d9c625SLionel Sambuc #else /* _LIBOBJC */ 651*84d9c625SLionel Sambuc 652*84d9c625SLionel Sambuc static inline int 653*84d9c625SLionel Sambuc __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), 654*84d9c625SLionel Sambuc void *__args) 655*84d9c625SLionel Sambuc { 656*84d9c625SLionel Sambuc return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); 657*84d9c625SLionel Sambuc } 658*84d9c625SLionel Sambuc 659*84d9c625SLionel Sambuc static inline int 660*84d9c625SLionel Sambuc __gthread_join (__gthread_t __threadid, void **__value_ptr) 661*84d9c625SLionel Sambuc { 662*84d9c625SLionel Sambuc return __gthrw_(pthread_join) (__threadid, __value_ptr); 663*84d9c625SLionel Sambuc } 664*84d9c625SLionel Sambuc 665*84d9c625SLionel Sambuc static inline int 666*84d9c625SLionel Sambuc __gthread_detach (__gthread_t __threadid) 667*84d9c625SLionel Sambuc { 668*84d9c625SLionel Sambuc return __gthrw_(pthread_detach) (__threadid); 669*84d9c625SLionel Sambuc } 670*84d9c625SLionel Sambuc 671*84d9c625SLionel Sambuc static inline int 672*84d9c625SLionel Sambuc __gthread_equal (__gthread_t __t1, __gthread_t __t2) 673*84d9c625SLionel Sambuc { 674*84d9c625SLionel Sambuc return __gthrw_(pthread_equal) (__t1, __t2); 675*84d9c625SLionel Sambuc } 676*84d9c625SLionel Sambuc 677*84d9c625SLionel Sambuc static inline __gthread_t 678*84d9c625SLionel Sambuc __gthread_self (void) 679*84d9c625SLionel Sambuc { 680*84d9c625SLionel Sambuc return __gthrw_(pthread_self) (); 681*84d9c625SLionel Sambuc } 682*84d9c625SLionel Sambuc 683*84d9c625SLionel Sambuc static inline int 684*84d9c625SLionel Sambuc __gthread_yield (void) 685*84d9c625SLionel Sambuc { 686*84d9c625SLionel Sambuc return __gthrw_(sched_yield) (); 687*84d9c625SLionel Sambuc } 688*84d9c625SLionel Sambuc 689*84d9c625SLionel Sambuc static inline int 690*84d9c625SLionel Sambuc __gthread_once (__gthread_once_t *__once, void (*__func) (void)) 691*84d9c625SLionel Sambuc { 692*84d9c625SLionel Sambuc if (__gthread_active_p ()) 693*84d9c625SLionel Sambuc return __gthrw_(pthread_once) (__once, __func); 694*84d9c625SLionel Sambuc else 695*84d9c625SLionel Sambuc return -1; 696*84d9c625SLionel Sambuc } 697*84d9c625SLionel Sambuc 698*84d9c625SLionel Sambuc static inline int 699*84d9c625SLionel Sambuc __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) 700*84d9c625SLionel Sambuc { 701*84d9c625SLionel Sambuc return __gthrw_(pthread_key_create) (__key, __dtor); 702*84d9c625SLionel Sambuc } 703*84d9c625SLionel Sambuc 704*84d9c625SLionel Sambuc static inline int 705*84d9c625SLionel Sambuc __gthread_key_delete (__gthread_key_t __key) 706*84d9c625SLionel Sambuc { 707*84d9c625SLionel Sambuc return __gthrw_(pthread_key_delete) (__key); 708*84d9c625SLionel Sambuc } 709*84d9c625SLionel Sambuc 710*84d9c625SLionel Sambuc static inline void * 711*84d9c625SLionel Sambuc __gthread_getspecific (__gthread_key_t __key) 712*84d9c625SLionel Sambuc { 713*84d9c625SLionel Sambuc return __gthrw_(pthread_getspecific) (__key); 714*84d9c625SLionel Sambuc } 715*84d9c625SLionel Sambuc 716*84d9c625SLionel Sambuc static inline int 717*84d9c625SLionel Sambuc __gthread_setspecific (__gthread_key_t __key, const void *__ptr) 718*84d9c625SLionel Sambuc { 719*84d9c625SLionel Sambuc return __gthrw_(pthread_setspecific) (__key, __ptr); 720*84d9c625SLionel Sambuc } 721*84d9c625SLionel Sambuc 722*84d9c625SLionel Sambuc static inline int 723*84d9c625SLionel Sambuc __gthread_mutex_destroy (__gthread_mutex_t *__mutex) 724*84d9c625SLionel Sambuc { 725*84d9c625SLionel Sambuc if (__gthread_active_p ()) 726*84d9c625SLionel Sambuc return __gthrw_(pthread_mutex_destroy) (__mutex); 727*84d9c625SLionel Sambuc else 728*84d9c625SLionel Sambuc return 0; 729*84d9c625SLionel Sambuc } 730*84d9c625SLionel Sambuc 731*84d9c625SLionel Sambuc static inline int 732*84d9c625SLionel Sambuc __gthread_mutex_lock (__gthread_mutex_t *__mutex) 733*84d9c625SLionel Sambuc { 734*84d9c625SLionel Sambuc if (__gthread_active_p ()) 735*84d9c625SLionel Sambuc return __gthrw_(pthread_mutex_lock) (__mutex); 736*84d9c625SLionel Sambuc else 737*84d9c625SLionel Sambuc return 0; 738*84d9c625SLionel Sambuc } 739*84d9c625SLionel Sambuc 740*84d9c625SLionel Sambuc static inline int 741*84d9c625SLionel Sambuc __gthread_mutex_trylock (__gthread_mutex_t *__mutex) 742*84d9c625SLionel Sambuc { 743*84d9c625SLionel Sambuc if (__gthread_active_p ()) 744*84d9c625SLionel Sambuc return __gthrw_(pthread_mutex_trylock) (__mutex); 745*84d9c625SLionel Sambuc else 746*84d9c625SLionel Sambuc return 0; 747*84d9c625SLionel Sambuc } 748*84d9c625SLionel Sambuc 749*84d9c625SLionel Sambuc #ifdef _POSIX_TIMEOUTS 750*84d9c625SLionel Sambuc #if _POSIX_TIMEOUTS >= 0 751*84d9c625SLionel Sambuc static inline int 752*84d9c625SLionel Sambuc __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, 753*84d9c625SLionel Sambuc const __gthread_time_t *__abs_timeout) 754*84d9c625SLionel Sambuc { 755*84d9c625SLionel Sambuc if (__gthread_active_p ()) 756*84d9c625SLionel Sambuc return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout); 757*84d9c625SLionel Sambuc else 758*84d9c625SLionel Sambuc return 0; 759*84d9c625SLionel Sambuc } 760*84d9c625SLionel Sambuc #endif 761*84d9c625SLionel Sambuc #endif 762*84d9c625SLionel Sambuc 763*84d9c625SLionel Sambuc static inline int 764*84d9c625SLionel Sambuc __gthread_mutex_unlock (__gthread_mutex_t *__mutex) 765*84d9c625SLionel Sambuc { 766*84d9c625SLionel Sambuc if (__gthread_active_p ()) 767*84d9c625SLionel Sambuc return __gthrw_(pthread_mutex_unlock) (__mutex); 768*84d9c625SLionel Sambuc else 769*84d9c625SLionel Sambuc return 0; 770*84d9c625SLionel Sambuc } 771*84d9c625SLionel Sambuc 772*84d9c625SLionel Sambuc #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 773*84d9c625SLionel Sambuc static inline int 774*84d9c625SLionel Sambuc __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) 775*84d9c625SLionel Sambuc { 776*84d9c625SLionel Sambuc if (__gthread_active_p ()) 777*84d9c625SLionel Sambuc { 778*84d9c625SLionel Sambuc pthread_mutexattr_t __attr; 779*84d9c625SLionel Sambuc int __r; 780*84d9c625SLionel Sambuc 781*84d9c625SLionel Sambuc __r = __gthrw_(pthread_mutexattr_init) (&__attr); 782*84d9c625SLionel Sambuc if (!__r) 783*84d9c625SLionel Sambuc __r = __gthrw_(pthread_mutexattr_settype) (&__attr, 784*84d9c625SLionel Sambuc PTHREAD_MUTEX_RECURSIVE); 785*84d9c625SLionel Sambuc if (!__r) 786*84d9c625SLionel Sambuc __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr); 787*84d9c625SLionel Sambuc if (!__r) 788*84d9c625SLionel Sambuc __r = __gthrw_(pthread_mutexattr_destroy) (&__attr); 789*84d9c625SLionel Sambuc return __r; 790*84d9c625SLionel Sambuc } 791*84d9c625SLionel Sambuc return 0; 792*84d9c625SLionel Sambuc } 793*84d9c625SLionel Sambuc #endif 794*84d9c625SLionel Sambuc 795*84d9c625SLionel Sambuc static inline int 796*84d9c625SLionel Sambuc __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) 797*84d9c625SLionel Sambuc { 798*84d9c625SLionel Sambuc return __gthread_mutex_lock (__mutex); 799*84d9c625SLionel Sambuc } 800*84d9c625SLionel Sambuc 801*84d9c625SLionel Sambuc static inline int 802*84d9c625SLionel Sambuc __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) 803*84d9c625SLionel Sambuc { 804*84d9c625SLionel Sambuc return __gthread_mutex_trylock (__mutex); 805*84d9c625SLionel Sambuc } 806*84d9c625SLionel Sambuc 807*84d9c625SLionel Sambuc #ifdef _POSIX_TIMEOUTS 808*84d9c625SLionel Sambuc #if _POSIX_TIMEOUTS >= 0 809*84d9c625SLionel Sambuc static inline int 810*84d9c625SLionel Sambuc __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, 811*84d9c625SLionel Sambuc const __gthread_time_t *__abs_timeout) 812*84d9c625SLionel Sambuc { 813*84d9c625SLionel Sambuc return __gthread_mutex_timedlock (__mutex, __abs_timeout); 814*84d9c625SLionel Sambuc } 815*84d9c625SLionel Sambuc #endif 816*84d9c625SLionel Sambuc #endif 817*84d9c625SLionel Sambuc 818*84d9c625SLionel Sambuc static inline int 819*84d9c625SLionel Sambuc __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) 820*84d9c625SLionel Sambuc { 821*84d9c625SLionel Sambuc return __gthread_mutex_unlock (__mutex); 822*84d9c625SLionel Sambuc } 823*84d9c625SLionel Sambuc 824*84d9c625SLionel Sambuc static inline int 825*84d9c625SLionel Sambuc __gthread_cond_broadcast (__gthread_cond_t *__cond) 826*84d9c625SLionel Sambuc { 827*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_broadcast) (__cond); 828*84d9c625SLionel Sambuc } 829*84d9c625SLionel Sambuc 830*84d9c625SLionel Sambuc static inline int 831*84d9c625SLionel Sambuc __gthread_cond_signal (__gthread_cond_t *__cond) 832*84d9c625SLionel Sambuc { 833*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_signal) (__cond); 834*84d9c625SLionel Sambuc } 835*84d9c625SLionel Sambuc 836*84d9c625SLionel Sambuc static inline int 837*84d9c625SLionel Sambuc __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) 838*84d9c625SLionel Sambuc { 839*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_wait) (__cond, __mutex); 840*84d9c625SLionel Sambuc } 841*84d9c625SLionel Sambuc 842*84d9c625SLionel Sambuc static inline int 843*84d9c625SLionel Sambuc __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, 844*84d9c625SLionel Sambuc const __gthread_time_t *__abs_timeout) 845*84d9c625SLionel Sambuc { 846*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); 847*84d9c625SLionel Sambuc } 848*84d9c625SLionel Sambuc 849*84d9c625SLionel Sambuc static inline int 850*84d9c625SLionel Sambuc __gthread_cond_wait_recursive (__gthread_cond_t *__cond, 851*84d9c625SLionel Sambuc __gthread_recursive_mutex_t *__mutex) 852*84d9c625SLionel Sambuc { 853*84d9c625SLionel Sambuc return __gthread_cond_wait (__cond, __mutex); 854*84d9c625SLionel Sambuc } 855*84d9c625SLionel Sambuc 856*84d9c625SLionel Sambuc static inline int 857*84d9c625SLionel Sambuc __gthread_cond_timedwait_recursive (__gthread_cond_t *__cond, 858*84d9c625SLionel Sambuc __gthread_recursive_mutex_t *__mutex, 859*84d9c625SLionel Sambuc const __gthread_time_t *__abs_timeout) 860*84d9c625SLionel Sambuc { 861*84d9c625SLionel Sambuc return __gthread_cond_timedwait (__cond, __mutex, __abs_timeout); 862*84d9c625SLionel Sambuc } 863*84d9c625SLionel Sambuc 864*84d9c625SLionel Sambuc static inline int 865*84d9c625SLionel Sambuc __gthread_cond_destroy (__gthread_cond_t* __cond) 866*84d9c625SLionel Sambuc { 867*84d9c625SLionel Sambuc return __gthrw_(pthread_cond_destroy) (__cond); 868*84d9c625SLionel Sambuc } 869*84d9c625SLionel Sambuc 870*84d9c625SLionel Sambuc #endif /* _LIBOBJC */ 871*84d9c625SLionel Sambuc 872*84d9c625SLionel Sambuc #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ 873