LCOV - code coverage report
Current view: top level - usr/include/x86_64-linux-gnu/c++/9/bits - gthr-default.h (source / functions) Hit Total Coverage
Test: ROSE Lines: 9 9 100.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14