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    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 2, 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 You should have received a copy of the GNU General Public License
00019 along with GCC; see the file COPYING.  If not, write to the Free
00020 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
00021 02110-1301, USA.  */
00022 
00023 /* As a special exception, if you link this library with other files,
00024    some of which are compiled with GCC, to produce an executable,
00025    this library does not by itself cause the resulting executable
00026    to be covered by the GNU General Public License.
00027    This exception does not however invalidate any other reasons why
00028    the executable file might be covered by the GNU General Public License.  */
00029 
00030 #ifndef _GLIBCXX_GCC_GTHR_POSIX_H
00031 #define _GLIBCXX_GCC_GTHR_POSIX_H
00032 
00033 /* POSIX threads specific definitions.
00034    Easy, since the interface is just one-to-one mapping.  */
00035 
00036 #define __GTHREADS 1
00037 
00038 /* Some implementations of <pthread.h> require this to be defined.  */
00039 #if !defined(_REENTRANT) && defined(__osf__)
00040 #define _REENTRANT 1
00041 #endif
00042 
00043 #include <pthread.h>
00044 #include <unistd.h>
00045 
00046 typedef pthread_key_t __gthread_key_t;
00047 typedef pthread_once_t __gthread_once_t;
00048 typedef pthread_mutex_t __gthread_mutex_t;
00049 typedef pthread_mutex_t __gthread_recursive_mutex_t;
00050 typedef pthread_cond_t __gthread_cond_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 
00067 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
00068 # ifndef __gthrw_pragma
00069 #  define __gthrw_pragma(pragma)
00070 # endif
00071 # define __gthrw2(name,name2,type) \
00072   static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
00073   __gthrw_pragma(weak type)
00074 # define __gthrw_(name) __gthrw_ ## name
00075 #else
00076 # define __gthrw2(name,name2,type)
00077 # define __gthrw_(name) name
00078 #endif
00079 
00080 /* Typically, __gthrw_foo is a weak reference to symbol foo.  */
00081 #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
00082 
00083 /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
00084    map a subset of the POSIX pthread API to mangled versions of their
00085    names.  */
00086 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
00087 #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
00088 __gthrw3(pthread_once)
00089 __gthrw3(pthread_getspecific)
00090 __gthrw3(pthread_setspecific)
00091 __gthrw3(pthread_create)
00092 __gthrw3(pthread_cancel)
00093 __gthrw3(pthread_mutex_lock)
00094 __gthrw3(pthread_mutex_trylock)
00095 __gthrw3(pthread_mutex_unlock)
00096 __gthrw3(pthread_mutex_init)
00097 __gthrw3(pthread_cond_broadcast)
00098 __gthrw3(pthread_cond_wait)
00099 #else
00100 __gthrw(pthread_once)
00101 __gthrw(pthread_getspecific)
00102 __gthrw(pthread_setspecific)
00103 __gthrw(pthread_create)
00104 __gthrw(pthread_cancel)
00105 __gthrw(pthread_mutex_lock)
00106 __gthrw(pthread_mutex_trylock)
00107 __gthrw(pthread_mutex_unlock)
00108 __gthrw(pthread_mutex_init)
00109 __gthrw(pthread_cond_broadcast)
00110 __gthrw(pthread_cond_wait)
00111 #endif
00112 
00113 __gthrw(pthread_key_create)
00114 __gthrw(pthread_key_delete)
00115 __gthrw(pthread_mutexattr_init)
00116 __gthrw(pthread_mutexattr_settype)
00117 __gthrw(pthread_mutexattr_destroy)
00118 
00119 
00120 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
00121 /* Objective-C.  */
00122 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
00123 __gthrw3(pthread_cond_destroy)
00124 __gthrw3(pthread_cond_init)
00125 __gthrw3(pthread_cond_signal)
00126 __gthrw3(pthread_exit)
00127 __gthrw3(pthread_mutex_destroy)
00128 __gthrw3(pthread_self)
00129 #else
00130 __gthrw(pthread_cond_destroy)
00131 __gthrw(pthread_cond_init)
00132 __gthrw(pthread_cond_signal)
00133 __gthrw(pthread_exit)
00134 __gthrw(pthread_mutex_destroy)
00135 __gthrw(pthread_self)
00136 #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
00137 #ifdef _POSIX_PRIORITY_SCHEDULING
00138 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00139 __gthrw(sched_get_priority_max)
00140 __gthrw(sched_get_priority_min)
00141 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00142 #endif /* _POSIX_PRIORITY_SCHEDULING */
00143 __gthrw(sched_yield)
00144 __gthrw(pthread_attr_destroy)
00145 __gthrw(pthread_attr_init)
00146 __gthrw(pthread_attr_setdetachstate)
00147 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00148 __gthrw(pthread_getschedparam)
00149 __gthrw(pthread_setschedparam)
00150 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00151 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
00152 
00153 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
00154 
00155 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
00156    -pthreads is not specified.  The functions are dummies and most return an
00157    error value.  However pthread_once returns 0 without invoking the routine
00158    it is passed so we cannot pretend that the interface is active if -pthreads
00159    is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
00160    we need to play the usual game with weak symbols.  On Solaris 10 and up, a
00161    working interface is always exposed.  */
00162 
00163 #if defined(__sun) && defined(__svr4__)
00164 
00165 static volatile int __gthread_active = -1;
00166 
00167 static void
00168 __gthread_trigger (void)
00169 {
00170   __gthread_active = 1;
00171 }
00172 
00173 static inline int
00174 __gthread_active_p (void)
00175 {
00176   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
00177   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
00178 
00179   /* Avoid reading __gthread_active twice on the main code path.  */
00180   int __gthread_active_latest_value = __gthread_active;
00181 
00182   /* This test is not protected to avoid taking a lock on the main code
00183      path so every update of __gthread_active in a threaded program must
00184      be atomic with regard to the result of the test.  */
00185   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00186     {
00187       if (__gthrw_(pthread_once))
00188     {
00189       /* If this really is a threaded program, then we must ensure that
00190          __gthread_active has been set to 1 before exiting this block.  */
00191       __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
00192       __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
00193       __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
00194     }
00195 
00196       /* Make sure we'll never enter this block again.  */
00197       if (__gthread_active < 0)
00198     __gthread_active = 0;
00199 
00200       __gthread_active_latest_value = __gthread_active;
00201     }
00202 
00203   return __gthread_active_latest_value != 0;
00204 }
00205 
00206 #else /* not Solaris */
00207 
00208 static inline int
00209 __gthread_active_p (void)
00210 {
00211   static void *const __gthread_active_ptr 
00212     = __extension__ (void *) &__gthrw_(pthread_cancel);
00213   return __gthread_active_ptr != 0;
00214 }
00215 
00216 #endif /* Solaris */
00217 
00218 #else /* not __GXX_WEAK__ */
00219 
00220 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
00221    calls in shared flavors of the HP-UX C library.  Most of the stubs
00222    have no functionality.  The details are described in the "libc cumulative
00223    patch" for each subversion of HP-UX 11.  There are two special interfaces
00224    provided for checking whether an application is linked to a pthread
00225    library or not.  However, these interfaces aren't available in early
00226    libc versions.  We also can't use pthread_once as some libc versions
00227    call the init function.  So, we use pthread_create to check whether it
00228    is possible to create a thread or not.  The stub implementation returns
00229    the error number ENOSYS.  */
00230 
00231 #if defined(__hppa__) && defined(__hpux__)
00232 
00233 #include <errno.h>
00234 
00235 static volatile int __gthread_active = -1;
00236 
00237 static void *
00238 __gthread_start (void *arg __attribute__((unused)))
00239 {
00240   return NULL;
00241 }
00242 
00243 static void __gthread_active_init (void) __attribute__((noinline));
00244 static void
00245 __gthread_active_init (void)
00246 {
00247   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
00248   pthread_t t;
00249   pthread_attr_t a;
00250   int result;
00251 
00252   __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
00253   if (__gthread_active < 0)
00254     {
00255       __gthrw_(pthread_attr_init) (&a);
00256       __gthrw_(pthread_attr_setdetachstate) (&a, PTHREAD_CREATE_DETACHED);
00257       result = __gthrw_(pthread_create) (&t, &a, __gthread_start, NULL);
00258       if (result != ENOSYS)
00259     __gthread_active = 1;
00260       else
00261     __gthread_active = 0;
00262       __gthrw_(pthread_attr_destroy) (&a);
00263     }
00264   __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
00265 }
00266 
00267 static inline int
00268 __gthread_active_p (void)
00269 {
00270   /* Avoid reading __gthread_active twice on the main code path.  */
00271   int __gthread_active_latest_value = __gthread_active;
00272 
00273   /* This test is not protected to avoid taking a lock on the main code
00274      path so every update of __gthread_active in a threaded program must
00275      be atomic with regard to the result of the test.  */
00276   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00277     {
00278       __gthread_active_init ();
00279       __gthread_active_latest_value = __gthread_active;
00280     }
00281 
00282   return __gthread_active_latest_value != 0;
00283 }
00284 
00285 #else /* not hppa-hpux */
00286 
00287 static inline int
00288 __gthread_active_p (void)
00289 {
00290   return 1;
00291 }
00292 
00293 #endif /* hppa-hpux */
00294 
00295 #endif /* __GXX_WEAK__ */
00296 
00297 #ifdef _LIBOBJC
00298 
00299 /* This is the config.h file in libobjc/ */
00300 #include <config.h>
00301 
00302 #ifdef HAVE_SCHED_H
00303 # include <sched.h>
00304 #endif
00305 
00306 /* Key structure for maintaining thread specific storage */
00307 static pthread_key_t _objc_thread_storage;
00308 static pthread_attr_t _objc_thread_attribs;
00309 
00310 /* Thread local storage for a single thread */
00311 static void *thread_local_storage = NULL;
00312 
00313 /* Backend initialization functions */
00314 
00315 /* Initialize the threads subsystem.  */
00316 static inline int
00317 __gthread_objc_init_thread_system (void)
00318 {
00319   if (__gthread_active_p ())
00320     {
00321       /* Initialize the thread storage key.  */
00322       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
00323     {
00324       /* The normal default detach state for threads is
00325        * PTHREAD_CREATE_JOINABLE which causes threads to not die
00326        * when you think they should.  */
00327       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
00328           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
00329                           PTHREAD_CREATE_DETACHED) == 0)
00330         return 0;
00331     }
00332     }
00333 
00334   return -1;
00335 }
00336 
00337 /* Close the threads subsystem.  */
00338 static inline int
00339 __gthread_objc_close_thread_system (void)
00340 {
00341   if (__gthread_active_p ()
00342       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
00343       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
00344     return 0;
00345 
00346   return -1;
00347 }
00348 
00349 /* Backend thread functions */
00350 
00351 /* Create a new thread of execution.  */
00352 static inline objc_thread_t
00353 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00354 {
00355   objc_thread_t thread_id;
00356   pthread_t new_thread_handle;
00357 
00358   if (!__gthread_active_p ())
00359     return NULL;
00360 
00361   if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
00362     thread_id = (objc_thread_t) new_thread_handle;
00363   else
00364     thread_id = NULL;
00365 
00366   return thread_id;
00367 }
00368 
00369 /* Set the current thread's priority.  */
00370 static inline int
00371 __gthread_objc_thread_set_priority (int priority)
00372 {
00373   if (!__gthread_active_p ())
00374     return -1;
00375   else
00376     {
00377 #ifdef _POSIX_PRIORITY_SCHEDULING
00378 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00379       pthread_t thread_id = __gthrw_(pthread_self) ();
00380       int policy;
00381       struct sched_param params;
00382       int priority_min, priority_max;
00383 
00384       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
00385     {
00386       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
00387         return -1;
00388 
00389       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
00390         return -1;
00391 
00392       if (priority > priority_max)
00393         priority = priority_max;
00394       else if (priority < priority_min)
00395         priority = priority_min;
00396       params.sched_priority = priority;
00397 
00398       /*
00399        * The solaris 7 and several other man pages incorrectly state that
00400        * this should be a pointer to policy but pthread.h is universally
00401        * at odds with this.
00402        */
00403       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
00404         return 0;
00405     }
00406 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00407 #endif /* _POSIX_PRIORITY_SCHEDULING */
00408       return -1;
00409     }
00410 }
00411 
00412 /* Return the current thread's priority.  */
00413 static inline int
00414 __gthread_objc_thread_get_priority (void)
00415 {
00416 #ifdef _POSIX_PRIORITY_SCHEDULING
00417 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00418   if (__gthread_active_p ())
00419     {
00420       int policy;
00421       struct sched_param params;
00422 
00423       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
00424     return params.sched_priority;
00425       else
00426     return -1;
00427     }
00428   else
00429 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00430 #endif /* _POSIX_PRIORITY_SCHEDULING */
00431     return OBJC_THREAD_INTERACTIVE_PRIORITY;
00432 }
00433 
00434 /* Yield our process time to another thread.  */
00435 static inline void
00436 __gthread_objc_thread_yield (void)
00437 {
00438   if (__gthread_active_p ())
00439     __gthrw_(sched_yield) ();
00440 }
00441 
00442 /* Terminate the current thread.  */
00443 static inline int
00444 __gthread_objc_thread_exit (void)
00445 {
00446   if (__gthread_active_p ())
00447     /* exit the thread */
00448     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
00449 
00450   /* Failed if we reached here */
00451   return -1;
00452 }
00453 
00454 /* Returns an integer value which uniquely describes a thread.  */
00455 static inline objc_thread_t
00456 __gthread_objc_thread_id (void)
00457 {
00458   if (__gthread_active_p ())
00459     return (objc_thread_t) __gthrw_(pthread_self) ();
00460   else
00461     return (objc_thread_t) 1;
00462 }
00463 
00464 /* Sets the thread's local storage pointer.  */
00465 static inline int
00466 __gthread_objc_thread_set_data (void *value)
00467 {
00468   if (__gthread_active_p ())
00469     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
00470   else
00471     {
00472       thread_local_storage = value;
00473       return 0;
00474     }
00475 }
00476 
00477 /* Returns the thread's local storage pointer.  */
00478 static inline void *
00479 __gthread_objc_thread_get_data (void)
00480 {
00481   if (__gthread_active_p ())
00482     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
00483   else
00484     return thread_local_storage;
00485 }
00486 
00487 /* Backend mutex functions */
00488 
00489 /* Allocate a mutex.  */
00490 static inline int
00491 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00492 {
00493   if (__gthread_active_p ())
00494     {
00495       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
00496 
00497       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
00498     {
00499       objc_free (mutex->backend);
00500       mutex->backend = NULL;
00501       return -1;
00502     }
00503     }
00504 
00505   return 0;
00506 }
00507 
00508 /* Deallocate a mutex.  */
00509 static inline int
00510 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00511 {
00512   if (__gthread_active_p ())
00513     {
00514       int count;
00515 
00516       /*
00517        * Posix Threads specifically require that the thread be unlocked
00518        * for __gthrw_(pthread_mutex_destroy) to work.
00519        */
00520 
00521       do
00522     {
00523       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
00524       if (count < 0)
00525         return -1;
00526     }
00527       while (count);
00528 
00529       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
00530     return -1;
00531 
00532       objc_free (mutex->backend);
00533       mutex->backend = NULL;
00534     }
00535   return 0;
00536 }
00537 
00538 /* Grab a lock on a mutex.  */
00539 static inline int
00540 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00541 {
00542   if (__gthread_active_p ()
00543       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
00544     {
00545       return -1;
00546     }
00547 
00548   return 0;
00549 }
00550 
00551 /* Try to grab a lock on a mutex.  */
00552 static inline int
00553 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00554 {
00555   if (__gthread_active_p ()
00556       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
00557     {
00558       return -1;
00559     }
00560 
00561   return 0;
00562 }
00563 
00564 /* Unlock the mutex */
00565 static inline int
00566 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00567 {
00568   if (__gthread_active_p ()
00569       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
00570     {
00571       return -1;
00572     }
00573 
00574   return 0;
00575 }
00576 
00577 /* Backend condition mutex functions */
00578 
00579 /* Allocate a condition.  */
00580 static inline int
00581 __gthread_objc_condition_allocate (objc_condition_t condition)
00582 {
00583   if (__gthread_active_p ())
00584     {
00585       condition->backend = objc_malloc (sizeof (pthread_cond_t));
00586 
00587       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
00588     {
00589       objc_free (condition->backend);
00590       condition->backend = NULL;
00591       return -1;
00592     }
00593     }
00594 
00595   return 0;
00596 }
00597 
00598 /* Deallocate a condition.  */
00599 static inline int
00600 __gthread_objc_condition_deallocate (objc_condition_t condition)
00601 {
00602   if (__gthread_active_p ())
00603     {
00604       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
00605     return -1;
00606 
00607       objc_free (condition->backend);
00608       condition->backend = NULL;
00609     }
00610   return 0;
00611 }
00612 
00613 /* Wait on the condition */
00614 static inline int
00615 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00616 {
00617   if (__gthread_active_p ())
00618     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
00619                   (pthread_mutex_t *) mutex->backend);
00620   else
00621     return 0;
00622 }
00623 
00624 /* Wake up all threads waiting on this condition.  */
00625 static inline int
00626 __gthread_objc_condition_broadcast (objc_condition_t condition)
00627 {
00628   if (__gthread_active_p ())
00629     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
00630   else
00631     return 0;
00632 }
00633 
00634 /* Wake up one thread waiting on this condition.  */
00635 static inline int
00636 __gthread_objc_condition_signal (objc_condition_t condition)
00637 {
00638   if (__gthread_active_p ())
00639     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
00640   else
00641     return 0;
00642 }
00643 
00644 #else /* _LIBOBJC */
00645 
00646 static inline int
00647 __gthread_once (__gthread_once_t *once, void (*func) (void))
00648 {
00649   if (__gthread_active_p ())
00650     return __gthrw_(pthread_once) (once, func);
00651   else
00652     return -1;
00653 }
00654 
00655 static inline int
00656 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00657 {
00658   return __gthrw_(pthread_key_create) (key, dtor);
00659 }
00660 
00661 static inline int
00662 __gthread_key_delete (__gthread_key_t key)
00663 {
00664   return __gthrw_(pthread_key_delete) (key);
00665 }
00666 
00667 static inline void *
00668 __gthread_getspecific (__gthread_key_t key)
00669 {
00670   return __gthrw_(pthread_getspecific) (key);
00671 }
00672 
00673 static inline int
00674 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00675 {
00676   return __gthrw_(pthread_setspecific) (key, ptr);
00677 }
00678 
00679 static inline int
00680 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00681 {
00682   if (__gthread_active_p ())
00683     return __gthrw_(pthread_mutex_lock) (mutex);
00684   else
00685     return 0;
00686 }
00687 
00688 static inline int
00689 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00690 {
00691   if (__gthread_active_p ())
00692     return __gthrw_(pthread_mutex_trylock) (mutex);
00693   else
00694     return 0;
00695 }
00696 
00697 static inline int
00698 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00699 {
00700   if (__gthread_active_p ())
00701     return __gthrw_(pthread_mutex_unlock) (mutex);
00702   else
00703     return 0;
00704 }
00705 
00706 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00707 static inline int
00708 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
00709 {
00710   if (__gthread_active_p ())
00711     {
00712       pthread_mutexattr_t attr;
00713       int r;
00714 
00715       r = __gthrw_(pthread_mutexattr_init) (&attr);
00716       if (!r)
00717     r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
00718       if (!r)
00719     r = __gthrw_(pthread_mutex_init) (mutex, &attr);
00720       if (!r)
00721     r = __gthrw_(pthread_mutexattr_destroy) (&attr);
00722       return r;
00723     }
00724   return 0;
00725 }
00726 #endif
00727 
00728 static inline int
00729 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
00730 {
00731   return __gthread_mutex_lock (mutex);
00732 }
00733 
00734 static inline int
00735 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
00736 {
00737   return __gthread_mutex_trylock (mutex);
00738 }
00739 
00740 static inline int
00741 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
00742 {
00743   return __gthread_mutex_unlock (mutex);
00744 }
00745 
00746 static inline int
00747 __gthread_cond_broadcast (__gthread_cond_t *cond)
00748 {
00749   return __gthrw_(pthread_cond_broadcast) (cond);
00750 }
00751 
00752 static inline int
00753 __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex)
00754 {
00755   return __gthrw_(pthread_cond_wait) (cond, mutex);
00756 }
00757 
00758 static inline int
00759 __gthread_cond_wait_recursive (__gthread_cond_t *cond,
00760                    __gthread_recursive_mutex_t *mutex)
00761 {
00762   return __gthread_cond_wait (cond, mutex);
00763 }
00764 
00765 #endif /* _LIBOBJC */
00766 
00767 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

Generated on Wed Mar 26 00:42:58 2008 for libstdc++ by  doxygen 1.5.1