xref: /minix3/external/gpl3/gcc/lib/libstdc++-v3/arch/arm/gthr-posix.h (revision 18a5822eff3a5bdeb6301a60d7d6269594c7ce35)
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, &params) == 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, &params) == 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, &params) == 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