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 pthread
00254    library or not.  However, these interfaces aren't available in early
00255    libc versions.  We also can't use pthread_once as some libc versions
00256    call the init function.  So, we use pthread_create to check whether it
00257    is possible to create a thread or not.  The stub implementation returns
00258    the error number ENOSYS.  */
00259 
00260 #if defined(__hppa__) && defined(__hpux__)
00261 
00262 #include <errno.h>
00263 
00264 static volatile int __gthread_active = -1;
00265 
00266 static void *
00267 __gthread_start (void *__arg __attribute__((unused)))
00268 {
00269   return NULL;
00270 }
00271 
00272 static void __gthread_active_init (void) __attribute__((noinline));
00273 static void
00274 __gthread_active_init (void)
00275 {
00276   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
00277   pthread_t __t;
00278   pthread_attr_t __a;
00279   int __result;
00280 
00281   __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
00282   if (__gthread_active < 0)
00283     {
00284       __gthrw_(pthread_attr_init) (&__a);
00285       __gthrw_(pthread_attr_setdetachstate) (&__a, PTHREAD_CREATE_DETACHED);
00286       __result = __gthrw_(pthread_create) (&__t, &__a, __gthread_start, NULL);
00287       if (__result != ENOSYS)
00288     __gthread_active = 1;
00289       else
00290     __gthread_active = 0;
00291       __gthrw_(pthread_attr_destroy) (&__a);
00292     }
00293   __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
00294 }
00295 
00296 static inline int
00297 __gthread_active_p (void)
00298 {
00299   /* Avoid reading __gthread_active twice on the main code path.  */
00300   int __gthread_active_latest_value = __gthread_active;
00301 
00302   /* This test is not protected to avoid taking a lock on the main code
00303      path so every update of __gthread_active in a threaded program must
00304      be atomic with regard to the result of the test.  */
00305   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00306     {
00307       __gthread_active_init ();
00308       __gthread_active_latest_value = __gthread_active;
00309     }
00310 
00311   return __gthread_active_latest_value != 0;
00312 }
00313 
00314 #else /* not hppa-hpux */
00315 
00316 static inline int
00317 __gthread_active_p (void)
00318 {
00319   return 1;
00320 }
00321 
00322 #endif /* hppa-hpux */
00323 
00324 #endif /* __GXX_WEAK__ */
00325 
00326 #ifdef _LIBOBJC
00327 
00328 /* This is the config.h file in libobjc/ */
00329 #include <config.h>
00330 
00331 #ifdef HAVE_SCHED_H
00332 # include <sched.h>
00333 #endif
00334 
00335 /* Key structure for maintaining thread specific storage */
00336 static pthread_key_t _objc_thread_storage;
00337 static pthread_attr_t _objc_thread_attribs;
00338 
00339 /* Thread local storage for a single thread */
00340 static void *thread_local_storage = NULL;
00341 
00342 /* Backend initialization functions */
00343 
00344 /* Initialize the threads subsystem.  */
00345 static inline int
00346 __gthread_objc_init_thread_system (void)
00347 {
00348   if (__gthread_active_p ())
00349     {
00350       /* Initialize the thread storage key.  */
00351       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
00352     {
00353       /* The normal default detach state for threads is
00354        * PTHREAD_CREATE_JOINABLE which causes threads to not die
00355        * when you think they should.  */
00356       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
00357           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
00358                           PTHREAD_CREATE_DETACHED) == 0)
00359         return 0;
00360     }
00361     }
00362 
00363   return -1;
00364 }
00365 
00366 /* Close the threads subsystem.  */
00367 static inline int
00368 __gthread_objc_close_thread_system (void)
00369 {
00370   if (__gthread_active_p ()
00371       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
00372       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
00373     return 0;
00374 
00375   return -1;
00376 }
00377 
00378 /* Backend thread functions */
00379 
00380 /* Create a new thread of execution.  */
00381 static inline objc_thread_t
00382 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00383 {
00384   objc_thread_t thread_id;
00385   pthread_t new_thread_handle;
00386 
00387   if (!__gthread_active_p ())
00388     return NULL;
00389 
00390   if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
00391     thread_id = (objc_thread_t) new_thread_handle;
00392   else
00393     thread_id = NULL;
00394 
00395   return thread_id;
00396 }
00397 
00398 /* Set the current thread's priority.  */
00399 static inline int
00400 __gthread_objc_thread_set_priority (int priority)
00401 {
00402   if (!__gthread_active_p ())
00403     return -1;
00404   else
00405     {
00406 #ifdef _POSIX_PRIORITY_SCHEDULING
00407 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00408       pthread_t thread_id = __gthrw_(pthread_self) ();
00409       int policy;
00410       struct sched_param params;
00411       int priority_min, priority_max;
00412 
00413       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
00414     {
00415       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
00416         return -1;
00417 
00418       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
00419         return -1;
00420 
00421       if (priority > priority_max)
00422         priority = priority_max;
00423       else if (priority < priority_min)
00424         priority = priority_min;
00425       params.sched_priority = priority;
00426 
00427       /*
00428        * The solaris 7 and several other man pages incorrectly state that
00429        * this should be a pointer to policy but pthread.h is universally
00430        * at odds with this.
00431        */
00432       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
00433         return 0;
00434     }
00435 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00436 #endif /* _POSIX_PRIORITY_SCHEDULING */
00437       return -1;
00438     }
00439 }
00440 
00441 /* Return the current thread's priority.  */
00442 static inline int
00443 __gthread_objc_thread_get_priority (void)
00444 {
00445 #ifdef _POSIX_PRIORITY_SCHEDULING
00446 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00447   if (__gthread_active_p ())
00448     {
00449       int policy;
00450       struct sched_param params;
00451 
00452       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
00453     return params.sched_priority;
00454       else
00455     return -1;
00456     }
00457   else
00458 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00459 #endif /* _POSIX_PRIORITY_SCHEDULING */
00460     return OBJC_THREAD_INTERACTIVE_PRIORITY;
00461 }
00462 
00463 /* Yield our process time to another thread.  */
00464 static inline void
00465 __gthread_objc_thread_yield (void)
00466 {
00467   if (__gthread_active_p ())
00468     __gthrw_(sched_yield) ();
00469 }
00470 
00471 /* Terminate the current thread.  */
00472 static inline int
00473 __gthread_objc_thread_exit (void)
00474 {
00475   if (__gthread_active_p ())
00476     /* exit the thread */
00477     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
00478 
00479   /* Failed if we reached here */
00480   return -1;
00481 }
00482 
00483 /* Returns an integer value which uniquely describes a thread.  */
00484 static inline objc_thread_t
00485 __gthread_objc_thread_id (void)
00486 {
00487   if (__gthread_active_p ())
00488     return (objc_thread_t) __gthrw_(pthread_self) ();
00489   else
00490     return (objc_thread_t) 1;
00491 }
00492 
00493 /* Sets the thread's local storage pointer.  */
00494 static inline int
00495 __gthread_objc_thread_set_data (void *value)
00496 {
00497   if (__gthread_active_p ())
00498     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
00499   else
00500     {
00501       thread_local_storage = value;
00502       return 0;
00503     }
00504 }
00505 
00506 /* Returns the thread's local storage pointer.  */
00507 static inline void *
00508 __gthread_objc_thread_get_data (void)
00509 {
00510   if (__gthread_active_p ())
00511     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
00512   else
00513     return thread_local_storage;
00514 }
00515 
00516 /* Backend mutex functions */
00517 
00518 /* Allocate a mutex.  */
00519 static inline int
00520 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00521 {
00522   if (__gthread_active_p ())
00523     {
00524       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
00525 
00526       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
00527     {
00528       objc_free (mutex->backend);
00529       mutex->backend = NULL;
00530       return -1;
00531     }
00532     }
00533 
00534   return 0;
00535 }
00536 
00537 /* Deallocate a mutex.  */
00538 static inline int
00539 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00540 {
00541   if (__gthread_active_p ())
00542     {
00543       int count;
00544 
00545       /*
00546        * Posix Threads specifically require that the thread be unlocked
00547        * for __gthrw_(pthread_mutex_destroy) to work.
00548        */
00549 
00550       do
00551     {
00552       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
00553       if (count < 0)
00554         return -1;
00555     }
00556       while (count);
00557 
00558       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
00559     return -1;
00560 
00561       objc_free (mutex->backend);
00562       mutex->backend = NULL;
00563     }
00564   return 0;
00565 }
00566 
00567 /* Grab a lock on a mutex.  */
00568 static inline int
00569 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00570 {
00571   if (__gthread_active_p ()
00572       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
00573     {
00574       return -1;
00575     }
00576 
00577   return 0;
00578 }
00579 
00580 /* Try to grab a lock on a mutex.  */
00581 static inline int
00582 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00583 {
00584   if (__gthread_active_p ()
00585       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
00586     {
00587       return -1;
00588     }
00589 
00590   return 0;
00591 }
00592 
00593 /* Unlock the mutex */
00594 static inline int
00595 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00596 {
00597   if (__gthread_active_p ()
00598       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
00599     {
00600       return -1;
00601     }
00602 
00603   return 0;
00604 }
00605 
00606 /* Backend condition mutex functions */
00607 
00608 /* Allocate a condition.  */
00609 static inline int
00610 __gthread_objc_condition_allocate (objc_condition_t condition)
00611 {
00612   if (__gthread_active_p ())
00613     {
00614       condition->backend = objc_malloc (sizeof (pthread_cond_t));
00615 
00616       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
00617     {
00618       objc_free (condition->backend);
00619       condition->backend = NULL;
00620       return -1;
00621     }
00622     }
00623 
00624   return 0;
00625 }
00626 
00627 /* Deallocate a condition.  */
00628 static inline int
00629 __gthread_objc_condition_deallocate (objc_condition_t condition)
00630 {
00631   if (__gthread_active_p ())
00632     {
00633       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
00634     return -1;
00635 
00636       objc_free (condition->backend);
00637       condition->backend = NULL;
00638     }
00639   return 0;
00640 }
00641 
00642 /* Wait on the condition */
00643 static inline int
00644 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00645 {
00646   if (__gthread_active_p ())
00647     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
00648                   (pthread_mutex_t *) mutex->backend);
00649   else
00650     return 0;
00651 }
00652 
00653 /* Wake up all threads waiting on this condition.  */
00654 static inline int
00655 __gthread_objc_condition_broadcast (objc_condition_t condition)
00656 {
00657   if (__gthread_active_p ())
00658     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
00659   else
00660     return 0;
00661 }
00662 
00663 /* Wake up one thread waiting on this condition.  */
00664 static inline int
00665 __gthread_objc_condition_signal (objc_condition_t condition)
00666 {
00667   if (__gthread_active_p ())
00668     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
00669   else
00670     return 0;
00671 }
00672 
00673 #else /* _LIBOBJC */
00674 
00675 static inline int
00676 __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
00677           void *__args)
00678 {
00679   return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
00680 }
00681 
00682 static inline int
00683 __gthread_join (__gthread_t __threadid, void **__value_ptr)
00684 {
00685   return __gthrw_(pthread_join) (__threadid, __value_ptr);
00686 }
00687 
00688 static inline int
00689 __gthread_detach (__gthread_t __threadid)
00690 {
00691   return __gthrw_(pthread_detach) (__threadid);
00692 }
00693 
00694 static inline int
00695 __gthread_equal (__gthread_t __t1, __gthread_t __t2)
00696 {
00697   return __gthrw_(pthread_equal) (__t1, __t2);
00698 }
00699 
00700 static inline __gthread_t
00701 __gthread_self (void)
00702 {
00703   return __gthrw_(pthread_self) ();
00704 }
00705 
00706 static inline int
00707 __gthread_yield (void)
00708 {
00709   return __gthrw_(sched_yield) ();
00710 }
00711 
00712 static inline int
00713 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
00714 {
00715   if (__gthread_active_p ())
00716     return __gthrw_(pthread_once) (__once, __func);
00717   else
00718     return -1;
00719 }
00720 
00721 static inline int
00722 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
00723 {
00724   return __gthrw_(pthread_key_create) (__key, __dtor);
00725 }
00726 
00727 static inline int
00728 __gthread_key_delete (__gthread_key_t __key)
00729 {
00730   return __gthrw_(pthread_key_delete) (__key);
00731 }
00732 
00733 static inline void *
00734 __gthread_getspecific (__gthread_key_t __key)
00735 {
00736   return __gthrw_(pthread_getspecific) (__key);
00737 }
00738 
00739 static inline int
00740 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
00741 {
00742   return __gthrw_(pthread_setspecific) (__key, __ptr);
00743 }
00744 
00745 static inline int
00746 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
00747 {
00748   if (__gthread_active_p ())
00749     return __gthrw_(pthread_mutex_destroy) (__mutex);
00750   else
00751     return 0;
00752 }
00753 
00754 static inline int
00755 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
00756 {
00757   if (__gthread_active_p ())
00758     return __gthrw_(pthread_mutex_lock) (__mutex);
00759   else
00760     return 0;
00761 }
00762 
00763 static inline int
00764 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
00765 {
00766   if (__gthread_active_p ())
00767     return __gthrw_(pthread_mutex_trylock) (__mutex);
00768   else
00769     return 0;
00770 }
00771 
00772 #ifdef _POSIX_TIMEOUTS
00773 #if _POSIX_TIMEOUTS >= 0
00774 static inline int
00775 __gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
00776                const __gthread_time_t *__abs_timeout)
00777 {
00778   if (__gthread_active_p ())
00779     return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
00780   else
00781     return 0;
00782 }
00783 #endif
00784 #endif
00785 
00786 static inline int
00787 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
00788 {
00789   if (__gthread_active_p ())
00790     return __gthrw_(pthread_mutex_unlock) (__mutex);
00791   else
00792     return 0;
00793 }
00794 
00795 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00796 static inline int
00797 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
00798 {
00799   if (__gthread_active_p ())
00800     {
00801       pthread_mutexattr_t __attr;
00802       int __r;
00803 
00804       __r = __gthrw_(pthread_mutexattr_init) (&__attr);
00805       if (!__r)
00806     __r = __gthrw_(pthread_mutexattr_settype) (&__attr,
00807                            PTHREAD_MUTEX_RECURSIVE);
00808       if (!__r)
00809     __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
00810       if (!__r)
00811     __r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
00812       return __r;
00813     }
00814   return 0;
00815 }
00816 #endif
00817 
00818 static inline int
00819 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
00820 {
00821   return __gthread_mutex_lock (__mutex);
00822 }
00823 
00824 static inline int
00825 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
00826 {
00827   return __gthread_mutex_trylock (__mutex);
00828 }
00829 
00830 #ifdef _POSIX_TIMEOUTS
00831 #if _POSIX_TIMEOUTS >= 0
00832 static inline int
00833 __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
00834                      const __gthread_time_t *__abs_timeout)
00835 {
00836   return __gthread_mutex_timedlock (__mutex, __abs_timeout);
00837 }
00838 #endif
00839 #endif
00840 
00841 static inline int
00842 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
00843 {
00844   return __gthread_mutex_unlock (__mutex);
00845 }
00846 
00847 static inline int
00848 __gthread_cond_broadcast (__gthread_cond_t *__cond)
00849 {
00850   return __gthrw_(pthread_cond_broadcast) (__cond);
00851 }
00852 
00853 static inline int
00854 __gthread_cond_signal (__gthread_cond_t *__cond)
00855 {
00856   return __gthrw_(pthread_cond_signal) (__cond);
00857 }
00858 
00859 static inline int
00860 __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
00861 {
00862   return __gthrw_(pthread_cond_wait) (__cond, __mutex);
00863 }
00864 
00865 static inline int
00866 __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
00867               const __gthread_time_t *__abs_timeout)
00868 {
00869   return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
00870 }
00871 
00872 static inline int
00873 __gthread_cond_wait_recursive (__gthread_cond_t *__cond,
00874                    __gthread_recursive_mutex_t *__mutex)
00875 {
00876   return __gthread_cond_wait (__cond, __mutex);
00877 }
00878 
00879 static inline int
00880 __gthread_cond_timedwait_recursive (__gthread_cond_t *__cond,
00881                     __gthread_recursive_mutex_t *__mutex,
00882                     const __gthread_time_t *__abs_timeout)
00883 {
00884   return __gthread_cond_timedwait (__cond, __mutex, __abs_timeout);
00885 }
00886 
00887 static inline int
00888 __gthread_cond_destroy (__gthread_cond_t* __cond)
00889 {
00890   return __gthrw_(pthread_cond_destroy) (__cond);
00891 }
00892 
00893 #endif /* _LIBOBJC */
00894 
00895 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

Generated on Tue Apr 21 13:13:27 2009 for libstdc++ by  doxygen 1.5.8