]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/gthr-posix.h
Reset PHI base0 flag if it's clear in any argument [PR101977, ...]
[thirdparty/gcc.git] / libgcc / gthr-posix.h
CommitLineData
15794a95 1/* Threads compatibility routines for libgcc2 and libobjc. */
f24af81b 2/* Compile this one with gcc. */
99dee823 3/* Copyright (C) 1997-2021 Free Software Foundation, Inc.
f24af81b 4
1322177d 5This file is part of GCC.
f24af81b 6
1322177d
LB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
748086b7 9Software Foundation; either version 3, or (at your option) any later
1322177d 10version.
f24af81b 11
1322177d
LB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
f24af81b 16
748086b7
JJ
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
f24af81b 25
88657302
RH
26#ifndef GCC_GTHR_POSIX_H
27#define GCC_GTHR_POSIX_H
f24af81b
TT
28
29/* POSIX threads specific definitions.
71287280 30 Easy, since the interface is just one-to-one mapping. */
f24af81b
TT
31
32#define __GTHREADS 1
a75150ae 33#define __GTHREADS_CXX0X 1
f24af81b
TT
34
35#include <pthread.h>
6545e33e
PC
36
37#if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \
38 || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK))
39# include <unistd.h>
40# if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0
41# define _GTHREAD_USE_MUTEX_TIMEDLOCK 1
42# else
43# define _GTHREAD_USE_MUTEX_TIMEDLOCK 0
44# endif
45#endif
f24af81b 46
a75150ae 47typedef pthread_t __gthread_t;
f24af81b
TT
48typedef pthread_key_t __gthread_key_t;
49typedef pthread_once_t __gthread_once_t;
50typedef pthread_mutex_t __gthread_mutex_t;
40aac948 51typedef pthread_mutex_t __gthread_recursive_mutex_t;
afd82ef5 52typedef pthread_cond_t __gthread_cond_t;
a75150ae 53typedef struct timespec __gthread_time_t;
afd82ef5
DK
54
55/* POSIX like conditional variables are supported. Please look at comments
56 in gthr.h for details. */
b8698a0f 57#define __GTHREAD_HAS_COND 1
f24af81b
TT
58
59#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
33e3e24d 60#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
f24af81b 61#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
40aac948
JM
62#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
63#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
64#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
65#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
e95dc99b 66#else
ab3d1049 67#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
40aac948 68#endif
afd82ef5 69#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
a75150ae 70#define __GTHREAD_TIME_INIT {0,0}
f24af81b 71
b59cbd50
JW
72#ifdef _GTHREAD_USE_MUTEX_INIT_FUNC
73# undef __GTHREAD_MUTEX_INIT
b59cbd50
JW
74#endif
75#ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
76# undef __GTHREAD_RECURSIVE_MUTEX_INIT
77# undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
78# define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
79#endif
80#ifdef _GTHREAD_USE_COND_INIT_FUNC
81# undef __GTHREAD_COND_INIT
82# define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
83#endif
84
f24af81b 85#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
b36e79e5
RO
86# ifndef __gthrw_pragma
87# define __gthrw_pragma(pragma)
88# endif
a11dd268 89# define __gthrw2(name,name2,type) \
29d24852
MS
90 static __typeof(type) name \
91 __attribute__ ((__weakref__(#name2), __copy__ (type))); \
b36e79e5 92 __gthrw_pragma(weak type)
72b16773 93# define __gthrw_(name) __gthrw_ ## name
7ef67393 94#else
a11dd268 95# define __gthrw2(name,name2,type)
72b16773 96# define __gthrw_(name) name
7ef67393 97#endif
f24af81b 98
efbbbb61 99/* Typically, __gthrw_foo is a weak reference to symbol foo. */
a11dd268 100#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
c2a8530e 101
72b16773 102__gthrw(pthread_once)
72b16773
AO
103__gthrw(pthread_getspecific)
104__gthrw(pthread_setspecific)
a75150ae 105
72b16773 106__gthrw(pthread_create)
a75150ae
CF
107__gthrw(pthread_join)
108__gthrw(pthread_equal)
109__gthrw(pthread_self)
110__gthrw(pthread_detach)
3714764d 111#ifndef __BIONIC__
72b16773 112__gthrw(pthread_cancel)
3714764d 113#endif
a75150ae
CF
114__gthrw(sched_yield)
115
72b16773
AO
116__gthrw(pthread_mutex_lock)
117__gthrw(pthread_mutex_trylock)
6545e33e 118#if _GTHREAD_USE_MUTEX_TIMEDLOCK
a75150ae 119__gthrw(pthread_mutex_timedlock)
1cd8b853 120#endif
72b16773 121__gthrw(pthread_mutex_unlock)
c2a8530e 122__gthrw(pthread_mutex_init)
4dabf736 123__gthrw(pthread_mutex_destroy)
a75150ae 124
b59cbd50 125__gthrw(pthread_cond_init)
afd82ef5 126__gthrw(pthread_cond_broadcast)
a75150ae 127__gthrw(pthread_cond_signal)
afd82ef5 128__gthrw(pthread_cond_wait)
a75150ae
CF
129__gthrw(pthread_cond_timedwait)
130__gthrw(pthread_cond_destroy)
c2a8530e
RS
131
132__gthrw(pthread_key_create)
133__gthrw(pthread_key_delete)
72b16773
AO
134__gthrw(pthread_mutexattr_init)
135__gthrw(pthread_mutexattr_settype)
136__gthrw(pthread_mutexattr_destroy)
70008293 137
15794a95 138
2a4e8ebc 139#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
40f03658 140/* Objective-C. */
72b16773 141__gthrw(pthread_exit)
45863ba3 142#ifdef _POSIX_PRIORITY_SCHEDULING
c95d07f8 143#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773
AO
144__gthrw(sched_get_priority_max)
145__gthrw(sched_get_priority_min)
c95d07f8 146#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
45863ba3 147#endif /* _POSIX_PRIORITY_SCHEDULING */
72b16773
AO
148__gthrw(pthread_attr_destroy)
149__gthrw(pthread_attr_init)
150__gthrw(pthread_attr_setdetachstate)
c95d07f8 151#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773
AO
152__gthrw(pthread_getschedparam)
153__gthrw(pthread_setschedparam)
c95d07f8 154#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
2a4e8ebc 155#endif /* _LIBOBJC || _LIBOBJC_WEAK */
f24af81b 156
7ef67393
AO
157#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
158
efd6ef80
EB
159/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
160 -pthreads is not specified. The functions are dummies and most return an
161 error value. However pthread_once returns 0 without invoking the routine
162 it is passed so we cannot pretend that the interface is active if -pthreads
163 is not specified. On Solaris 2.5.1, the interface is not exposed at all so
164 we need to play the usual game with weak symbols. On Solaris 10 and up, a
799cff46
MS
165 working interface is always exposed. On FreeBSD 6 and later, libc also
166 exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
167 to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
168 which means the alternate __gthread_active_p below cannot be used there. */
efd6ef80 169
799cff46 170#if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
efd6ef80
EB
171
172static volatile int __gthread_active = -1;
173
174static void
175__gthread_trigger (void)
176{
177 __gthread_active = 1;
178}
179
180static inline int
181__gthread_active_p (void)
182{
183 static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
184 static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
185
186 /* Avoid reading __gthread_active twice on the main code path. */
187 int __gthread_active_latest_value = __gthread_active;
188
189 /* This test is not protected to avoid taking a lock on the main code
190 path so every update of __gthread_active in a threaded program must
191 be atomic with regard to the result of the test. */
192 if (__builtin_expect (__gthread_active_latest_value < 0, 0))
193 {
194 if (__gthrw_(pthread_once))
195 {
196 /* If this really is a threaded program, then we must ensure that
197 __gthread_active has been set to 1 before exiting this block. */
198 __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
199 __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
200 __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
201 }
202
203 /* Make sure we'll never enter this block again. */
204 if (__gthread_active < 0)
205 __gthread_active = 0;
206
207 __gthread_active_latest_value = __gthread_active;
208 }
209
210 return __gthread_active_latest_value != 0;
211}
212
799cff46 213#else /* neither FreeBSD nor Solaris */
efd6ef80 214
67a218c5
RM
215/* For a program to be multi-threaded the only thing that it certainly must
216 be using is pthread_create. However, there may be other libraries that
217 intercept pthread_create with their own definitions to wrap pthreads
218 functionality for some purpose. In those cases, pthread_create being
219 defined might not necessarily mean that libpthread is actually linked
220 in.
221
222 For the GNU C library, we can use a known internal name. This is always
223 available in the ABI, but no other library would define it. That is
224 ideal, since any public pthread function might be intercepted just as
225 pthread_create might be. __pthread_key_create is an "internal"
226 implementation symbol, but it is part of the public exported ABI. Also,
227 it's among the symbols that the static libpthread.a always links in
228 whenever pthread_create is used, so there is no danger of a false
229 negative result in any statically-linked, multi-threaded program.
230
231 For others, we choose pthread_cancel as a function that seems unlikely
232 to be redefined by an interceptor library. The bionic (Android) C
233 library does not provide pthread_cancel, so we do use pthread_create
234 there (and interceptor libraries lose). */
235
236#ifdef __GLIBC__
237__gthrw2(__gthrw_(__pthread_key_create),
238 __pthread_key_create,
239 pthread_key_create)
240# define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create)
241#elif defined (__BIONIC__)
242# define GTHR_ACTIVE_PROXY __gthrw_(pthread_create)
243#else
244# define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel)
245#endif
246
f24af81b 247static inline int
d1e51320 248__gthread_active_p (void)
f24af81b 249{
e621f530 250 static void *const __gthread_active_ptr
67a218c5 251 = __extension__ (void *) &GTHR_ACTIVE_PROXY;
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
b59cbd50
JW
729static inline void
730__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
731{
732 if (__gthread_active_p ())
733 __gthrw_(pthread_mutex_init) (__mutex, NULL);
734}
33e3e24d 735
4dabf736 736static inline int
09e361bb 737__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
4dabf736
JB
738{
739 if (__gthread_active_p ())
09e361bb 740 return __gthrw_(pthread_mutex_destroy) (__mutex);
4dabf736
JB
741 else
742 return 0;
743}
744
f24af81b 745static inline int
09e361bb 746__gthread_mutex_lock (__gthread_mutex_t *__mutex)
f24af81b
TT
747{
748 if (__gthread_active_p ())
09e361bb 749 return __gthrw_(pthread_mutex_lock) (__mutex);
f24af81b
TT
750 else
751 return 0;
752}
753
754static inline int
09e361bb 755__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
f24af81b
TT
756{
757 if (__gthread_active_p ())
09e361bb 758 return __gthrw_(pthread_mutex_trylock) (__mutex);
f24af81b
TT
759 else
760 return 0;
761}
762
6545e33e 763#if _GTHREAD_USE_MUTEX_TIMEDLOCK
a75150ae 764static inline int
09e361bb
JJ
765__gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
766 const __gthread_time_t *__abs_timeout)
a75150ae
CF
767{
768 if (__gthread_active_p ())
09e361bb 769 return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
a75150ae
CF
770 else
771 return 0;
772}
773#endif
774
f24af81b 775static inline int
09e361bb 776__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
f24af81b
TT
777{
778 if (__gthread_active_p ())
09e361bb 779 return __gthrw_(pthread_mutex_unlock) (__mutex);
f24af81b
TT
780 else
781 return 0;
782}
783
b59cbd50
JW
784#if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \
785 || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC)
40aac948 786static inline int
09e361bb 787__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
40aac948
JM
788{
789 if (__gthread_active_p ())
790 {
09e361bb
JJ
791 pthread_mutexattr_t __attr;
792 int __r;
793
794 __r = __gthrw_(pthread_mutexattr_init) (&__attr);
795 if (!__r)
796 __r = __gthrw_(pthread_mutexattr_settype) (&__attr,
797 PTHREAD_MUTEX_RECURSIVE);
798 if (!__r)
799 __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
800 if (!__r)
801 __r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
802 return __r;
40aac948 803 }
7c68fabb 804 return 0;
40aac948
JM
805}
806#endif
807
808static inline int
09e361bb 809__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
40aac948 810{
09e361bb 811 return __gthread_mutex_lock (__mutex);
40aac948
JM
812}
813
814static inline int
09e361bb 815__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
40aac948 816{
09e361bb 817 return __gthread_mutex_trylock (__mutex);
40aac948
JM
818}
819
6545e33e 820#if _GTHREAD_USE_MUTEX_TIMEDLOCK
a75150ae 821static inline int
09e361bb
JJ
822__gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
823 const __gthread_time_t *__abs_timeout)
a75150ae 824{
09e361bb 825 return __gthread_mutex_timedlock (__mutex, __abs_timeout);
a75150ae
CF
826}
827#endif
828
40aac948 829static inline int
09e361bb 830__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
40aac948 831{
09e361bb 832 return __gthread_mutex_unlock (__mutex);
40aac948
JM
833}
834
1504e3e1
JW
835static inline int
836__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
837{
838 return __gthread_mutex_destroy (__mutex);
839}
840
b59cbd50
JW
841#ifdef _GTHREAD_USE_COND_INIT_FUNC
842static inline void
843__gthread_cond_init_function (__gthread_cond_t *__cond)
844{
845 if (__gthread_active_p ())
846 __gthrw_(pthread_cond_init) (__cond, NULL);
847}
848#endif
849
afd82ef5 850static inline int
09e361bb 851__gthread_cond_broadcast (__gthread_cond_t *__cond)
afd82ef5 852{
09e361bb 853 return __gthrw_(pthread_cond_broadcast) (__cond);
afd82ef5
DK
854}
855
a75150ae 856static inline int
09e361bb 857__gthread_cond_signal (__gthread_cond_t *__cond)
a75150ae 858{
09e361bb 859 return __gthrw_(pthread_cond_signal) (__cond);
a75150ae
CF
860}
861
afd82ef5 862static inline int
09e361bb 863__gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
afd82ef5 864{
09e361bb 865 return __gthrw_(pthread_cond_wait) (__cond, __mutex);
afd82ef5
DK
866}
867
a75150ae 868static inline int
09e361bb
JJ
869__gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
870 const __gthread_time_t *__abs_timeout)
a75150ae 871{
09e361bb 872 return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
a75150ae
CF
873}
874
afd82ef5 875static inline int
09e361bb
JJ
876__gthread_cond_wait_recursive (__gthread_cond_t *__cond,
877 __gthread_recursive_mutex_t *__mutex)
afd82ef5 878{
09e361bb 879 return __gthread_cond_wait (__cond, __mutex);
afd82ef5
DK
880}
881
a75150ae 882static inline int
09e361bb 883__gthread_cond_destroy (__gthread_cond_t* __cond)
a75150ae 884{
09e361bb 885 return __gthrw_(pthread_cond_destroy) (__cond);
a75150ae
CF
886}
887
15794a95
L
888#endif /* _LIBOBJC */
889
88657302 890#endif /* ! GCC_GTHR_POSIX_H */