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