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