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