118a5822eSThomas Veerman /* This file is automatically generated. DO NOT EDIT! */
2*0a6a1f1dSLionel Sambuc /* Generated from: NetBSD: mknative-gcc,v 1.70 2013/05/05 07:11:34 skrll Exp */
3*0a6a1f1dSLionel Sambuc /* Generated from: NetBSD: mknative.common,v 1.8 2006/05/26 19:17:21 mrg Exp */
418a5822eSThomas Veerman
518a5822eSThomas Veerman /* Threads compatibility routines for libgcc2 and libobjc. */
618a5822eSThomas Veerman /* Compile this one with gcc. */
7*0a6a1f1dSLionel Sambuc /* Copyright (C) 1997-2013 Free Software Foundation, Inc.
818a5822eSThomas Veerman
918a5822eSThomas Veerman This file is part of GCC.
1018a5822eSThomas Veerman
1118a5822eSThomas Veerman GCC is free software; you can redistribute it and/or modify it under
1218a5822eSThomas Veerman the terms of the GNU General Public License as published by the Free
1318a5822eSThomas Veerman Software Foundation; either version 3, or (at your option) any later
1418a5822eSThomas Veerman version.
1518a5822eSThomas Veerman
1618a5822eSThomas Veerman GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1718a5822eSThomas Veerman WARRANTY; without even the implied warranty of MERCHANTABILITY or
1818a5822eSThomas Veerman FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1918a5822eSThomas Veerman for more details.
2018a5822eSThomas Veerman
2118a5822eSThomas Veerman Under Section 7 of GPL version 3, you are granted additional
2218a5822eSThomas Veerman permissions described in the GCC Runtime Library Exception, version
2318a5822eSThomas Veerman 3.1, as published by the Free Software Foundation.
2418a5822eSThomas Veerman
2518a5822eSThomas Veerman You should have received a copy of the GNU General Public License and
2618a5822eSThomas Veerman a copy of the GCC Runtime Library Exception along with this program;
2718a5822eSThomas Veerman see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2818a5822eSThomas Veerman <http://www.gnu.org/licenses/>. */
2918a5822eSThomas Veerman
3018a5822eSThomas Veerman #ifndef _GLIBCXX_GCC_GTHR_POSIX_H
3118a5822eSThomas Veerman #define _GLIBCXX_GCC_GTHR_POSIX_H
3218a5822eSThomas Veerman
3318a5822eSThomas Veerman /* POSIX threads specific definitions.
3418a5822eSThomas Veerman Easy, since the interface is just one-to-one mapping. */
3518a5822eSThomas Veerman
3618a5822eSThomas Veerman #define __GTHREADS 1
3718a5822eSThomas Veerman #define __GTHREADS_CXX0X 1
3818a5822eSThomas Veerman
3918a5822eSThomas Veerman #include <pthread.h>
40*0a6a1f1dSLionel Sambuc
41*0a6a1f1dSLionel Sambuc #if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \
42*0a6a1f1dSLionel Sambuc || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK))
4318a5822eSThomas Veerman # 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
5018a5822eSThomas Veerman
5118a5822eSThomas Veerman typedef pthread_t __gthread_t;
5218a5822eSThomas Veerman typedef pthread_key_t __gthread_key_t;
5318a5822eSThomas Veerman typedef pthread_once_t __gthread_once_t;
5418a5822eSThomas Veerman typedef pthread_mutex_t __gthread_mutex_t;
5518a5822eSThomas Veerman typedef pthread_mutex_t __gthread_recursive_mutex_t;
5618a5822eSThomas Veerman typedef pthread_cond_t __gthread_cond_t;
5718a5822eSThomas Veerman typedef struct timespec __gthread_time_t;
5818a5822eSThomas Veerman
5918a5822eSThomas Veerman /* POSIX like conditional variables are supported. Please look at comments
6018a5822eSThomas Veerman in gthr.h for details. */
6118a5822eSThomas Veerman #define __GTHREAD_HAS_COND 1
6218a5822eSThomas Veerman
6318a5822eSThomas Veerman #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
64*0a6a1f1dSLionel Sambuc #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
6518a5822eSThomas Veerman #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
6618a5822eSThomas Veerman #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
6718a5822eSThomas Veerman #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
6818a5822eSThomas Veerman #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
6918a5822eSThomas Veerman #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
7018a5822eSThomas Veerman #else
7118a5822eSThomas Veerman #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
7218a5822eSThomas Veerman #endif
7318a5822eSThomas Veerman #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
7418a5822eSThomas Veerman #define __GTHREAD_TIME_INIT {0,0}
7518a5822eSThomas Veerman
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
8918a5822eSThomas Veerman #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
9018a5822eSThomas Veerman # ifndef __gthrw_pragma
9118a5822eSThomas Veerman # define __gthrw_pragma(pragma)
9218a5822eSThomas Veerman # endif
9318a5822eSThomas Veerman # define __gthrw2(name,name2,type) \
9418a5822eSThomas Veerman static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
9518a5822eSThomas Veerman __gthrw_pragma(weak type)
9618a5822eSThomas Veerman # define __gthrw_(name) __gthrw_ ## name
9718a5822eSThomas Veerman #else
9818a5822eSThomas Veerman # define __gthrw2(name,name2,type)
9918a5822eSThomas Veerman # define __gthrw_(name) name
10018a5822eSThomas Veerman #endif
10118a5822eSThomas Veerman
10218a5822eSThomas Veerman /* Typically, __gthrw_foo is a weak reference to symbol foo. */
10318a5822eSThomas Veerman #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
10418a5822eSThomas Veerman
10518a5822eSThomas Veerman __gthrw(pthread_once)
10618a5822eSThomas Veerman __gthrw(pthread_getspecific)
10718a5822eSThomas Veerman __gthrw(pthread_setspecific)
10818a5822eSThomas Veerman
10918a5822eSThomas Veerman __gthrw(pthread_create)
11018a5822eSThomas Veerman __gthrw(pthread_join)
11118a5822eSThomas Veerman __gthrw(pthread_equal)
11218a5822eSThomas Veerman __gthrw(pthread_self)
11318a5822eSThomas Veerman __gthrw(pthread_detach)
114*0a6a1f1dSLionel Sambuc #ifndef __BIONIC__
11518a5822eSThomas Veerman __gthrw(pthread_cancel)
116*0a6a1f1dSLionel Sambuc #endif
11718a5822eSThomas Veerman __gthrw(sched_yield)
11818a5822eSThomas Veerman
11918a5822eSThomas Veerman __gthrw(pthread_mutex_lock)
12018a5822eSThomas Veerman __gthrw(pthread_mutex_trylock)
121*0a6a1f1dSLionel Sambuc #if _GTHREAD_USE_MUTEX_TIMEDLOCK
12218a5822eSThomas Veerman __gthrw(pthread_mutex_timedlock)
12318a5822eSThomas Veerman #endif
12418a5822eSThomas Veerman __gthrw(pthread_mutex_unlock)
12518a5822eSThomas Veerman __gthrw(pthread_mutex_init)
12618a5822eSThomas Veerman __gthrw(pthread_mutex_destroy)
12718a5822eSThomas Veerman
128*0a6a1f1dSLionel Sambuc __gthrw(pthread_cond_init)
12918a5822eSThomas Veerman __gthrw(pthread_cond_broadcast)
13018a5822eSThomas Veerman __gthrw(pthread_cond_signal)
13118a5822eSThomas Veerman __gthrw(pthread_cond_wait)
13218a5822eSThomas Veerman __gthrw(pthread_cond_timedwait)
13318a5822eSThomas Veerman __gthrw(pthread_cond_destroy)
13418a5822eSThomas Veerman
13518a5822eSThomas Veerman __gthrw(pthread_key_create)
13618a5822eSThomas Veerman __gthrw(pthread_key_delete)
13718a5822eSThomas Veerman __gthrw(pthread_mutexattr_init)
13818a5822eSThomas Veerman __gthrw(pthread_mutexattr_settype)
13918a5822eSThomas Veerman __gthrw(pthread_mutexattr_destroy)
14018a5822eSThomas Veerman
14118a5822eSThomas Veerman
14218a5822eSThomas Veerman #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
14318a5822eSThomas Veerman /* Objective-C. */
14418a5822eSThomas Veerman __gthrw(pthread_exit)
14518a5822eSThomas Veerman #ifdef _POSIX_PRIORITY_SCHEDULING
14618a5822eSThomas Veerman #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
14718a5822eSThomas Veerman __gthrw(sched_get_priority_max)
14818a5822eSThomas Veerman __gthrw(sched_get_priority_min)
14918a5822eSThomas Veerman #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
15018a5822eSThomas Veerman #endif /* _POSIX_PRIORITY_SCHEDULING */
15118a5822eSThomas Veerman __gthrw(pthread_attr_destroy)
15218a5822eSThomas Veerman __gthrw(pthread_attr_init)
15318a5822eSThomas Veerman __gthrw(pthread_attr_setdetachstate)
15418a5822eSThomas Veerman #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
15518a5822eSThomas Veerman __gthrw(pthread_getschedparam)
15618a5822eSThomas Veerman __gthrw(pthread_setschedparam)
15718a5822eSThomas Veerman #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
15818a5822eSThomas Veerman #endif /* _LIBOBJC || _LIBOBJC_WEAK */
15918a5822eSThomas Veerman
16018a5822eSThomas Veerman #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
16118a5822eSThomas Veerman
16218a5822eSThomas Veerman /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
16318a5822eSThomas Veerman -pthreads is not specified. The functions are dummies and most return an
16418a5822eSThomas Veerman error value. However pthread_once returns 0 without invoking the routine
16518a5822eSThomas Veerman it is passed so we cannot pretend that the interface is active if -pthreads
16618a5822eSThomas Veerman is not specified. On Solaris 2.5.1, the interface is not exposed at all so
16718a5822eSThomas Veerman we need to play the usual game with weak symbols. On Solaris 10 and up, a
16818a5822eSThomas Veerman working interface is always exposed. On FreeBSD 6 and later, libc also
16918a5822eSThomas Veerman exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
17018a5822eSThomas Veerman to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
17118a5822eSThomas Veerman which means the alternate __gthread_active_p below cannot be used there. */
17218a5822eSThomas Veerman
17318a5822eSThomas Veerman #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
17418a5822eSThomas Veerman
17518a5822eSThomas Veerman static volatile int __gthread_active = -1;
17618a5822eSThomas Veerman
17718a5822eSThomas Veerman static void
__gthread_trigger(void)17818a5822eSThomas Veerman __gthread_trigger (void)
17918a5822eSThomas Veerman {
18018a5822eSThomas Veerman __gthread_active = 1;
18118a5822eSThomas Veerman }
18218a5822eSThomas Veerman
18318a5822eSThomas Veerman static inline int
__gthread_active_p(void)18418a5822eSThomas Veerman __gthread_active_p (void)
18518a5822eSThomas Veerman {
18618a5822eSThomas Veerman static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
18718a5822eSThomas Veerman static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
18818a5822eSThomas Veerman
18918a5822eSThomas Veerman /* Avoid reading __gthread_active twice on the main code path. */
19018a5822eSThomas Veerman int __gthread_active_latest_value = __gthread_active;
19118a5822eSThomas Veerman
19218a5822eSThomas Veerman /* This test is not protected to avoid taking a lock on the main code
19318a5822eSThomas Veerman path so every update of __gthread_active in a threaded program must
19418a5822eSThomas Veerman be atomic with regard to the result of the test. */
19518a5822eSThomas Veerman if (__builtin_expect (__gthread_active_latest_value < 0, 0))
19618a5822eSThomas Veerman {
19718a5822eSThomas Veerman if (__gthrw_(pthread_once))
19818a5822eSThomas Veerman {
19918a5822eSThomas Veerman /* If this really is a threaded program, then we must ensure that
20018a5822eSThomas Veerman __gthread_active has been set to 1 before exiting this block. */
20118a5822eSThomas Veerman __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
20218a5822eSThomas Veerman __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
20318a5822eSThomas Veerman __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
20418a5822eSThomas Veerman }
20518a5822eSThomas Veerman
20618a5822eSThomas Veerman /* Make sure we'll never enter this block again. */
20718a5822eSThomas Veerman if (__gthread_active < 0)
20818a5822eSThomas Veerman __gthread_active = 0;
20918a5822eSThomas Veerman
21018a5822eSThomas Veerman __gthread_active_latest_value = __gthread_active;
21118a5822eSThomas Veerman }
21218a5822eSThomas Veerman
21318a5822eSThomas Veerman return __gthread_active_latest_value != 0;
21418a5822eSThomas Veerman }
21518a5822eSThomas Veerman
21618a5822eSThomas Veerman #else /* neither FreeBSD nor Solaris */
21718a5822eSThomas Veerman
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
25018a5822eSThomas Veerman static inline int
25118a5822eSThomas Veerman __gthread_active_p (void)
25218a5822eSThomas Veerman {
25318a5822eSThomas Veerman static void *const __gthread_active_ptr
254*0a6a1f1dSLionel Sambuc = __extension__ (void *) >HR_ACTIVE_PROXY;
25518a5822eSThomas Veerman return __gthread_active_ptr != 0;
25618a5822eSThomas Veerman }
25718a5822eSThomas Veerman
25818a5822eSThomas Veerman #endif /* FreeBSD or Solaris */
25918a5822eSThomas Veerman
26018a5822eSThomas Veerman #else /* not __GXX_WEAK__ */
26118a5822eSThomas Veerman
26218a5822eSThomas Veerman /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
26318a5822eSThomas Veerman calls in shared flavors of the HP-UX C library. Most of the stubs
26418a5822eSThomas Veerman have no functionality. The details are described in the "libc cumulative
26518a5822eSThomas Veerman patch" for each subversion of HP-UX 11. There are two special interfaces
26618a5822eSThomas Veerman provided for checking whether an application is linked to a shared pthread
26718a5822eSThomas Veerman library or not. However, these interfaces aren't available in early
26818a5822eSThomas Veerman libpthread libraries. We also need a test that works for archive
26918a5822eSThomas Veerman libraries. We can't use pthread_once as some libc versions call the
27018a5822eSThomas Veerman init function. We also can't use pthread_create or pthread_attr_init
27118a5822eSThomas Veerman as these create a thread and thereby prevent changing the default stack
27218a5822eSThomas Veerman size. The function pthread_default_stacksize_np is available in both
27318a5822eSThomas Veerman the archive and shared versions of libpthread. It can be used to
27418a5822eSThomas Veerman determine the default pthread stack size. There is a stub in some
27518a5822eSThomas Veerman shared libc versions which returns a zero size if pthreads are not
27618a5822eSThomas Veerman active. We provide an equivalent stub to handle cases where libc
27718a5822eSThomas Veerman doesn't provide one. */
27818a5822eSThomas Veerman
27918a5822eSThomas Veerman #if defined(__hppa__) && defined(__hpux__)
28018a5822eSThomas Veerman
28118a5822eSThomas Veerman static volatile int __gthread_active = -1;
28218a5822eSThomas Veerman
28318a5822eSThomas Veerman static inline int
28418a5822eSThomas Veerman __gthread_active_p (void)
28518a5822eSThomas Veerman {
28618a5822eSThomas Veerman /* Avoid reading __gthread_active twice on the main code path. */
28718a5822eSThomas Veerman int __gthread_active_latest_value = __gthread_active;
28818a5822eSThomas Veerman size_t __s;
28918a5822eSThomas Veerman
29018a5822eSThomas Veerman if (__builtin_expect (__gthread_active_latest_value < 0, 0))
29118a5822eSThomas Veerman {
29218a5822eSThomas Veerman pthread_default_stacksize_np (0, &__s);
29318a5822eSThomas Veerman __gthread_active = __s ? 1 : 0;
29418a5822eSThomas Veerman __gthread_active_latest_value = __gthread_active;
29518a5822eSThomas Veerman }
29618a5822eSThomas Veerman
29718a5822eSThomas Veerman return __gthread_active_latest_value != 0;
29818a5822eSThomas Veerman }
29918a5822eSThomas Veerman
30018a5822eSThomas Veerman #else /* not hppa-hpux */
30118a5822eSThomas Veerman
30218a5822eSThomas Veerman static inline int
30318a5822eSThomas Veerman __gthread_active_p (void)
30418a5822eSThomas Veerman {
30518a5822eSThomas Veerman return 1;
30618a5822eSThomas Veerman }
30718a5822eSThomas Veerman
30818a5822eSThomas Veerman #endif /* hppa-hpux */
30918a5822eSThomas Veerman
31018a5822eSThomas Veerman #endif /* __GXX_WEAK__ */
31118a5822eSThomas Veerman
31218a5822eSThomas Veerman #ifdef _LIBOBJC
31318a5822eSThomas Veerman
31418a5822eSThomas Veerman /* This is the config.h file in libobjc/ */
31518a5822eSThomas Veerman #include <config.h>
31618a5822eSThomas Veerman
31718a5822eSThomas Veerman #ifdef HAVE_SCHED_H
31818a5822eSThomas Veerman # include <sched.h>
31918a5822eSThomas Veerman #endif
32018a5822eSThomas Veerman
32118a5822eSThomas Veerman /* Key structure for maintaining thread specific storage */
32218a5822eSThomas Veerman static pthread_key_t _objc_thread_storage;
32318a5822eSThomas Veerman static pthread_attr_t _objc_thread_attribs;
32418a5822eSThomas Veerman
32518a5822eSThomas Veerman /* Thread local storage for a single thread */
32618a5822eSThomas Veerman static void *thread_local_storage = NULL;
32718a5822eSThomas Veerman
32818a5822eSThomas Veerman /* Backend initialization functions */
32918a5822eSThomas Veerman
33018a5822eSThomas Veerman /* Initialize the threads subsystem. */
33118a5822eSThomas Veerman static inline int
__gthread_objc_init_thread_system(void)33218a5822eSThomas Veerman __gthread_objc_init_thread_system (void)
33318a5822eSThomas Veerman {
33418a5822eSThomas Veerman if (__gthread_active_p ())
33518a5822eSThomas Veerman {
33618a5822eSThomas Veerman /* Initialize the thread storage key. */
33718a5822eSThomas Veerman if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
33818a5822eSThomas Veerman {
33918a5822eSThomas Veerman /* The normal default detach state for threads is
34018a5822eSThomas Veerman * PTHREAD_CREATE_JOINABLE which causes threads to not die
34118a5822eSThomas Veerman * when you think they should. */
34218a5822eSThomas Veerman if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
34318a5822eSThomas Veerman && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
34418a5822eSThomas Veerman PTHREAD_CREATE_DETACHED) == 0)
34518a5822eSThomas Veerman return 0;
34618a5822eSThomas Veerman }
34718a5822eSThomas Veerman }
34818a5822eSThomas Veerman
34918a5822eSThomas Veerman return -1;
35018a5822eSThomas Veerman }
35118a5822eSThomas Veerman
35218a5822eSThomas Veerman /* Close the threads subsystem. */
35318a5822eSThomas Veerman static inline int
__gthread_objc_close_thread_system(void)35418a5822eSThomas Veerman __gthread_objc_close_thread_system (void)
35518a5822eSThomas Veerman {
35618a5822eSThomas Veerman if (__gthread_active_p ()
35718a5822eSThomas Veerman && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
35818a5822eSThomas Veerman && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
35918a5822eSThomas Veerman return 0;
36018a5822eSThomas Veerman
36118a5822eSThomas Veerman return -1;
36218a5822eSThomas Veerman }
36318a5822eSThomas Veerman
36418a5822eSThomas Veerman /* Backend thread functions */
36518a5822eSThomas Veerman
36618a5822eSThomas Veerman /* Create a new thread of execution. */
36718a5822eSThomas Veerman static inline objc_thread_t
__gthread_objc_thread_detach(void (* func)(void *),void * arg)36818a5822eSThomas Veerman __gthread_objc_thread_detach (void (*func)(void *), void *arg)
36918a5822eSThomas Veerman {
37018a5822eSThomas Veerman objc_thread_t thread_id;
37118a5822eSThomas Veerman pthread_t new_thread_handle;
37218a5822eSThomas Veerman
37318a5822eSThomas Veerman if (!__gthread_active_p ())
37418a5822eSThomas Veerman return NULL;
37518a5822eSThomas Veerman
376*0a6a1f1dSLionel Sambuc if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
377*0a6a1f1dSLionel Sambuc (void *) func, arg)))
37818a5822eSThomas Veerman thread_id = (objc_thread_t) new_thread_handle;
37918a5822eSThomas Veerman else
38018a5822eSThomas Veerman thread_id = NULL;
38118a5822eSThomas Veerman
38218a5822eSThomas Veerman return thread_id;
38318a5822eSThomas Veerman }
38418a5822eSThomas Veerman
38518a5822eSThomas Veerman /* Set the current thread's priority. */
38618a5822eSThomas Veerman static inline int
__gthread_objc_thread_set_priority(int priority)38718a5822eSThomas Veerman __gthread_objc_thread_set_priority (int priority)
38818a5822eSThomas Veerman {
38918a5822eSThomas Veerman if (!__gthread_active_p ())
39018a5822eSThomas Veerman return -1;
39118a5822eSThomas Veerman else
39218a5822eSThomas Veerman {
39318a5822eSThomas Veerman #ifdef _POSIX_PRIORITY_SCHEDULING
39418a5822eSThomas Veerman #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
39518a5822eSThomas Veerman pthread_t thread_id = __gthrw_(pthread_self) ();
39618a5822eSThomas Veerman int policy;
39718a5822eSThomas Veerman struct sched_param params;
39818a5822eSThomas Veerman int priority_min, priority_max;
39918a5822eSThomas Veerman
40018a5822eSThomas Veerman if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0)
40118a5822eSThomas Veerman {
40218a5822eSThomas Veerman if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
40318a5822eSThomas Veerman return -1;
40418a5822eSThomas Veerman
40518a5822eSThomas Veerman if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
40618a5822eSThomas Veerman return -1;
40718a5822eSThomas Veerman
40818a5822eSThomas Veerman if (priority > priority_max)
40918a5822eSThomas Veerman priority = priority_max;
41018a5822eSThomas Veerman else if (priority < priority_min)
41118a5822eSThomas Veerman priority = priority_min;
41218a5822eSThomas Veerman params.sched_priority = priority;
41318a5822eSThomas Veerman
41418a5822eSThomas Veerman /*
41518a5822eSThomas Veerman * The solaris 7 and several other man pages incorrectly state that
41618a5822eSThomas Veerman * this should be a pointer to policy but pthread.h is universally
41718a5822eSThomas Veerman * at odds with this.
41818a5822eSThomas Veerman */
41918a5822eSThomas Veerman if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0)
42018a5822eSThomas Veerman return 0;
42118a5822eSThomas Veerman }
42218a5822eSThomas Veerman #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
42318a5822eSThomas Veerman #endif /* _POSIX_PRIORITY_SCHEDULING */
42418a5822eSThomas Veerman return -1;
42518a5822eSThomas Veerman }
42618a5822eSThomas Veerman }
42718a5822eSThomas Veerman
42818a5822eSThomas Veerman /* Return the current thread's priority. */
42918a5822eSThomas Veerman static inline int
__gthread_objc_thread_get_priority(void)43018a5822eSThomas Veerman __gthread_objc_thread_get_priority (void)
43118a5822eSThomas Veerman {
43218a5822eSThomas Veerman #ifdef _POSIX_PRIORITY_SCHEDULING
43318a5822eSThomas Veerman #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
43418a5822eSThomas Veerman if (__gthread_active_p ())
43518a5822eSThomas Veerman {
43618a5822eSThomas Veerman int policy;
43718a5822eSThomas Veerman struct sched_param params;
43818a5822eSThomas Veerman
43918a5822eSThomas Veerman if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0)
44018a5822eSThomas Veerman return params.sched_priority;
44118a5822eSThomas Veerman else
44218a5822eSThomas Veerman return -1;
44318a5822eSThomas Veerman }
44418a5822eSThomas Veerman else
44518a5822eSThomas Veerman #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
44618a5822eSThomas Veerman #endif /* _POSIX_PRIORITY_SCHEDULING */
44718a5822eSThomas Veerman return OBJC_THREAD_INTERACTIVE_PRIORITY;
44818a5822eSThomas Veerman }
44918a5822eSThomas Veerman
45018a5822eSThomas Veerman /* Yield our process time to another thread. */
45118a5822eSThomas Veerman static inline void
__gthread_objc_thread_yield(void)45218a5822eSThomas Veerman __gthread_objc_thread_yield (void)
45318a5822eSThomas Veerman {
45418a5822eSThomas Veerman if (__gthread_active_p ())
45518a5822eSThomas Veerman __gthrw_(sched_yield) ();
45618a5822eSThomas Veerman }
45718a5822eSThomas Veerman
45818a5822eSThomas Veerman /* Terminate the current thread. */
45918a5822eSThomas Veerman static inline int
__gthread_objc_thread_exit(void)46018a5822eSThomas Veerman __gthread_objc_thread_exit (void)
46118a5822eSThomas Veerman {
46218a5822eSThomas Veerman if (__gthread_active_p ())
46318a5822eSThomas Veerman /* exit the thread */
46418a5822eSThomas Veerman __gthrw_(pthread_exit) (&__objc_thread_exit_status);
46518a5822eSThomas Veerman
46618a5822eSThomas Veerman /* Failed if we reached here */
46718a5822eSThomas Veerman return -1;
46818a5822eSThomas Veerman }
46918a5822eSThomas Veerman
47018a5822eSThomas Veerman /* Returns an integer value which uniquely describes a thread. */
47118a5822eSThomas Veerman static inline objc_thread_t
__gthread_objc_thread_id(void)47218a5822eSThomas Veerman __gthread_objc_thread_id (void)
47318a5822eSThomas Veerman {
47418a5822eSThomas Veerman if (__gthread_active_p ())
47518a5822eSThomas Veerman return (objc_thread_t) __gthrw_(pthread_self) ();
47618a5822eSThomas Veerman else
47718a5822eSThomas Veerman return (objc_thread_t) 1;
47818a5822eSThomas Veerman }
47918a5822eSThomas Veerman
48018a5822eSThomas Veerman /* Sets the thread's local storage pointer. */
48118a5822eSThomas Veerman static inline int
__gthread_objc_thread_set_data(void * value)48218a5822eSThomas Veerman __gthread_objc_thread_set_data (void *value)
48318a5822eSThomas Veerman {
48418a5822eSThomas Veerman if (__gthread_active_p ())
48518a5822eSThomas Veerman return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
48618a5822eSThomas Veerman else
48718a5822eSThomas Veerman {
48818a5822eSThomas Veerman thread_local_storage = value;
48918a5822eSThomas Veerman return 0;
49018a5822eSThomas Veerman }
49118a5822eSThomas Veerman }
49218a5822eSThomas Veerman
49318a5822eSThomas Veerman /* Returns the thread's local storage pointer. */
49418a5822eSThomas Veerman static inline void *
__gthread_objc_thread_get_data(void)49518a5822eSThomas Veerman __gthread_objc_thread_get_data (void)
49618a5822eSThomas Veerman {
49718a5822eSThomas Veerman if (__gthread_active_p ())
49818a5822eSThomas Veerman return __gthrw_(pthread_getspecific) (_objc_thread_storage);
49918a5822eSThomas Veerman else
50018a5822eSThomas Veerman return thread_local_storage;
50118a5822eSThomas Veerman }
50218a5822eSThomas Veerman
50318a5822eSThomas Veerman /* Backend mutex functions */
50418a5822eSThomas Veerman
50518a5822eSThomas Veerman /* Allocate a mutex. */
50618a5822eSThomas Veerman static inline int
__gthread_objc_mutex_allocate(objc_mutex_t mutex)50718a5822eSThomas Veerman __gthread_objc_mutex_allocate (objc_mutex_t mutex)
50818a5822eSThomas Veerman {
50918a5822eSThomas Veerman if (__gthread_active_p ())
51018a5822eSThomas Veerman {
51118a5822eSThomas Veerman mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
51218a5822eSThomas Veerman
51318a5822eSThomas Veerman if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
51418a5822eSThomas Veerman {
51518a5822eSThomas Veerman objc_free (mutex->backend);
51618a5822eSThomas Veerman mutex->backend = NULL;
51718a5822eSThomas Veerman return -1;
51818a5822eSThomas Veerman }
51918a5822eSThomas Veerman }
52018a5822eSThomas Veerman
52118a5822eSThomas Veerman return 0;
52218a5822eSThomas Veerman }
52318a5822eSThomas Veerman
52418a5822eSThomas Veerman /* Deallocate a mutex. */
52518a5822eSThomas Veerman static inline int
__gthread_objc_mutex_deallocate(objc_mutex_t mutex)52618a5822eSThomas Veerman __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
52718a5822eSThomas Veerman {
52818a5822eSThomas Veerman if (__gthread_active_p ())
52918a5822eSThomas Veerman {
53018a5822eSThomas Veerman int count;
53118a5822eSThomas Veerman
53218a5822eSThomas Veerman /*
53318a5822eSThomas Veerman * Posix Threads specifically require that the thread be unlocked
53418a5822eSThomas Veerman * for __gthrw_(pthread_mutex_destroy) to work.
53518a5822eSThomas Veerman */
53618a5822eSThomas Veerman
53718a5822eSThomas Veerman do
53818a5822eSThomas Veerman {
53918a5822eSThomas Veerman count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
54018a5822eSThomas Veerman if (count < 0)
54118a5822eSThomas Veerman return -1;
54218a5822eSThomas Veerman }
54318a5822eSThomas Veerman while (count);
54418a5822eSThomas Veerman
54518a5822eSThomas Veerman if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
54618a5822eSThomas Veerman return -1;
54718a5822eSThomas Veerman
54818a5822eSThomas Veerman objc_free (mutex->backend);
54918a5822eSThomas Veerman mutex->backend = NULL;
55018a5822eSThomas Veerman }
55118a5822eSThomas Veerman return 0;
55218a5822eSThomas Veerman }
55318a5822eSThomas Veerman
55418a5822eSThomas Veerman /* Grab a lock on a mutex. */
55518a5822eSThomas Veerman static inline int
__gthread_objc_mutex_lock(objc_mutex_t mutex)55618a5822eSThomas Veerman __gthread_objc_mutex_lock (objc_mutex_t mutex)
55718a5822eSThomas Veerman {
55818a5822eSThomas Veerman if (__gthread_active_p ()
55918a5822eSThomas Veerman && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
56018a5822eSThomas Veerman {
56118a5822eSThomas Veerman return -1;
56218a5822eSThomas Veerman }
56318a5822eSThomas Veerman
56418a5822eSThomas Veerman return 0;
56518a5822eSThomas Veerman }
56618a5822eSThomas Veerman
56718a5822eSThomas Veerman /* Try to grab a lock on a mutex. */
56818a5822eSThomas Veerman static inline int
__gthread_objc_mutex_trylock(objc_mutex_t mutex)56918a5822eSThomas Veerman __gthread_objc_mutex_trylock (objc_mutex_t mutex)
57018a5822eSThomas Veerman {
57118a5822eSThomas Veerman if (__gthread_active_p ()
57218a5822eSThomas Veerman && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
57318a5822eSThomas Veerman {
57418a5822eSThomas Veerman return -1;
57518a5822eSThomas Veerman }
57618a5822eSThomas Veerman
57718a5822eSThomas Veerman return 0;
57818a5822eSThomas Veerman }
57918a5822eSThomas Veerman
58018a5822eSThomas Veerman /* Unlock the mutex */
58118a5822eSThomas Veerman static inline int
__gthread_objc_mutex_unlock(objc_mutex_t mutex)58218a5822eSThomas Veerman __gthread_objc_mutex_unlock (objc_mutex_t mutex)
58318a5822eSThomas Veerman {
58418a5822eSThomas Veerman if (__gthread_active_p ()
58518a5822eSThomas Veerman && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
58618a5822eSThomas Veerman {
58718a5822eSThomas Veerman return -1;
58818a5822eSThomas Veerman }
58918a5822eSThomas Veerman
59018a5822eSThomas Veerman return 0;
59118a5822eSThomas Veerman }
59218a5822eSThomas Veerman
59318a5822eSThomas Veerman /* Backend condition mutex functions */
59418a5822eSThomas Veerman
59518a5822eSThomas Veerman /* Allocate a condition. */
59618a5822eSThomas Veerman static inline int
__gthread_objc_condition_allocate(objc_condition_t condition)59718a5822eSThomas Veerman __gthread_objc_condition_allocate (objc_condition_t condition)
59818a5822eSThomas Veerman {
59918a5822eSThomas Veerman if (__gthread_active_p ())
60018a5822eSThomas Veerman {
60118a5822eSThomas Veerman condition->backend = objc_malloc (sizeof (pthread_cond_t));
60218a5822eSThomas Veerman
60318a5822eSThomas Veerman if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
60418a5822eSThomas Veerman {
60518a5822eSThomas Veerman objc_free (condition->backend);
60618a5822eSThomas Veerman condition->backend = NULL;
60718a5822eSThomas Veerman return -1;
60818a5822eSThomas Veerman }
60918a5822eSThomas Veerman }
61018a5822eSThomas Veerman
61118a5822eSThomas Veerman return 0;
61218a5822eSThomas Veerman }
61318a5822eSThomas Veerman
61418a5822eSThomas Veerman /* Deallocate a condition. */
61518a5822eSThomas Veerman static inline int
__gthread_objc_condition_deallocate(objc_condition_t condition)61618a5822eSThomas Veerman __gthread_objc_condition_deallocate (objc_condition_t condition)
61718a5822eSThomas Veerman {
61818a5822eSThomas Veerman if (__gthread_active_p ())
61918a5822eSThomas Veerman {
62018a5822eSThomas Veerman if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
62118a5822eSThomas Veerman return -1;
62218a5822eSThomas Veerman
62318a5822eSThomas Veerman objc_free (condition->backend);
62418a5822eSThomas Veerman condition->backend = NULL;
62518a5822eSThomas Veerman }
62618a5822eSThomas Veerman return 0;
62718a5822eSThomas Veerman }
62818a5822eSThomas Veerman
62918a5822eSThomas Veerman /* Wait on the condition */
63018a5822eSThomas Veerman static inline int
__gthread_objc_condition_wait(objc_condition_t condition,objc_mutex_t mutex)63118a5822eSThomas Veerman __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
63218a5822eSThomas Veerman {
63318a5822eSThomas Veerman if (__gthread_active_p ())
63418a5822eSThomas Veerman return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
63518a5822eSThomas Veerman (pthread_mutex_t *) mutex->backend);
63618a5822eSThomas Veerman else
63718a5822eSThomas Veerman return 0;
63818a5822eSThomas Veerman }
63918a5822eSThomas Veerman
64018a5822eSThomas Veerman /* Wake up all threads waiting on this condition. */
64118a5822eSThomas Veerman static inline int
__gthread_objc_condition_broadcast(objc_condition_t condition)64218a5822eSThomas Veerman __gthread_objc_condition_broadcast (objc_condition_t condition)
64318a5822eSThomas Veerman {
64418a5822eSThomas Veerman if (__gthread_active_p ())
64518a5822eSThomas Veerman return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
64618a5822eSThomas Veerman else
64718a5822eSThomas Veerman return 0;
64818a5822eSThomas Veerman }
64918a5822eSThomas Veerman
65018a5822eSThomas Veerman /* Wake up one thread waiting on this condition. */
65118a5822eSThomas Veerman static inline int
__gthread_objc_condition_signal(objc_condition_t condition)65218a5822eSThomas Veerman __gthread_objc_condition_signal (objc_condition_t condition)
65318a5822eSThomas Veerman {
65418a5822eSThomas Veerman if (__gthread_active_p ())
65518a5822eSThomas Veerman return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
65618a5822eSThomas Veerman else
65718a5822eSThomas Veerman return 0;
65818a5822eSThomas Veerman }
65918a5822eSThomas Veerman
66018a5822eSThomas Veerman #else /* _LIBOBJC */
66118a5822eSThomas Veerman
66218a5822eSThomas Veerman static inline int
__gthread_create(__gthread_t * __threadid,void * (* __func)(void *),void * __args)66318a5822eSThomas Veerman __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
66418a5822eSThomas Veerman void *__args)
66518a5822eSThomas Veerman {
66618a5822eSThomas Veerman return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
66718a5822eSThomas Veerman }
66818a5822eSThomas Veerman
66918a5822eSThomas Veerman static inline int
__gthread_join(__gthread_t __threadid,void ** __value_ptr)67018a5822eSThomas Veerman __gthread_join (__gthread_t __threadid, void **__value_ptr)
67118a5822eSThomas Veerman {
67218a5822eSThomas Veerman return __gthrw_(pthread_join) (__threadid, __value_ptr);
67318a5822eSThomas Veerman }
67418a5822eSThomas Veerman
67518a5822eSThomas Veerman static inline int
__gthread_detach(__gthread_t __threadid)67618a5822eSThomas Veerman __gthread_detach (__gthread_t __threadid)
67718a5822eSThomas Veerman {
67818a5822eSThomas Veerman return __gthrw_(pthread_detach) (__threadid);
67918a5822eSThomas Veerman }
68018a5822eSThomas Veerman
68118a5822eSThomas Veerman static inline int
__gthread_equal(__gthread_t __t1,__gthread_t __t2)68218a5822eSThomas Veerman __gthread_equal (__gthread_t __t1, __gthread_t __t2)
68318a5822eSThomas Veerman {
68418a5822eSThomas Veerman return __gthrw_(pthread_equal) (__t1, __t2);
68518a5822eSThomas Veerman }
68618a5822eSThomas Veerman
68718a5822eSThomas Veerman static inline __gthread_t
__gthread_self(void)68818a5822eSThomas Veerman __gthread_self (void)
68918a5822eSThomas Veerman {
69018a5822eSThomas Veerman return __gthrw_(pthread_self) ();
69118a5822eSThomas Veerman }
69218a5822eSThomas Veerman
69318a5822eSThomas Veerman static inline int
__gthread_yield(void)69418a5822eSThomas Veerman __gthread_yield (void)
69518a5822eSThomas Veerman {
69618a5822eSThomas Veerman return __gthrw_(sched_yield) ();
69718a5822eSThomas Veerman }
69818a5822eSThomas Veerman
69918a5822eSThomas Veerman static inline int
__gthread_once(__gthread_once_t * __once,void (* __func)(void))70018a5822eSThomas Veerman __gthread_once (__gthread_once_t *__once, void (*__func) (void))
70118a5822eSThomas Veerman {
70218a5822eSThomas Veerman if (__gthread_active_p ())
70318a5822eSThomas Veerman return __gthrw_(pthread_once) (__once, __func);
70418a5822eSThomas Veerman else
70518a5822eSThomas Veerman return -1;
70618a5822eSThomas Veerman }
70718a5822eSThomas Veerman
70818a5822eSThomas Veerman static inline int
__gthread_key_create(__gthread_key_t * __key,void (* __dtor)(void *))70918a5822eSThomas Veerman __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
71018a5822eSThomas Veerman {
71118a5822eSThomas Veerman return __gthrw_(pthread_key_create) (__key, __dtor);
71218a5822eSThomas Veerman }
71318a5822eSThomas Veerman
71418a5822eSThomas Veerman static inline int
__gthread_key_delete(__gthread_key_t __key)71518a5822eSThomas Veerman __gthread_key_delete (__gthread_key_t __key)
71618a5822eSThomas Veerman {
71718a5822eSThomas Veerman return __gthrw_(pthread_key_delete) (__key);
71818a5822eSThomas Veerman }
71918a5822eSThomas Veerman
72018a5822eSThomas Veerman static inline void *
__gthread_getspecific(__gthread_key_t __key)72118a5822eSThomas Veerman __gthread_getspecific (__gthread_key_t __key)
72218a5822eSThomas Veerman {
72318a5822eSThomas Veerman return __gthrw_(pthread_getspecific) (__key);
72418a5822eSThomas Veerman }
72518a5822eSThomas Veerman
72618a5822eSThomas Veerman static inline int
__gthread_setspecific(__gthread_key_t __key,const void * __ptr)72718a5822eSThomas Veerman __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
72818a5822eSThomas Veerman {
72918a5822eSThomas Veerman return __gthrw_(pthread_setspecific) (__key, __ptr);
73018a5822eSThomas Veerman }
73118a5822eSThomas Veerman
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
73918a5822eSThomas Veerman static inline int
__gthread_mutex_destroy(__gthread_mutex_t * __mutex)74018a5822eSThomas Veerman __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
74118a5822eSThomas Veerman {
74218a5822eSThomas Veerman if (__gthread_active_p ())
74318a5822eSThomas Veerman return __gthrw_(pthread_mutex_destroy) (__mutex);
74418a5822eSThomas Veerman else
74518a5822eSThomas Veerman return 0;
74618a5822eSThomas Veerman }
74718a5822eSThomas Veerman
74818a5822eSThomas Veerman static inline int
__gthread_mutex_lock(__gthread_mutex_t * __mutex)74918a5822eSThomas Veerman __gthread_mutex_lock (__gthread_mutex_t *__mutex)
75018a5822eSThomas Veerman {
75118a5822eSThomas Veerman if (__gthread_active_p ())
75218a5822eSThomas Veerman return __gthrw_(pthread_mutex_lock) (__mutex);
75318a5822eSThomas Veerman else
75418a5822eSThomas Veerman return 0;
75518a5822eSThomas Veerman }
75618a5822eSThomas Veerman
75718a5822eSThomas Veerman static inline int
__gthread_mutex_trylock(__gthread_mutex_t * __mutex)75818a5822eSThomas Veerman __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
75918a5822eSThomas Veerman {
76018a5822eSThomas Veerman if (__gthread_active_p ())
76118a5822eSThomas Veerman return __gthrw_(pthread_mutex_trylock) (__mutex);
76218a5822eSThomas Veerman else
76318a5822eSThomas Veerman return 0;
76418a5822eSThomas Veerman }
76518a5822eSThomas Veerman
766*0a6a1f1dSLionel Sambuc #if _GTHREAD_USE_MUTEX_TIMEDLOCK
76718a5822eSThomas Veerman static inline int
__gthread_mutex_timedlock(__gthread_mutex_t * __mutex,const __gthread_time_t * __abs_timeout)76818a5822eSThomas Veerman __gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
76918a5822eSThomas Veerman const __gthread_time_t *__abs_timeout)
77018a5822eSThomas Veerman {
77118a5822eSThomas Veerman if (__gthread_active_p ())
77218a5822eSThomas Veerman return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
77318a5822eSThomas Veerman else
77418a5822eSThomas Veerman return 0;
77518a5822eSThomas Veerman }
77618a5822eSThomas Veerman #endif
77718a5822eSThomas Veerman
77818a5822eSThomas Veerman static inline int
__gthread_mutex_unlock(__gthread_mutex_t * __mutex)77918a5822eSThomas Veerman __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
78018a5822eSThomas Veerman {
78118a5822eSThomas Veerman if (__gthread_active_p ())
78218a5822eSThomas Veerman return __gthrw_(pthread_mutex_unlock) (__mutex);
78318a5822eSThomas Veerman else
78418a5822eSThomas Veerman return 0;
78518a5822eSThomas Veerman }
78618a5822eSThomas Veerman
787*0a6a1f1dSLionel Sambuc #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \
788*0a6a1f1dSLionel Sambuc || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC)
78918a5822eSThomas Veerman static inline int
__gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t * __mutex)79018a5822eSThomas Veerman __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
79118a5822eSThomas Veerman {
79218a5822eSThomas Veerman if (__gthread_active_p ())
79318a5822eSThomas Veerman {
79418a5822eSThomas Veerman pthread_mutexattr_t __attr;
79518a5822eSThomas Veerman int __r;
79618a5822eSThomas Veerman
79718a5822eSThomas Veerman __r = __gthrw_(pthread_mutexattr_init) (&__attr);
79818a5822eSThomas Veerman if (!__r)
79918a5822eSThomas Veerman __r = __gthrw_(pthread_mutexattr_settype) (&__attr,
80018a5822eSThomas Veerman PTHREAD_MUTEX_RECURSIVE);
80118a5822eSThomas Veerman if (!__r)
80218a5822eSThomas Veerman __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
80318a5822eSThomas Veerman if (!__r)
80418a5822eSThomas Veerman __r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
80518a5822eSThomas Veerman return __r;
80618a5822eSThomas Veerman }
80718a5822eSThomas Veerman return 0;
80818a5822eSThomas Veerman }
80918a5822eSThomas Veerman #endif
81018a5822eSThomas Veerman
81118a5822eSThomas Veerman static inline int
__gthread_recursive_mutex_lock(__gthread_recursive_mutex_t * __mutex)81218a5822eSThomas Veerman __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
81318a5822eSThomas Veerman {
81418a5822eSThomas Veerman return __gthread_mutex_lock (__mutex);
81518a5822eSThomas Veerman }
81618a5822eSThomas Veerman
81718a5822eSThomas Veerman static inline int
__gthread_recursive_mutex_trylock(__gthread_recursive_mutex_t * __mutex)81818a5822eSThomas Veerman __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
81918a5822eSThomas Veerman {
82018a5822eSThomas Veerman return __gthread_mutex_trylock (__mutex);
82118a5822eSThomas Veerman }
82218a5822eSThomas Veerman
823*0a6a1f1dSLionel Sambuc #if _GTHREAD_USE_MUTEX_TIMEDLOCK
82418a5822eSThomas Veerman static inline int
__gthread_recursive_mutex_timedlock(__gthread_recursive_mutex_t * __mutex,const __gthread_time_t * __abs_timeout)82518a5822eSThomas Veerman __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
82618a5822eSThomas Veerman const __gthread_time_t *__abs_timeout)
82718a5822eSThomas Veerman {
82818a5822eSThomas Veerman return __gthread_mutex_timedlock (__mutex, __abs_timeout);
82918a5822eSThomas Veerman }
83018a5822eSThomas Veerman #endif
83118a5822eSThomas Veerman
83218a5822eSThomas Veerman static inline int
__gthread_recursive_mutex_unlock(__gthread_recursive_mutex_t * __mutex)83318a5822eSThomas Veerman __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
83418a5822eSThomas Veerman {
83518a5822eSThomas Veerman return __gthread_mutex_unlock (__mutex);
83618a5822eSThomas Veerman }
83718a5822eSThomas Veerman
83818a5822eSThomas Veerman 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)85418a5822eSThomas Veerman __gthread_cond_broadcast (__gthread_cond_t *__cond)
85518a5822eSThomas Veerman {
85618a5822eSThomas Veerman return __gthrw_(pthread_cond_broadcast) (__cond);
85718a5822eSThomas Veerman }
85818a5822eSThomas Veerman
85918a5822eSThomas Veerman static inline int
__gthread_cond_signal(__gthread_cond_t * __cond)86018a5822eSThomas Veerman __gthread_cond_signal (__gthread_cond_t *__cond)
86118a5822eSThomas Veerman {
86218a5822eSThomas Veerman return __gthrw_(pthread_cond_signal) (__cond);
86318a5822eSThomas Veerman }
86418a5822eSThomas Veerman
86518a5822eSThomas Veerman static inline int
__gthread_cond_wait(__gthread_cond_t * __cond,__gthread_mutex_t * __mutex)86618a5822eSThomas Veerman __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
86718a5822eSThomas Veerman {
86818a5822eSThomas Veerman return __gthrw_(pthread_cond_wait) (__cond, __mutex);
86918a5822eSThomas Veerman }
87018a5822eSThomas Veerman
87118a5822eSThomas Veerman static inline int
__gthread_cond_timedwait(__gthread_cond_t * __cond,__gthread_mutex_t * __mutex,const __gthread_time_t * __abs_timeout)87218a5822eSThomas Veerman __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
87318a5822eSThomas Veerman const __gthread_time_t *__abs_timeout)
87418a5822eSThomas Veerman {
87518a5822eSThomas Veerman return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
87618a5822eSThomas Veerman }
87718a5822eSThomas Veerman
87818a5822eSThomas Veerman static inline int
__gthread_cond_wait_recursive(__gthread_cond_t * __cond,__gthread_recursive_mutex_t * __mutex)87918a5822eSThomas Veerman __gthread_cond_wait_recursive (__gthread_cond_t *__cond,
88018a5822eSThomas Veerman __gthread_recursive_mutex_t *__mutex)
88118a5822eSThomas Veerman {
88218a5822eSThomas Veerman return __gthread_cond_wait (__cond, __mutex);
88318a5822eSThomas Veerman }
88418a5822eSThomas Veerman
88518a5822eSThomas Veerman static inline int
__gthread_cond_destroy(__gthread_cond_t * __cond)88618a5822eSThomas Veerman __gthread_cond_destroy (__gthread_cond_t* __cond)
88718a5822eSThomas Veerman {
88818a5822eSThomas Veerman return __gthrw_(pthread_cond_destroy) (__cond);
88918a5822eSThomas Veerman }
89018a5822eSThomas Veerman
89118a5822eSThomas Veerman #endif /* _LIBOBJC */
89218a5822eSThomas Veerman
89318a5822eSThomas Veerman #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */
894