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