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