gthr-default.h

00001 /* Threads compatibility routines for libgcc2 and libobjc.  */
00002 /* Compile this one with gcc.  */
00003 /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
00004    2008, 2009 Free Software Foundation, Inc.
00005 
00006 This file is part of GCC.
00007 
00008 GCC is free software; you can redistribute it and/or modify it under
00009 the terms of the GNU General Public License as published by the Free
00010 Software Foundation; either version 3, or (at your option) any later
00011 version.
00012 
00013 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
00014 WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 Under Section 7 of GPL version 3, you are granted additional
00019 permissions described in the GCC Runtime Library Exception, version
00020 3.1, as published by the Free Software Foundation.
00021 
00022 You should have received a copy of the GNU General Public License and
00023 a copy of the GCC Runtime Library Exception along with this program;
00024 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00025 <http://www.gnu.org/licenses/>.  */
00026 
00027 #ifndef _GLIBCXX_GCC_GTHR_POSIX_H
00028 #define _GLIBCXX_GCC_GTHR_POSIX_H
00029 
00030 /* POSIX threads specific definitions.
00031    Easy, since the interface is just one-to-one mapping.  */
00032 
00033 #define __GTHREADS 1
00034 #define __GTHREADS_CXX0X 1
00035 
00036 /* Some implementations of <pthread.h> require this to be defined.  */
00037 #if !defined(_REENTRANT) && defined(__osf__)
00038 #define _REENTRANT 1
00039 #endif
00040 
00041 #include <pthread.h>
00042 #include <unistd.h>
00043 
00044 typedef pthread_t __gthread_t;
00045 typedef pthread_key_t __gthread_key_t;
00046 typedef pthread_once_t __gthread_once_t;
00047 typedef pthread_mutex_t __gthread_mutex_t;
00048 typedef pthread_mutex_t __gthread_recursive_mutex_t;
00049 typedef pthread_cond_t __gthread_cond_t;
00050 typedef struct timespec __gthread_time_t;
00051 
00052 /* POSIX like conditional variables are supported.  Please look at comments
00053    in gthr.h for details. */
00054 #define __GTHREAD_HAS_COND  1   
00055 
00056 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
00057 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
00058 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
00059 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
00060 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
00061 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00062 #else
00063 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
00064 #endif
00065 #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
00066 #define __GTHREAD_TIME_INIT {0,0}
00067 
00068 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
00069 # ifndef __gthrw_pragma
00070 #  define __gthrw_pragma(pragma)
00071 # endif
00072 # define __gthrw2(name,name2,type) \
00073   static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
00074   __gthrw_pragma(weak type)
00075 # define __gthrw_(name) __gthrw_ ## name
00076 #else
00077 # define __gthrw2(name,name2,type)
00078 # define __gthrw_(name) name
00079 #endif
00080 
00081 /* Typically, __gthrw_foo is a weak reference to symbol foo.  */
00082 #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
00083 
00084 /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
00085    map a subset of the POSIX pthread API to mangled versions of their
00086    names.  */
00087 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
00088 #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
00089 __gthrw3(pthread_once)
00090 __gthrw3(pthread_getspecific)
00091 __gthrw3(pthread_setspecific)
00092 
00093 __gthrw3(pthread_create)
00094 __gthrw3(pthread_join)
00095 __gthrw3(pthread_detach)
00096 __gthrw3(pthread_equal)
00097 __gthrw3(pthread_self)
00098 __gthrw3(pthread_cancel)
00099 __gthrw3(sched_yield)
00100 
00101 __gthrw3(pthread_mutex_lock)
00102 __gthrw3(pthread_mutex_trylock)
00103 #ifdef _POSIX_TIMEOUTS
00104 #if _POSIX_TIMEOUTS >= 0
00105 __gthrw3(pthread_mutex_timedlock)
00106 #endif
00107 #endif /* _POSIX_TIMEOUTS */
00108 __gthrw3(pthread_mutex_unlock)
00109 __gthrw3(pthread_mutex_init)
00110 __gthrw3(pthread_mutex_destroy)
00111 
00112 __gthrw3(pthread_cond_broadcast)
00113 __gthrw3(pthread_cond_signal)
00114 __gthrw3(pthread_cond_wait)
00115 __gthrw3(pthread_cond_timedwait)
00116 __gthrw3(pthread_cond_destroy)
00117 #else
00118 __gthrw(pthread_once)
00119 __gthrw(pthread_getspecific)
00120 __gthrw(pthread_setspecific)
00121 
00122 __gthrw(pthread_create)
00123 __gthrw(pthread_join)
00124 __gthrw(pthread_equal)
00125 __gthrw(pthread_self)
00126 __gthrw(pthread_detach)
00127 __gthrw(pthread_cancel)
00128 __gthrw(sched_yield)
00129 
00130 __gthrw(pthread_mutex_lock)
00131 __gthrw(pthread_mutex_trylock)
00132 #ifdef _POSIX_TIMEOUTS
00133 #if _POSIX_TIMEOUTS >= 0
00134 __gthrw(pthread_mutex_timedlock)
00135 #endif
00136 #endif /* _POSIX_TIMEOUTS */
00137 __gthrw(pthread_mutex_unlock)
00138 __gthrw(pthread_mutex_init)
00139 __gthrw(pthread_mutex_destroy)
00140 
00141 __gthrw(pthread_cond_broadcast)
00142 __gthrw(pthread_cond_signal)
00143 __gthrw(pthread_cond_wait)
00144 __gthrw(pthread_cond_timedwait)
00145 __gthrw(pthread_cond_destroy)
00146 #endif
00147 
00148 __gthrw(pthread_key_create)
00149 __gthrw(pthread_key_delete)
00150 __gthrw(pthread_mutexattr_init)
00151 __gthrw(pthread_mutexattr_settype)
00152 __gthrw(pthread_mutexattr_destroy)
00153 
00154 
00155 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
00156 /* Objective-C.  */
00157 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
00158 __gthrw3(pthread_cond_init)
00159 __gthrw3(pthread_exit)
00160 #else
00161 __gthrw(pthread_cond_init)
00162 __gthrw(pthread_exit)
00163 #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
00164 #ifdef _POSIX_PRIORITY_SCHEDULING
00165 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00166 __gthrw(sched_get_priority_max)
00167 __gthrw(sched_get_priority_min)
00168 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00169 #endif /* _POSIX_PRIORITY_SCHEDULING */
00170 __gthrw(pthread_attr_destroy)
00171 __gthrw(pthread_attr_init)
00172 __gthrw(pthread_attr_setdetachstate)
00173 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00174 __gthrw(pthread_getschedparam)
00175 __gthrw(pthread_setschedparam)
00176 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00177 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
00178 
00179 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
00180 
00181 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
00182    -pthreads is not specified.  The functions are dummies and most return an
00183    error value.  However pthread_once returns 0 without invoking the routine
00184    it is passed so we cannot pretend that the interface is active if -pthreads
00185    is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
00186    we need to play the usual game with weak symbols.  On Solaris 10 and up, a
00187    working interface is always exposed.  On FreeBSD 6 and later, libc also
00188    exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
00189    to 9 does.  FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
00190    which means the alternate __gthread_active_p below cannot be used there.  */
00191 
00192 #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
00193 
00194 static volatile int __gthread_active = -1;
00195 
00196 static void
00197 __gthread_trigger (void)
00198 {
00199   __gthread_active = 1;
00200 }
00201 
00202 static inline int
00203 __gthread_active_p (void)
00204 {
00205   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
00206   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
00207 
00208   /* Avoid reading __gthread_active twice on the main code path.  */
00209   int __gthread_active_latest_value = __gthread_active;
00210 
00211   /* This test is not protected to avoid taking a lock on the main code
00212      path so every update of __gthread_active in a threaded program must
00213      be atomic with regard to the result of the test.  */
00214   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00215     {
00216       if (__gthrw_(pthread_once))
00217     {
00218       /* If this really is a threaded program, then we must ensure that
00219          __gthread_active has been set to 1 before exiting this block.  */
00220       __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
00221       __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
00222       __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
00223     }
00224 
00225       /* Make sure we'll never enter this block again.  */
00226       if (__gthread_active < 0)
00227     __gthread_active = 0;
00228 
00229       __gthread_active_latest_value = __gthread_active;
00230     }
00231 
00232   return __gthread_active_latest_value != 0;
00233 }
00234 
00235 #else /* neither FreeBSD nor Solaris */
00236 
00237 static inline int
00238 __gthread_active_p (void)
00239 {
00240   static void *const __gthread_active_ptr 
00241     = __extension__ (void *) &__gthrw_(pthread_cancel);
00242   return __gthread_active_ptr != 0;
00243 }
00244 
00245 #endif /* FreeBSD or Solaris */
00246 
00247 #else /* not __GXX_WEAK__ */
00248 
00249 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
00250    calls in shared flavors of the HP-UX C library.  Most of the stubs
00251    have no functionality.  The details are described in the "libc cumulative
00252    patch" for each subversion of HP-UX 11.  There are two special interfaces
00253    provided for checking whether an application is linked to a shared pthread
00254    library or not.  However, these interfaces aren't available in early
00255    libpthread libraries.  We also need a test that works for archive
00256    libraries.  We can't use pthread_once as some libc versions call the
00257    init function.  We also can't use pthread_create or pthread_attr_init
00258    as these create a thread and thereby prevent changing the default stack
00259    size.  The function pthread_default_stacksize_np is available in both
00260    the archive and shared versions of libpthread.   It can be used to
00261    determine the default pthread stack size.  There is a stub in some
00262    shared libc versions which returns a zero size if pthreads are not
00263    active.  We provide an equivalent stub to handle cases where libc
00264    doesn't provide one.  */
00265 
00266 #if defined(__hppa__) && defined(__hpux__)
00267 
00268 static volatile int __gthread_active = -1;
00269 
00270 static inline int
00271 __gthread_active_p (void)
00272 {
00273   /* Avoid reading __gthread_active twice on the main code path.  */
00274   int __gthread_active_latest_value = __gthread_active;
00275   size_t __s;
00276 
00277   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00278     {
00279       pthread_default_stacksize_np (0, &__s);
00280       __gthread_active = __s ? 1 : 0;
00281       __gthread_active_latest_value = __gthread_active;
00282     }
00283 
00284   return __gthread_active_latest_value != 0;
00285 }
00286 
00287 #else /* not hppa-hpux */
00288 
00289 static inline int
00290 __gthread_active_p (void)
00291 {
00292   return 1;
00293 }
00294 
00295 #endif /* hppa-hpux */
00296 
00297 #endif /* __GXX_WEAK__ */
00298 
00299 #ifdef _LIBOBJC
00300 
00301 /* This is the config.h file in libobjc/ */
00302 #include <config.h>
00303 
00304 #ifdef HAVE_SCHED_H
00305 # include <sched.h>
00306 #endif
00307 
00308 /* Key structure for maintaining thread specific storage */
00309 static pthread_key_t _objc_thread_storage;
00310 static pthread_attr_t _objc_thread_attribs;
00311 
00312 /* Thread local storage for a single thread */
00313 static void *thread_local_storage = NULL;
00314 
00315 /* Backend initialization functions */
00316 
00317 /* Initialize the threads subsystem.  */
00318 static inline int
00319 __gthread_objc_init_thread_system (void)
00320 {
00321   if (__gthread_active_p ())
00322     {
00323       /* Initialize the thread storage key.  */
00324       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
00325     {
00326       /* The normal default detach state for threads is
00327        * PTHREAD_CREATE_JOINABLE which causes threads to not die
00328        * when you think they should.  */
00329       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
00330           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
00331                           PTHREAD_CREATE_DETACHED) == 0)
00332         return 0;
00333     }
00334     }
00335 
00336   return -1;
00337 }
00338 
00339 /* Close the threads subsystem.  */
00340 static inline int
00341 __gthread_objc_close_thread_system (void)
00342 {
00343   if (__gthread_active_p ()
00344       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
00345       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
00346     return 0;
00347 
00348   return -1;
00349 }
00350 
00351 /* Backend thread functions */
00352 
00353 /* Create a new thread of execution.  */
00354 static inline objc_thread_t
00355 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00356 {
00357   objc_thread_t thread_id;
00358   pthread_t new_thread_handle;
00359 
00360   if (!__gthread_active_p ())
00361     return NULL;
00362 
00363   if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
00364     thread_id = (objc_thread_t) new_thread_handle;
00365   else
00366     thread_id = NULL;
00367 
00368   return thread_id;
00369 }
00370 
00371 /* Set the current thread's priority.  */
00372 static inline int
00373 __gthread_objc_thread_set_priority (int priority)
00374 {
00375   if (!__gthread_active_p ())
00376     return -1;
00377   else
00378     {
00379 #ifdef _POSIX_PRIORITY_SCHEDULING
00380 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00381       pthread_t thread_id = __gthrw_(pthread_self) ();
00382       int policy;
00383       struct sched_param params;
00384       int priority_min, priority_max;
00385 
00386       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
00387     {
00388       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
00389         return -1;
00390 
00391       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
00392         return -1;
00393 
00394       if (priority > priority_max)
00395         priority = priority_max;
00396       else if (priority < priority_min)
00397         priority = priority_min;
00398       params.sched_priority = priority;
00399 
00400       /*
00401        * The solaris 7 and several other man pages incorrectly state that
00402        * this should be a pointer to policy but pthread.h is universally
00403        * at odds with this.
00404        */
00405       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
00406         return 0;
00407     }
00408 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00409 #endif /* _POSIX_PRIORITY_SCHEDULING */
00410       return -1;
00411     }
00412 }
00413 
00414 /* Return the current thread's priority.  */
00415 static inline int
00416 __gthread_objc_thread_get_priority (void)
00417 {
00418 #ifdef _POSIX_PRIORITY_SCHEDULING
00419 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00420   if (__gthread_active_p ())
00421     {
00422       int policy;
00423       struct sched_param params;
00424 
00425       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
00426     return params.sched_priority;
00427       else
00428     return -1;
00429     }
00430   else
00431 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00432 #endif /* _POSIX_PRIORITY_SCHEDULING */
00433     return OBJC_THREAD_INTERACTIVE_PRIORITY;
00434 }
00435 
00436 /* Yield our process time to another thread.  */
00437 static inline void
00438 __gthread_objc_thread_yield (void)
00439 {
00440   if (__gthread_active_p ())
00441     __gthrw_(sched_yield) ();
00442 }
00443 
00444 /* Terminate the current thread.  */
00445 static inline int
00446 __gthread_objc_thread_exit (void)
00447 {
00448   if (__gthread_active_p ())
00449     /* exit the thread */
00450     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
00451 
00452   /* Failed if we reached here */
00453   return -1;
00454 }
00455 
00456 /* Returns an integer value which uniquely describes a thread.  */
00457 static inline objc_thread_t
00458 __gthread_objc_thread_id (void)
00459 {
00460   if (__gthread_active_p ())
00461     return (objc_thread_t) __gthrw_(pthread_self) ();
00462   else
00463     return (objc_thread_t) 1;
00464 }
00465 
00466 /* Sets the thread's local storage pointer.  */
00467 static inline int
00468 __gthread_objc_thread_set_data (void *value)
00469 {
00470   if (__gthread_active_p ())
00471     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
00472   else
00473     {
00474       thread_local_storage = value;
00475       return 0;
00476     }
00477 }
00478 
00479 /* Returns the thread's local storage pointer.  */
00480 static inline void *
00481 __gthread_objc_thread_get_data (void)
00482 {
00483   if (__gthread_active_p ())
00484     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
00485   else
00486     return thread_local_storage;
00487 }
00488 
00489 /* Backend mutex functions */
00490 
00491 /* Allocate a mutex.  */
00492 static inline int
00493 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00494 {
00495   if (__gthread_active_p ())
00496     {
00497       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
00498 
00499       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
00500     {
00501       objc_free (mutex->backend);
00502       mutex->backend = NULL;
00503       return -1;
00504     }
00505     }
00506 
00507   return 0;
00508 }
00509 
00510 /* Deallocate a mutex.  */
00511 static inline int
00512 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00513 {
00514   if (__gthread_active_p ())
00515     {
00516       int count;
00517 
00518       /*
00519        * Posix Threads specifically require that the thread be unlocked
00520        * for __gthrw_(pthread_mutex_destroy) to work.
00521        */
00522 
00523       do
00524     {
00525       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
00526       if (count < 0)
00527         return -1;
00528     }
00529       while (count);
00530 
00531       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
00532     return -1;
00533 
00534       objc_free (mutex->backend);
00535       mutex->backend = NULL;
00536     }
00537   return 0;
00538 }
00539 
00540 /* Grab a lock on a mutex.  */
00541 static inline int
00542 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00543 {
00544   if (__gthread_active_p ()
00545       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
00546     {
00547       return -1;
00548     }
00549 
00550   return 0;
00551 }
00552 
00553 /* Try to grab a lock on a mutex.  */
00554 static inline int
00555 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00556 {
00557   if (__gthread_active_p ()
00558       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
00559     {
00560       return -1;
00561     }
00562 
00563   return 0;
00564 }
00565 
00566 /* Unlock the mutex */
00567 static inline int
00568 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00569 {
00570   if (__gthread_active_p ()
00571       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
00572     {
00573       return -1;
00574     }
00575 
00576   return 0;
00577 }
00578 
00579 /* Backend condition mutex functions */
00580 
00581 /* Allocate a condition.  */
00582 static inline int
00583 __gthread_objc_condition_allocate (objc_condition_t condition)
00584 {
00585   if (__gthread_active_p ())
00586     {
00587       condition->backend = objc_malloc (sizeof (pthread_cond_t));
00588 
00589       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
00590     {
00591       objc_free (condition->backend);
00592       condition->backend = NULL;
00593       return -1;
00594     }
00595     }
00596 
00597   return 0;
00598 }
00599 
00600 /* Deallocate a condition.  */
00601 static inline int
00602 __gthread_objc_condition_deallocate (objc_condition_t condition)
00603 {
00604   if (__gthread_active_p ())
00605     {
00606       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
00607     return -1;
00608 
00609       objc_free (condition->backend);
00610       condition->backend = NULL;
00611     }
00612   return 0;
00613 }
00614 
00615 /* Wait on the condition */
00616 static inline int
00617 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00618 {
00619   if (__gthread_active_p ())
00620     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
00621                   (pthread_mutex_t *) mutex->backend);
00622   else
00623     return 0;
00624 }
00625 
00626 /* Wake up all threads waiting on this condition.  */
00627 static inline int
00628 __gthread_objc_condition_broadcast (objc_condition_t condition)
00629 {
00630   if (__gthread_active_p ())
00631     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
00632   else
00633     return 0;
00634 }
00635 
00636 /* Wake up one thread waiting on this condition.  */
00637 static inline int
00638 __gthread_objc_condition_signal (objc_condition_t condition)
00639 {
00640   if (__gthread_active_p ())
00641     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
00642   else
00643     return 0;
00644 }
00645 
00646 #else /* _LIBOBJC */
00647 
00648 static inline int
00649 __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
00650           void *__args)
00651 {
00652   return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
00653 }
00654 
00655 static inline int
00656 __gthread_join (__gthread_t __threadid, void **__value_ptr)
00657 {
00658   return __gthrw_(pthread_join) (__threadid, __value_ptr);
00659 }
00660 
00661 static inline int
00662 __gthread_detach (__gthread_t __threadid)
00663 {
00664   return __gthrw_(pthread_detach) (__threadid);
00665 }
00666 
00667 static inline int
00668 __gthread_equal (__gthread_t __t1, __gthread_t __t2)
00669 {
00670   return __gthrw_(pthread_equal) (__t1, __t2);
00671 }
00672 
00673 static inline __gthread_t
00674 __gthread_self (void)
00675 {
00676   return __gthrw_(pthread_self) ();
00677 }
00678 
00679 static inline int
00680 __gthread_yield (void)
00681 {
00682   return __gthrw_(sched_yield) ();
00683 }
00684 
00685 static inline int
00686 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
00687 {
00688   if (__gthread_active_p ())
00689     return __gthrw_(pthread_once) (__once, __func);
00690   else
00691     return -1;
00692 }
00693 
00694 static inline int
00695 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
00696 {
00697   return __gthrw_(pthread_key_create) (__key, __dtor);
00698 }
00699 
00700 static inline int
00701 __gthread_key_delete (__gthread_key_t __key)
00702 {
00703   return __gthrw_(pthread_key_delete) (__key);
00704 }
00705 
00706 static inline void *
00707 __gthread_getspecific (__gthread_key_t __key)
00708 {
00709   return __gthrw_(pthread_getspecific) (__key);
00710 }
00711 
00712 static inline int
00713 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
00714 {
00715   return __gthrw_(pthread_setspecific) (__key, __ptr);
00716 }
00717 
00718 static inline int
00719 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
00720 {
00721   if (__gthread_active_p ())
00722     return __gthrw_(pthread_mutex_destroy) (__mutex);
00723   else
00724     return 0;
00725 }
00726 
00727 static inline int
00728 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
00729 {
00730   if (__gthread_active_p ())
00731     return __gthrw_(pthread_mutex_lock) (__mutex);
00732   else
00733     return 0;
00734 }
00735 
00736 static inline int
00737 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
00738 {
00739   if (__gthread_active_p ())
00740     return __gthrw_(pthread_mutex_trylock) (__mutex);
00741   else
00742     return 0;
00743 }
00744 
00745 #ifdef _POSIX_TIMEOUTS
00746 #if _POSIX_TIMEOUTS >= 0
00747 static inline int
00748 __gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
00749                const __gthread_time_t *__abs_timeout)
00750 {
00751   if (__gthread_active_p ())
00752     return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
00753   else
00754     return 0;
00755 }
00756 #endif
00757 #endif
00758 
00759 static inline int
00760 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
00761 {
00762   if (__gthread_active_p ())
00763     return __gthrw_(pthread_mutex_unlock) (__mutex);
00764   else
00765     return 0;
00766 }
00767 
00768 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00769 static inline int
00770 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
00771 {
00772   if (__gthread_active_p ())
00773     {
00774       pthread_mutexattr_t __attr;
00775       int __r;
00776 
00777       __r = __gthrw_(pthread_mutexattr_init) (&__attr);
00778       if (!__r)
00779     __r = __gthrw_(pthread_mutexattr_settype) (&__attr,
00780                            PTHREAD_MUTEX_RECURSIVE);
00781       if (!__r)
00782     __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
00783       if (!__r)
00784     __r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
00785       return __r;
00786     }
00787   return 0;
00788 }
00789 #endif
00790 
00791 static inline int
00792 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
00793 {
00794   return __gthread_mutex_lock (__mutex);
00795 }
00796 
00797 static inline int
00798 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
00799 {
00800   return __gthread_mutex_trylock (__mutex);
00801 }
00802 
00803 #ifdef _POSIX_TIMEOUTS
00804 #if _POSIX_TIMEOUTS >= 0
00805 static inline int
00806 __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
00807                      const __gthread_time_t *__abs_timeout)
00808 {
00809   return __gthread_mutex_timedlock (__mutex, __abs_timeout);
00810 }
00811 #endif
00812 #endif
00813 
00814 static inline int
00815 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
00816 {
00817   return __gthread_mutex_unlock (__mutex);
00818 }
00819 
00820 static inline int
00821 __gthread_cond_broadcast (__gthread_cond_t *__cond)
00822 {
00823   return __gthrw_(pthread_cond_broadcast) (__cond);
00824 }
00825 
00826 static inline int
00827 __gthread_cond_signal (__gthread_cond_t *__cond)
00828 {
00829   return __gthrw_(pthread_cond_signal) (__cond);
00830 }
00831 
00832 static inline int
00833 __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
00834 {
00835   return __gthrw_(pthread_cond_wait) (__cond, __mutex);
00836 }
00837 
00838 static inline int
00839 __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
00840               const __gthread_time_t *__abs_timeout)
00841 {
00842   return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
00843 }
00844 
00845 static inline int
00846 __gthread_cond_wait_recursive (__gthread_cond_t *__cond,
00847                    __gthread_recursive_mutex_t *__mutex)
00848 {
00849   return __gthread_cond_wait (__cond, __mutex);
00850 }
00851 
00852 static inline int
00853 __gthread_cond_timedwait_recursive (__gthread_cond_t *__cond,
00854                     __gthread_recursive_mutex_t *__mutex,
00855                     const __gthread_time_t *__abs_timeout)
00856 {
00857   return __gthread_cond_timedwait (__cond, __mutex, __abs_timeout);
00858 }
00859 
00860 static inline int
00861 __gthread_cond_destroy (__gthread_cond_t* __cond)
00862 {
00863   return __gthrw_(pthread_cond_destroy) (__cond);
00864 }
00865 
00866 #endif /* _LIBOBJC */
00867 
00868 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

Generated on 23 Jul 2015 for libstdc++ by  doxygen 1.6.1