]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gthr-posix.h
function.h (struct function): Rename calls_unwind_init to saves_all_registers.
[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
37
2a4e8ebc 38/* Some implementations of <pthread.h> require this to be defined. */
c2431a62 39#if !defined(_REENTRANT) && defined(__osf__)
2a4e8ebc
RO
40#define _REENTRANT 1
41#endif
42
f24af81b 43#include <pthread.h>
c95d07f8 44#include <unistd.h>
f24af81b
TT
45
46typedef pthread_key_t __gthread_key_t;
47typedef pthread_once_t __gthread_once_t;
48typedef pthread_mutex_t __gthread_mutex_t;
40aac948 49typedef pthread_mutex_t __gthread_recursive_mutex_t;
f24af81b
TT
50
51#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
52#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
40aac948
JM
53#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
54#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
55#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
56#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
e95dc99b 57#else
ab3d1049 58#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
40aac948 59#endif
f24af81b
TT
60
61#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
b36e79e5
RO
62# ifndef __gthrw_pragma
63# define __gthrw_pragma(pragma)
64# endif
a11dd268 65# define __gthrw2(name,name2,type) \
b36e79e5
RO
66 static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
67 __gthrw_pragma(weak type)
72b16773 68# define __gthrw_(name) __gthrw_ ## name
7ef67393 69#else
a11dd268 70# define __gthrw2(name,name2,type)
72b16773 71# define __gthrw_(name) name
7ef67393 72#endif
f24af81b 73
efbbbb61 74/* Typically, __gthrw_foo is a weak reference to symbol foo. */
a11dd268 75#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
c2a8530e
RS
76
77/* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
78 map a subset of the POSIX pthread API to mangled versions of their
79 names. */
80#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
a11dd268
RS
81#define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
82__gthrw3(pthread_once)
83__gthrw3(pthread_getspecific)
84__gthrw3(pthread_setspecific)
85__gthrw3(pthread_create)
86__gthrw3(pthread_cancel)
87__gthrw3(pthread_mutex_lock)
88__gthrw3(pthread_mutex_trylock)
89__gthrw3(pthread_mutex_unlock)
90__gthrw3(pthread_mutex_init)
c2a8530e 91#else
72b16773 92__gthrw(pthread_once)
72b16773
AO
93__gthrw(pthread_getspecific)
94__gthrw(pthread_setspecific)
95__gthrw(pthread_create)
96__gthrw(pthread_cancel)
72b16773
AO
97__gthrw(pthread_mutex_lock)
98__gthrw(pthread_mutex_trylock)
99__gthrw(pthread_mutex_unlock)
c2a8530e
RS
100__gthrw(pthread_mutex_init)
101#endif
102
103__gthrw(pthread_key_create)
104__gthrw(pthread_key_delete)
72b16773
AO
105__gthrw(pthread_mutexattr_init)
106__gthrw(pthread_mutexattr_settype)
107__gthrw(pthread_mutexattr_destroy)
70008293 108
15794a95 109
2a4e8ebc 110#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
40f03658 111/* Objective-C. */
c2a8530e 112#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
a11dd268
RS
113__gthrw3(pthread_cond_broadcast)
114__gthrw3(pthread_cond_destroy)
115__gthrw3(pthread_cond_init)
116__gthrw3(pthread_cond_signal)
117__gthrw3(pthread_cond_wait)
118__gthrw3(pthread_exit)
119__gthrw3(pthread_mutex_destroy)
120__gthrw3(pthread_self)
c2a8530e 121#else
72b16773
AO
122__gthrw(pthread_cond_broadcast)
123__gthrw(pthread_cond_destroy)
124__gthrw(pthread_cond_init)
125__gthrw(pthread_cond_signal)
126__gthrw(pthread_cond_wait)
127__gthrw(pthread_exit)
128__gthrw(pthread_mutex_destroy)
129__gthrw(pthread_self)
c2a8530e 130#endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
45863ba3 131#ifdef _POSIX_PRIORITY_SCHEDULING
c95d07f8 132#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773
AO
133__gthrw(sched_get_priority_max)
134__gthrw(sched_get_priority_min)
c95d07f8 135#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
45863ba3 136#endif /* _POSIX_PRIORITY_SCHEDULING */
72b16773
AO
137__gthrw(sched_yield)
138__gthrw(pthread_attr_destroy)
139__gthrw(pthread_attr_init)
140__gthrw(pthread_attr_setdetachstate)
c95d07f8 141#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773
AO
142__gthrw(pthread_getschedparam)
143__gthrw(pthread_setschedparam)
c95d07f8 144#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
2a4e8ebc 145#endif /* _LIBOBJC || _LIBOBJC_WEAK */
f24af81b 146
7ef67393
AO
147#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
148
efd6ef80
EB
149/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
150 -pthreads is not specified. The functions are dummies and most return an
151 error value. However pthread_once returns 0 without invoking the routine
152 it is passed so we cannot pretend that the interface is active if -pthreads
153 is not specified. On Solaris 2.5.1, the interface is not exposed at all so
154 we need to play the usual game with weak symbols. On Solaris 10 and up, a
155 working interface is always exposed. */
156
157#if defined(__sun) && defined(__svr4__)
158
159static volatile int __gthread_active = -1;
160
161static void
162__gthread_trigger (void)
163{
164 __gthread_active = 1;
165}
166
167static inline int
168__gthread_active_p (void)
169{
170 static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
171 static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
172
173 /* Avoid reading __gthread_active twice on the main code path. */
174 int __gthread_active_latest_value = __gthread_active;
175
176 /* This test is not protected to avoid taking a lock on the main code
177 path so every update of __gthread_active in a threaded program must
178 be atomic with regard to the result of the test. */
179 if (__builtin_expect (__gthread_active_latest_value < 0, 0))
180 {
181 if (__gthrw_(pthread_once))
182 {
183 /* If this really is a threaded program, then we must ensure that
184 __gthread_active has been set to 1 before exiting this block. */
185 __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
186 __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
187 __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
188 }
189
190 /* Make sure we'll never enter this block again. */
191 if (__gthread_active < 0)
192 __gthread_active = 0;
193
194 __gthread_active_latest_value = __gthread_active;
195 }
196
197 return __gthread_active_latest_value != 0;
198}
199
200#else /* not Solaris */
201
f24af81b 202static inline int
d1e51320 203__gthread_active_p (void)
f24af81b 204{
b235bd44 205 static void *const __gthread_active_ptr
72b16773 206 = __extension__ (void *) &__gthrw_(pthread_cancel);
f24af81b
TT
207 return __gthread_active_ptr != 0;
208}
209
efd6ef80
EB
210#endif /* Solaris */
211
f24af81b
TT
212#else /* not SUPPORTS_WEAK */
213
214static inline int
d1e51320 215__gthread_active_p (void)
f24af81b
TT
216{
217 return 1;
218}
219
220#endif /* SUPPORTS_WEAK */
221
15794a95
L
222#ifdef _LIBOBJC
223
5f974826
OP
224/* This is the config.h file in libobjc/ */
225#include <config.h>
226
227#ifdef HAVE_SCHED_H
228# include <sched.h>
229#endif
230
15794a95
L
231/* Key structure for maintaining thread specific storage */
232static pthread_key_t _objc_thread_storage;
447c11a5 233static pthread_attr_t _objc_thread_attribs;
15794a95
L
234
235/* Thread local storage for a single thread */
236static void *thread_local_storage = NULL;
237
238/* Backend initialization functions */
239
71287280 240/* Initialize the threads subsystem. */
15794a95 241static inline int
fe83a9ce 242__gthread_objc_init_thread_system (void)
15794a95
L
243{
244 if (__gthread_active_p ())
447c11a5 245 {
ea4b7848 246 /* Initialize the thread storage key. */
72b16773 247 if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
589005ff
KH
248 {
249 /* The normal default detach state for threads is
250 * PTHREAD_CREATE_JOINABLE which causes threads to not die
251 * when you think they should. */
72b16773
AO
252 if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
253 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
fe83a9ce 254 PTHREAD_CREATE_DETACHED) == 0)
589005ff
KH
255 return 0;
256 }
447c11a5 257 }
abc0360c
NP
258
259 return -1;
15794a95
L
260}
261
71287280 262/* Close the threads subsystem. */
15794a95 263static inline int
fe83a9ce 264__gthread_objc_close_thread_system (void)
15794a95 265{
447c11a5 266 if (__gthread_active_p ()
72b16773
AO
267 && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
268 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
15794a95 269 return 0;
447c11a5
OP
270
271 return -1;
15794a95
L
272}
273
274/* Backend thread functions */
275
71287280 276/* Create a new thread of execution. */
15794a95 277static inline objc_thread_t
fe83a9ce 278__gthread_objc_thread_detach (void (*func)(void *), void *arg)
15794a95
L
279{
280 objc_thread_t thread_id;
281 pthread_t new_thread_handle;
282
283 if (!__gthread_active_p ())
284 return NULL;
589005ff 285
72b16773 286 if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
fee013ef 287 thread_id = (objc_thread_t) new_thread_handle;
15794a95
L
288 else
289 thread_id = NULL;
589005ff 290
15794a95
L
291 return thread_id;
292}
293
71287280 294/* Set the current thread's priority. */
15794a95 295static inline int
fe83a9ce 296__gthread_objc_thread_set_priority (int priority)
15794a95 297{
fe83a9ce 298 if (!__gthread_active_p ())
447c11a5 299 return -1;
fe83a9ce
KH
300 else
301 {
45863ba3 302#ifdef _POSIX_PRIORITY_SCHEDULING
c95d07f8 303#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773 304 pthread_t thread_id = __gthrw_(pthread_self) ();
fe83a9ce
KH
305 int policy;
306 struct sched_param params;
307 int priority_min, priority_max;
589005ff 308
72b16773 309 if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
fe83a9ce 310 {
72b16773 311 if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
fe83a9ce
KH
312 return -1;
313
72b16773 314 if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
fe83a9ce 315 return -1;
589005ff 316
fe83a9ce
KH
317 if (priority > priority_max)
318 priority = priority_max;
319 else if (priority < priority_min)
320 priority = priority_min;
321 params.sched_priority = priority;
322
323 /*
324 * The solaris 7 and several other man pages incorrectly state that
325 * this should be a pointer to policy but pthread.h is universally
326 * at odds with this.
327 */
72b16773 328 if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
fe83a9ce
KH
329 return 0;
330 }
c95d07f8 331#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
45863ba3 332#endif /* _POSIX_PRIORITY_SCHEDULING */
fe83a9ce
KH
333 return -1;
334 }
15794a95
L
335}
336
71287280 337/* Return the current thread's priority. */
15794a95 338static inline int
fe83a9ce 339__gthread_objc_thread_get_priority (void)
15794a95 340{
45863ba3 341#ifdef _POSIX_PRIORITY_SCHEDULING
c95d07f8 342#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
15794a95 343 if (__gthread_active_p ())
447c11a5
OP
344 {
345 int policy;
346 struct sched_param params;
347
72b16773 348 if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
589005ff 349 return params.sched_priority;
447c11a5 350 else
589005ff 351 return -1;
447c11a5 352 }
15794a95 353 else
c95d07f8 354#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
45863ba3 355#endif /* _POSIX_PRIORITY_SCHEDULING */
15794a95
L
356 return OBJC_THREAD_INTERACTIVE_PRIORITY;
357}
358
71287280 359/* Yield our process time to another thread. */
15794a95 360static inline void
fe83a9ce 361__gthread_objc_thread_yield (void)
15794a95
L
362{
363 if (__gthread_active_p ())
72b16773 364 __gthrw_(sched_yield) ();
15794a95
L
365}
366
71287280 367/* Terminate the current thread. */
15794a95 368static inline int
fe83a9ce 369__gthread_objc_thread_exit (void)
15794a95
L
370{
371 if (__gthread_active_p ())
372 /* exit the thread */
72b16773 373 __gthrw_(pthread_exit) (&__objc_thread_exit_status);
15794a95
L
374
375 /* Failed if we reached here */
376 return -1;
377}
378
71287280 379/* Returns an integer value which uniquely describes a thread. */
15794a95 380static inline objc_thread_t
fe83a9ce 381__gthread_objc_thread_id (void)
15794a95
L
382{
383 if (__gthread_active_p ())
72b16773 384 return (objc_thread_t) __gthrw_(pthread_self) ();
15794a95 385 else
fee013ef 386 return (objc_thread_t) 1;
15794a95
L
387}
388
71287280 389/* Sets the thread's local storage pointer. */
15794a95 390static inline int
fe83a9ce 391__gthread_objc_thread_set_data (void *value)
15794a95
L
392{
393 if (__gthread_active_p ())
72b16773 394 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
15794a95
L
395 else
396 {
397 thread_local_storage = value;
398 return 0;
399 }
400}
401
71287280 402/* Returns the thread's local storage pointer. */
15794a95 403static inline void *
fe83a9ce 404__gthread_objc_thread_get_data (void)
15794a95
L
405{
406 if (__gthread_active_p ())
72b16773 407 return __gthrw_(pthread_getspecific) (_objc_thread_storage);
15794a95
L
408 else
409 return thread_local_storage;
410}
411
412/* Backend mutex functions */
413
71287280 414/* Allocate a mutex. */
15794a95 415static inline int
fe83a9ce 416__gthread_objc_mutex_allocate (objc_mutex_t mutex)
15794a95
L
417{
418 if (__gthread_active_p ())
419 {
fe83a9ce 420 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
15794a95 421
72b16773 422 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
15794a95 423 {
fe83a9ce 424 objc_free (mutex->backend);
15794a95
L
425 mutex->backend = NULL;
426 return -1;
427 }
428 }
429
430 return 0;
431}
432
71287280 433/* Deallocate a mutex. */
15794a95 434static inline int
fe83a9ce 435__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
15794a95
L
436{
437 if (__gthread_active_p ())
438 {
439 int count;
440
441 /*
442 * Posix Threads specifically require that the thread be unlocked
72b16773 443 * for __gthrw_(pthread_mutex_destroy) to work.
15794a95
L
444 */
445
446 do
447 {
72b16773 448 count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
15794a95
L
449 if (count < 0)
450 return -1;
451 }
452 while (count);
453
72b16773 454 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
15794a95
L
455 return -1;
456
fe83a9ce 457 objc_free (mutex->backend);
15794a95
L
458 mutex->backend = NULL;
459 }
460 return 0;
461}
462
71287280 463/* Grab a lock on a mutex. */
15794a95 464static inline int
fe83a9ce 465__gthread_objc_mutex_lock (objc_mutex_t mutex)
15794a95 466{
589005ff 467 if (__gthread_active_p ()
72b16773 468 && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
054af139
NP
469 {
470 return -1;
471 }
472
473 return 0;
15794a95
L
474}
475
71287280 476/* Try to grab a lock on a mutex. */
15794a95 477static inline int
fe83a9ce 478__gthread_objc_mutex_trylock (objc_mutex_t mutex)
15794a95 479{
589005ff 480 if (__gthread_active_p ()
72b16773 481 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
054af139
NP
482 {
483 return -1;
484 }
485
486 return 0;
15794a95
L
487}
488
489/* Unlock the mutex */
490static inline int
fe83a9ce 491__gthread_objc_mutex_unlock (objc_mutex_t mutex)
15794a95 492{
589005ff 493 if (__gthread_active_p ()
72b16773 494 && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
054af139
NP
495 {
496 return -1;
497 }
498
499 return 0;
15794a95
L
500}
501
502/* Backend condition mutex functions */
503
71287280 504/* Allocate a condition. */
15794a95 505static inline int
fe83a9ce 506__gthread_objc_condition_allocate (objc_condition_t condition)
15794a95
L
507{
508 if (__gthread_active_p ())
509 {
fe83a9ce 510 condition->backend = objc_malloc (sizeof (pthread_cond_t));
15794a95 511
72b16773 512 if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
15794a95 513 {
fe83a9ce 514 objc_free (condition->backend);
15794a95
L
515 condition->backend = NULL;
516 return -1;
517 }
518 }
519
520 return 0;
521}
522
71287280 523/* Deallocate a condition. */
15794a95 524static inline int
fe83a9ce 525__gthread_objc_condition_deallocate (objc_condition_t condition)
15794a95
L
526{
527 if (__gthread_active_p ())
528 {
72b16773 529 if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
15794a95
L
530 return -1;
531
fe83a9ce 532 objc_free (condition->backend);
15794a95
L
533 condition->backend = NULL;
534 }
535 return 0;
536}
537
538/* Wait on the condition */
539static inline int
fe83a9ce 540__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
15794a95
L
541{
542 if (__gthread_active_p ())
72b16773 543 return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
fe83a9ce 544 (pthread_mutex_t *) mutex->backend);
15794a95
L
545 else
546 return 0;
547}
548
71287280 549/* Wake up all threads waiting on this condition. */
15794a95 550static inline int
fe83a9ce 551__gthread_objc_condition_broadcast (objc_condition_t condition)
15794a95
L
552{
553 if (__gthread_active_p ())
72b16773 554 return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
15794a95
L
555 else
556 return 0;
557}
558
71287280 559/* Wake up one thread waiting on this condition. */
15794a95 560static inline int
fe83a9ce 561__gthread_objc_condition_signal (objc_condition_t condition)
15794a95
L
562{
563 if (__gthread_active_p ())
72b16773 564 return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
15794a95
L
565 else
566 return 0;
567}
568
569#else /* _LIBOBJC */
570
f24af81b 571static inline int
d1e51320 572__gthread_once (__gthread_once_t *once, void (*func) (void))
f24af81b
TT
573{
574 if (__gthread_active_p ())
72b16773 575 return __gthrw_(pthread_once) (once, func);
f24af81b
TT
576 else
577 return -1;
578}
579
580static inline int
581__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
582{
72b16773 583 return __gthrw_(pthread_key_create) (key, dtor);
f24af81b
TT
584}
585
f24af81b
TT
586static inline int
587__gthread_key_delete (__gthread_key_t key)
588{
72b16773 589 return __gthrw_(pthread_key_delete) (key);
f24af81b
TT
590}
591
592static inline void *
593__gthread_getspecific (__gthread_key_t key)
594{
72b16773 595 return __gthrw_(pthread_getspecific) (key);
f24af81b
TT
596}
597
598static inline int
599__gthread_setspecific (__gthread_key_t key, const void *ptr)
600{
72b16773 601 return __gthrw_(pthread_setspecific) (key, ptr);
f24af81b
TT
602}
603
604static inline int
605__gthread_mutex_lock (__gthread_mutex_t *mutex)
606{
607 if (__gthread_active_p ())
72b16773 608 return __gthrw_(pthread_mutex_lock) (mutex);
f24af81b
TT
609 else
610 return 0;
611}
612
613static inline int
614__gthread_mutex_trylock (__gthread_mutex_t *mutex)
615{
616 if (__gthread_active_p ())
72b16773 617 return __gthrw_(pthread_mutex_trylock) (mutex);
f24af81b
TT
618 else
619 return 0;
620}
621
622static inline int
623__gthread_mutex_unlock (__gthread_mutex_t *mutex)
624{
625 if (__gthread_active_p ())
72b16773 626 return __gthrw_(pthread_mutex_unlock) (mutex);
f24af81b
TT
627 else
628 return 0;
629}
630
ab3d1049 631#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
40aac948
JM
632static inline int
633__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
634{
635 if (__gthread_active_p ())
636 {
637 pthread_mutexattr_t attr;
638 int r;
639
72b16773 640 r = __gthrw_(pthread_mutexattr_init) (&attr);
40aac948 641 if (!r)
72b16773 642 r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
40aac948 643 if (!r)
72b16773 644 r = __gthrw_(pthread_mutex_init) (mutex, &attr);
40aac948 645 if (!r)
72b16773 646 r = __gthrw_(pthread_mutexattr_destroy) (&attr);
40aac948
JM
647 return r;
648 }
7c68fabb 649 return 0;
40aac948
JM
650}
651#endif
652
653static inline int
654__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
655{
656 return __gthread_mutex_lock (mutex);
657}
658
659static inline int
660__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
661{
662 return __gthread_mutex_trylock (mutex);
663}
664
665static inline int
666__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
667{
668 return __gthread_mutex_unlock (mutex);
669}
670
15794a95
L
671#endif /* _LIBOBJC */
672
88657302 673#endif /* ! GCC_GTHR_POSIX_H */