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

Generated by: LCOV version 1.11