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.  On FreeBSD 6 and later, libc also
00162    exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
00163    to 9 does.  FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
00164    which means the alternate __gthread_active_p below cannot be used there.  */
00165 
00166 #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
00167 
00168 static volatile int __gthread_active = -1;
00169 
00170 static void
00171 __gthread_trigger (void)
00172 {
00173   __gthread_active = 1;
00174 }
00175 
00176 static inline int
00177 __gthread_active_p (void)
00178 {
00179   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
00180   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
00181 
00182   /* Avoid reading __gthread_active twice on the main code path.  */
00183   int __gthread_active_latest_value = __gthread_active;
00184 
00185   /* This test is not protected to avoid taking a lock on the main code
00186      path so every update of __gthread_active in a threaded program must
00187      be atomic with regard to the result of the test.  */
00188   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00189     {
00190       if (__gthrw_(pthread_once))
00191     {
00192       /* If this really is a threaded program, then we must ensure that
00193          __gthread_active has been set to 1 before exiting this block.  */
00194       __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
00195       __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
00196       __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
00197     }
00198 
00199       /* Make sure we'll never enter this block again.  */
00200       if (__gthread_active < 0)
00201     __gthread_active = 0;
00202 
00203       __gthread_active_latest_value = __gthread_active;
00204     }
00205 
00206   return __gthread_active_latest_value != 0;
00207 }
00208 
00209 #else /* neither FreeBSD nor Solaris */
00210 
00211 static inline int
00212 __gthread_active_p (void)
00213 {
00214   static void *const __gthread_active_ptr 
00215     = __extension__ (void *) &__gthrw_(pthread_cancel);
00216   return __gthread_active_ptr != 0;
00217 }
00218 
00219 #endif /* FreeBSD or Solaris */
00220 
00221 #else /* not __GXX_WEAK__ */
00222 
00223 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
00224    calls in shared flavors of the HP-UX C library.  Most of the stubs
00225    have no functionality.  The details are described in the "libc cumulative
00226    patch" for each subversion of HP-UX 11.  There are two special interfaces
00227    provided for checking whether an application is linked to a pthread
00228    library or not.  However, these interfaces aren't available in early
00229    libc versions.  We also can't use pthread_once as some libc versions
00230    call the init function.  So, we use pthread_create to check whether it
00231    is possible to create a thread or not.  The stub implementation returns
00232    the error number ENOSYS.  */
00233 
00234 #if defined(__hppa__) && defined(__hpux__)
00235 
00236 #include <errno.h>
00237 
00238 static volatile int __gthread_active = -1;
00239 
00240 static void *
00241 __gthread_start (void *arg __attribute__((unused)))
00242 {
00243   return NULL;
00244 }
00245 
00246 static void __gthread_active_init (void) __attribute__((noinline));
00247 static void
00248 __gthread_active_init (void)
00249 {
00250   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
00251   pthread_t t;
00252   pthread_attr_t a;
00253   int result;
00254 
00255   __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
00256   if (__gthread_active < 0)
00257     {
00258       __gthrw_(pthread_attr_init) (&a);
00259       __gthrw_(pthread_attr_setdetachstate) (&a, PTHREAD_CREATE_DETACHED);
00260       result = __gthrw_(pthread_create) (&t, &a, __gthread_start, NULL);
00261       if (result != ENOSYS)
00262     __gthread_active = 1;
00263       else
00264     __gthread_active = 0;
00265       __gthrw_(pthread_attr_destroy) (&a);
00266     }
00267   __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
00268 }
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 
00276   /* This test is not protected to avoid taking a lock on the main code
00277      path so every update of __gthread_active in a threaded program must
00278      be atomic with regard to the result of the test.  */
00279   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
00280     {
00281       __gthread_active_init ();
00282       __gthread_active_latest_value = __gthread_active;
00283     }
00284 
00285   return __gthread_active_latest_value != 0;
00286 }
00287 
00288 #else /* not hppa-hpux */
00289 
00290 static inline int
00291 __gthread_active_p (void)
00292 {
00293   return 1;
00294 }
00295 
00296 #endif /* hppa-hpux */
00297 
00298 #endif /* __GXX_WEAK__ */
00299 
00300 #ifdef _LIBOBJC
00301 
00302 /* This is the config.h file in libobjc/ */
00303 #include <config.h>
00304 
00305 #ifdef HAVE_SCHED_H
00306 # include <sched.h>
00307 #endif
00308 
00309 /* Key structure for maintaining thread specific storage */
00310 static pthread_key_t _objc_thread_storage;
00311 static pthread_attr_t _objc_thread_attribs;
00312 
00313 /* Thread local storage for a single thread */
00314 static void *thread_local_storage = NULL;
00315 
00316 /* Backend initialization functions */
00317 
00318 /* Initialize the threads subsystem.  */
00319 static inline int
00320 __gthread_objc_init_thread_system (void)
00321 {
00322   if (__gthread_active_p ())
00323     {
00324       /* Initialize the thread storage key.  */
00325       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
00326     {
00327       /* The normal default detach state for threads is
00328        * PTHREAD_CREATE_JOINABLE which causes threads to not die
00329        * when you think they should.  */
00330       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
00331           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
00332                           PTHREAD_CREATE_DETACHED) == 0)
00333         return 0;
00334     }
00335     }
00336 
00337   return -1;
00338 }
00339 
00340 /* Close the threads subsystem.  */
00341 static inline int
00342 __gthread_objc_close_thread_system (void)
00343 {
00344   if (__gthread_active_p ()
00345       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
00346       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
00347     return 0;
00348 
00349   return -1;
00350 }
00351 
00352 /* Backend thread functions */
00353 
00354 /* Create a new thread of execution.  */
00355 static inline objc_thread_t
00356 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00357 {
00358   objc_thread_t thread_id;
00359   pthread_t new_thread_handle;
00360 
00361   if (!__gthread_active_p ())
00362     return NULL;
00363 
00364   if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
00365     thread_id = (objc_thread_t) new_thread_handle;
00366   else
00367     thread_id = NULL;
00368 
00369   return thread_id;
00370 }
00371 
00372 /* Set the current thread's priority.  */
00373 static inline int
00374 __gthread_objc_thread_set_priority (int priority)
00375 {
00376   if (!__gthread_active_p ())
00377     return -1;
00378   else
00379     {
00380 #ifdef _POSIX_PRIORITY_SCHEDULING
00381 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00382       pthread_t thread_id = __gthrw_(pthread_self) ();
00383       int policy;
00384       struct sched_param params;
00385       int priority_min, priority_max;
00386 
00387       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
00388     {
00389       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
00390         return -1;
00391 
00392       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
00393         return -1;
00394 
00395       if (priority > priority_max)
00396         priority = priority_max;
00397       else if (priority < priority_min)
00398         priority = priority_min;
00399       params.sched_priority = priority;
00400 
00401       /*
00402        * The solaris 7 and several other man pages incorrectly state that
00403        * this should be a pointer to policy but pthread.h is universally
00404        * at odds with this.
00405        */
00406       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
00407         return 0;
00408     }
00409 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00410 #endif /* _POSIX_PRIORITY_SCHEDULING */
00411       return -1;
00412     }
00413 }
00414 
00415 /* Return the current thread's priority.  */
00416 static inline int
00417 __gthread_objc_thread_get_priority (void)
00418 {
00419 #ifdef _POSIX_PRIORITY_SCHEDULING
00420 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00421   if (__gthread_active_p ())
00422     {
00423       int policy;
00424       struct sched_param params;
00425 
00426       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
00427     return params.sched_priority;
00428       else
00429     return -1;
00430     }
00431   else
00432 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
00433 #endif /* _POSIX_PRIORITY_SCHEDULING */
00434     return OBJC_THREAD_INTERACTIVE_PRIORITY;
00435 }
00436 
00437 /* Yield our process time to another thread.  */
00438 static inline void
00439 __gthread_objc_thread_yield (void)
00440 {
00441   if (__gthread_active_p ())
00442     __gthrw_(sched_yield) ();
00443 }
00444 
00445 /* Terminate the current thread.  */
00446 static inline int
00447 __gthread_objc_thread_exit (void)
00448 {
00449   if (__gthread_active_p ())
00450     /* exit the thread */
00451     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
00452 
00453   /* Failed if we reached here */
00454   return -1;
00455 }
00456 
00457 /* Returns an integer value which uniquely describes a thread.  */
00458 static inline objc_thread_t
00459 __gthread_objc_thread_id (void)
00460 {
00461   if (__gthread_active_p ())
00462     return (objc_thread_t) __gthrw_(pthread_self) ();
00463   else
00464     return (objc_thread_t) 1;
00465 }
00466 
00467 /* Sets the thread's local storage pointer.  */
00468 static inline int
00469 __gthread_objc_thread_set_data (void *value)
00470 {
00471   if (__gthread_active_p ())
00472     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
00473   else
00474     {
00475       thread_local_storage = value;
00476       return 0;
00477     }
00478 }
00479 
00480 /* Returns the thread's local storage pointer.  */
00481 static inline void *
00482 __gthread_objc_thread_get_data (void)
00483 {
00484   if (__gthread_active_p ())
00485     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
00486   else
00487     return thread_local_storage;
00488 }
00489 
00490 /* Backend mutex functions */
00491 
00492 /* Allocate a mutex.  */
00493 static inline int
00494 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00495 {
00496   if (__gthread_active_p ())
00497     {
00498       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
00499 
00500       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
00501     {
00502       objc_free (mutex->backend);
00503       mutex->backend = NULL;
00504       return -1;
00505     }
00506     }
00507 
00508   return 0;
00509 }
00510 
00511 /* Deallocate a mutex.  */
00512 static inline int
00513 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00514 {
00515   if (__gthread_active_p ())
00516     {
00517       int count;
00518 
00519       /*
00520        * Posix Threads specifically require that the thread be unlocked
00521        * for __gthrw_(pthread_mutex_destroy) to work.
00522        */
00523 
00524       do
00525     {
00526       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
00527       if (count < 0)
00528         return -1;
00529     }
00530       while (count);
00531 
00532       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
00533     return -1;
00534 
00535       objc_free (mutex->backend);
00536       mutex->backend = NULL;
00537     }
00538   return 0;
00539 }
00540 
00541 /* Grab a lock on a mutex.  */
00542 static inline int
00543 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00544 {
00545   if (__gthread_active_p ()
00546       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
00547     {
00548       return -1;
00549     }
00550 
00551   return 0;
00552 }
00553 
00554 /* Try to grab a lock on a mutex.  */
00555 static inline int
00556 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00557 {
00558   if (__gthread_active_p ()
00559       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
00560     {
00561       return -1;
00562     }
00563 
00564   return 0;
00565 }
00566 
00567 /* Unlock the mutex */
00568 static inline int
00569 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00570 {
00571   if (__gthread_active_p ()
00572       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
00573     {
00574       return -1;
00575     }
00576 
00577   return 0;
00578 }
00579 
00580 /* Backend condition mutex functions */
00581 
00582 /* Allocate a condition.  */
00583 static inline int
00584 __gthread_objc_condition_allocate (objc_condition_t condition)
00585 {
00586   if (__gthread_active_p ())
00587     {
00588       condition->backend = objc_malloc (sizeof (pthread_cond_t));
00589 
00590       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
00591     {
00592       objc_free (condition->backend);
00593       condition->backend = NULL;
00594       return -1;
00595     }
00596     }
00597 
00598   return 0;
00599 }
00600 
00601 /* Deallocate a condition.  */
00602 static inline int
00603 __gthread_objc_condition_deallocate (objc_condition_t condition)
00604 {
00605   if (__gthread_active_p ())
00606     {
00607       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
00608     return -1;
00609 
00610       objc_free (condition->backend);
00611       condition->backend = NULL;
00612     }
00613   return 0;
00614 }
00615 
00616 /* Wait on the condition */
00617 static inline int
00618 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00619 {
00620   if (__gthread_active_p ())
00621     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
00622                   (pthread_mutex_t *) mutex->backend);
00623   else
00624     return 0;
00625 }
00626 
00627 /* Wake up all threads waiting on this condition.  */
00628 static inline int
00629 __gthread_objc_condition_broadcast (objc_condition_t condition)
00630 {
00631   if (__gthread_active_p ())
00632     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
00633   else
00634     return 0;
00635 }
00636 
00637 /* Wake up one thread waiting on this condition.  */
00638 static inline int
00639 __gthread_objc_condition_signal (objc_condition_t condition)
00640 {
00641   if (__gthread_active_p ())
00642     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
00643   else
00644     return 0;
00645 }
00646 
00647 #else /* _LIBOBJC */
00648 
00649 static inline int
00650 __gthread_once (__gthread_once_t *once, void (*func) (void))
00651 {
00652   if (__gthread_active_p ())
00653     return __gthrw_(pthread_once) (once, func);
00654   else
00655     return -1;
00656 }
00657 
00658 static inline int
00659 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00660 {
00661   return __gthrw_(pthread_key_create) (key, dtor);
00662 }
00663 
00664 static inline int
00665 __gthread_key_delete (__gthread_key_t key)
00666 {
00667   return __gthrw_(pthread_key_delete) (key);
00668 }
00669 
00670 static inline void *
00671 __gthread_getspecific (__gthread_key_t key)
00672 {
00673   return __gthrw_(pthread_getspecific) (key);
00674 }
00675 
00676 static inline int
00677 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00678 {
00679   return __gthrw_(pthread_setspecific) (key, ptr);
00680 }
00681 
00682 static inline int
00683 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00684 {
00685   if (__gthread_active_p ())
00686     return __gthrw_(pthread_mutex_lock) (mutex);
00687   else
00688     return 0;
00689 }
00690 
00691 static inline int
00692 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00693 {
00694   if (__gthread_active_p ())
00695     return __gthrw_(pthread_mutex_trylock) (mutex);
00696   else
00697     return 0;
00698 }
00699 
00700 static inline int
00701 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00702 {
00703   if (__gthread_active_p ())
00704     return __gthrw_(pthread_mutex_unlock) (mutex);
00705   else
00706     return 0;
00707 }
00708 
00709 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00710 static inline int
00711 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
00712 {
00713   if (__gthread_active_p ())
00714     {
00715       pthread_mutexattr_t attr;
00716       int r;
00717 
00718       r = __gthrw_(pthread_mutexattr_init) (&attr);
00719       if (!r)
00720     r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
00721       if (!r)
00722     r = __gthrw_(pthread_mutex_init) (mutex, &attr);
00723       if (!r)
00724     r = __gthrw_(pthread_mutexattr_destroy) (&attr);
00725       return r;
00726     }
00727   return 0;
00728 }
00729 #endif
00730 
00731 static inline int
00732 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
00733 {
00734   return __gthread_mutex_lock (mutex);
00735 }
00736 
00737 static inline int
00738 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
00739 {
00740   return __gthread_mutex_trylock (mutex);
00741 }
00742 
00743 static inline int
00744 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
00745 {
00746   return __gthread_mutex_unlock (mutex);
00747 }
00748 
00749 static inline int
00750 __gthread_cond_broadcast (__gthread_cond_t *cond)
00751 {
00752   return __gthrw_(pthread_cond_broadcast) (cond);
00753 }
00754 
00755 static inline int
00756 __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex)
00757 {
00758   return __gthrw_(pthread_cond_wait) (cond, mutex);
00759 }
00760 
00761 static inline int
00762 __gthread_cond_wait_recursive (__gthread_cond_t *cond,
00763                    __gthread_recursive_mutex_t *mutex)
00764 {
00765   return __gthread_cond_wait (cond, mutex);
00766 }
00767 
00768 #endif /* _LIBOBJC */
00769 
00770 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

Generated on Sat Dec 12 09:40:10 2009 for libstdc++ by  doxygen 1.5.6