OSDN Git Service

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