xref: /minix3/external/gpl3/gcc/lib/libstdc++-v3/arch/vax/gthr-posix.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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 *) &GTHR_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, &params) == 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, &params) == 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, &params) == 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