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