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