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