LCOV - code coverage report
Current view: top level - usr/include/c++/4.4/x86_64-linux-gnu/bits - gthr-default.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2 2 100.0 %
Date: 2017-07-14 10:03:36 Functions: 1 1 100.0 %

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

Generated by: LCOV version 1.11