gthr-default.h revision 11cd02dfb91661c65134cac258cf5924270e9d2b
1/* Threads compatibility routines for libgcc2 and libobjc. */ 2/* Compile this one with gcc. */ 3/* Copyright (C) 1997-2014 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 3, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17Under Section 7 of GPL version 3, you are granted additional 18permissions described in the GCC Runtime Library Exception, version 193.1, as published by the Free Software Foundation. 20 21You should have received a copy of the GNU General Public License and 22a copy of the GCC Runtime Library Exception along with this program; 23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24<http://www.gnu.org/licenses/>. */ 25 26#ifndef _GLIBCXX_GCC_GTHR_POSIX_H 27#define _GLIBCXX_GCC_GTHR_POSIX_H 28 29/* POSIX threads specific definitions. 30 Easy, since the interface is just one-to-one mapping. */ 31 32#define __GTHREADS 1 33#define __GTHREADS_CXX0X 1 34 35/* The following should normally be in a different header file, 36 * but I couldn't find the right location. The point of the macro 37 * definition below is to prevent libsupc++ and libstdc++ to reference 38 * weak symbols in their static C++ constructors. Such code crashes 39 * when a shared object linked statically to these libraries is 40 * loaded on Android 2.1 (Eclair) and older platform releases, due 41 * to a dynamic linker bug. 42 */ 43#ifdef __ANDROID__ 44#undef _GLIBCXX_GTHREAD_USE_WEAK 45#define _GLIBCXX_GTHREAD_USE_WEAK 0 46#endif 47 48#include <pthread.h> 49 50#if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \ 51 || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK)) 52# include <unistd.h> 53# if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0 54# define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 55# else 56# define _GTHREAD_USE_MUTEX_TIMEDLOCK 0 57# endif 58#endif 59 60typedef pthread_t __gthread_t; 61typedef pthread_key_t __gthread_key_t; 62typedef pthread_once_t __gthread_once_t; 63typedef pthread_mutex_t __gthread_mutex_t; 64typedef pthread_mutex_t __gthread_recursive_mutex_t; 65typedef pthread_cond_t __gthread_cond_t; 66typedef struct timespec __gthread_time_t; 67 68/* POSIX like conditional variables are supported. Please look at comments 69 in gthr.h for details. */ 70#define __GTHREAD_HAS_COND 1 71 72#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER 73#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function 74#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT 75#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 76#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER 77#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 78#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 79#else 80#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 81#endif 82#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER 83#define __GTHREAD_TIME_INIT {0,0} 84 85#ifdef _GTHREAD_USE_MUTEX_INIT_FUNC 86# undef __GTHREAD_MUTEX_INIT 87#endif 88#ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC 89# undef __GTHREAD_RECURSIVE_MUTEX_INIT 90# undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION 91# define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 92#endif 93#ifdef _GTHREAD_USE_COND_INIT_FUNC 94# undef __GTHREAD_COND_INIT 95# define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function 96#endif 97 98#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 99# ifndef __gthrw_pragma 100# define __gthrw_pragma(pragma) 101# endif 102# define __gthrw2(name,name2,type) \ 103 static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ 104 __gthrw_pragma(weak type) 105# define __gthrw_(name) __gthrw_ ## name 106#else 107# define __gthrw2(name,name2,type) 108# define __gthrw_(name) name 109#endif 110 111/* Typically, __gthrw_foo is a weak reference to symbol foo. */ 112#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) 113 114__gthrw(pthread_once) 115__gthrw(pthread_getspecific) 116__gthrw(pthread_setspecific) 117 118__gthrw(pthread_create) 119__gthrw(pthread_join) 120__gthrw(pthread_equal) 121__gthrw(pthread_self) 122__gthrw(pthread_detach) 123#ifndef __BIONIC__ 124__gthrw(pthread_cancel) 125#endif 126__gthrw(sched_yield) 127 128__gthrw(pthread_mutex_lock) 129__gthrw(pthread_mutex_trylock) 130#if _GTHREAD_USE_MUTEX_TIMEDLOCK 131__gthrw(pthread_mutex_timedlock) 132#endif 133__gthrw(pthread_mutex_unlock) 134__gthrw(pthread_mutex_init) 135__gthrw(pthread_mutex_destroy) 136 137__gthrw(pthread_cond_init) 138__gthrw(pthread_cond_broadcast) 139__gthrw(pthread_cond_signal) 140__gthrw(pthread_cond_wait) 141__gthrw(pthread_cond_timedwait) 142__gthrw(pthread_cond_destroy) 143 144__gthrw(pthread_key_create) 145__gthrw(pthread_key_delete) 146__gthrw(pthread_mutexattr_init) 147__gthrw(pthread_mutexattr_settype) 148__gthrw(pthread_mutexattr_destroy) 149 150 151#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) 152/* Objective-C. */ 153__gthrw(pthread_exit) 154#ifdef _POSIX_PRIORITY_SCHEDULING 155#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 156__gthrw(sched_get_priority_max) 157__gthrw(sched_get_priority_min) 158#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 159#endif /* _POSIX_PRIORITY_SCHEDULING */ 160__gthrw(pthread_attr_destroy) 161__gthrw(pthread_attr_init) 162__gthrw(pthread_attr_setdetachstate) 163#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 164__gthrw(pthread_getschedparam) 165__gthrw(pthread_setschedparam) 166#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 167#endif /* _LIBOBJC || _LIBOBJC_WEAK */ 168 169#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK 170 171/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if 172 -pthreads is not specified. The functions are dummies and most return an 173 error value. However pthread_once returns 0 without invoking the routine 174 it is passed so we cannot pretend that the interface is active if -pthreads 175 is not specified. On Solaris 2.5.1, the interface is not exposed at all so 176 we need to play the usual game with weak symbols. On Solaris 10 and up, a 177 working interface is always exposed. On FreeBSD 6 and later, libc also 178 exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up 179 to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, 180 which means the alternate __gthread_active_p below cannot be used there. */ 181 182#if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) 183 184static volatile int __gthread_active = -1; 185 186static void 187__gthread_trigger (void) 188{ 189 __gthread_active = 1; 190} 191 192static inline int 193__gthread_active_p (void) 194{ 195 static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; 196 static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; 197 198 /* Avoid reading __gthread_active twice on the main code path. */ 199 int __gthread_active_latest_value = __gthread_active; 200 201 /* This test is not protected to avoid taking a lock on the main code 202 path so every update of __gthread_active in a threaded program must 203 be atomic with regard to the result of the test. */ 204 if (__builtin_expect (__gthread_active_latest_value < 0, 0)) 205 { 206 if (__gthrw_(pthread_once)) 207 { 208 /* If this really is a threaded program, then we must ensure that 209 __gthread_active has been set to 1 before exiting this block. */ 210 __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); 211 __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); 212 __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); 213 } 214 215 /* Make sure we'll never enter this block again. */ 216 if (__gthread_active < 0) 217 __gthread_active = 0; 218 219 __gthread_active_latest_value = __gthread_active; 220 } 221 222 return __gthread_active_latest_value != 0; 223} 224 225#else /* neither FreeBSD nor Solaris */ 226 227/* For a program to be multi-threaded the only thing that it certainly must 228 be using is pthread_create. However, there may be other libraries that 229 intercept pthread_create with their own definitions to wrap pthreads 230 functionality for some purpose. In those cases, pthread_create being 231 defined might not necessarily mean that libpthread is actually linked 232 in. 233 234 For the GNU C library, we can use a known internal name. This is always 235 available in the ABI, but no other library would define it. That is 236 ideal, since any public pthread function might be intercepted just as 237 pthread_create might be. __pthread_key_create is an "internal" 238 implementation symbol, but it is part of the public exported ABI. Also, 239 it's among the symbols that the static libpthread.a always links in 240 whenever pthread_create is used, so there is no danger of a false 241 negative result in any statically-linked, multi-threaded program. 242 243 For others, we choose pthread_cancel as a function that seems unlikely 244 to be redefined by an interceptor library. The bionic (Android) C 245 library does not provide pthread_cancel, so we do use pthread_create 246 there (and interceptor libraries lose). */ 247 248#ifdef __GLIBC__ 249__gthrw2(__gthrw_(__pthread_key_create), 250 __pthread_key_create, 251 pthread_key_create) 252# define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create) 253#elif defined (__BIONIC__) 254# define GTHR_ACTIVE_PROXY __gthrw_(pthread_create) 255#else 256# define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel) 257#endif 258 259static inline int 260__gthread_active_p (void) 261{ 262 static void *const __gthread_active_ptr 263 = __extension__ (void *) >HR_ACTIVE_PROXY; 264 return __gthread_active_ptr != 0; 265} 266 267#endif /* FreeBSD or Solaris */ 268 269#else /* not __GXX_WEAK__ */ 270 271/* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread 272 calls in shared flavors of the HP-UX C library. Most of the stubs 273 have no functionality. The details are described in the "libc cumulative 274 patch" for each subversion of HP-UX 11. There are two special interfaces 275 provided for checking whether an application is linked to a shared pthread 276 library or not. However, these interfaces aren't available in early 277 libpthread libraries. We also need a test that works for archive 278 libraries. We can't use pthread_once as some libc versions call the 279 init function. We also can't use pthread_create or pthread_attr_init 280 as these create a thread and thereby prevent changing the default stack 281 size. The function pthread_default_stacksize_np is available in both 282 the archive and shared versions of libpthread. It can be used to 283 determine the default pthread stack size. There is a stub in some 284 shared libc versions which returns a zero size if pthreads are not 285 active. We provide an equivalent stub to handle cases where libc 286 doesn't provide one. */ 287 288#if defined(__hppa__) && defined(__hpux__) 289 290static volatile int __gthread_active = -1; 291 292static inline int 293__gthread_active_p (void) 294{ 295 /* Avoid reading __gthread_active twice on the main code path. */ 296 int __gthread_active_latest_value = __gthread_active; 297 size_t __s; 298 299 if (__builtin_expect (__gthread_active_latest_value < 0, 0)) 300 { 301 pthread_default_stacksize_np (0, &__s); 302 __gthread_active = __s ? 1 : 0; 303 __gthread_active_latest_value = __gthread_active; 304 } 305 306 return __gthread_active_latest_value != 0; 307} 308 309#else /* not hppa-hpux */ 310 311static inline int 312__gthread_active_p (void) 313{ 314 return 1; 315} 316 317#endif /* hppa-hpux */ 318 319#endif /* __GXX_WEAK__ */ 320 321#ifdef _LIBOBJC 322 323/* This is the config.h file in libobjc/ */ 324#include <config.h> 325 326#ifdef HAVE_SCHED_H 327# include <sched.h> 328#endif 329 330/* Key structure for maintaining thread specific storage */ 331static pthread_key_t _objc_thread_storage; 332static pthread_attr_t _objc_thread_attribs; 333 334/* Thread local storage for a single thread */ 335static void *thread_local_storage = NULL; 336 337/* Backend initialization functions */ 338 339/* Initialize the threads subsystem. */ 340static inline int 341__gthread_objc_init_thread_system (void) 342{ 343 if (__gthread_active_p ()) 344 { 345 /* Initialize the thread storage key. */ 346 if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) 347 { 348 /* The normal default detach state for threads is 349 * PTHREAD_CREATE_JOINABLE which causes threads to not die 350 * when you think they should. */ 351 if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 352 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, 353 PTHREAD_CREATE_DETACHED) == 0) 354 return 0; 355 } 356 } 357 358 return -1; 359} 360 361/* Close the threads subsystem. */ 362static inline int 363__gthread_objc_close_thread_system (void) 364{ 365 if (__gthread_active_p () 366 && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 367 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) 368 return 0; 369 370 return -1; 371} 372 373/* Backend thread functions */ 374 375/* Create a new thread of execution. */ 376static inline objc_thread_t 377__gthread_objc_thread_detach (void (*func)(void *), void *arg) 378{ 379 objc_thread_t thread_id; 380 pthread_t new_thread_handle; 381 382 if (!__gthread_active_p ()) 383 return NULL; 384 385 if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs, 386 (void *) func, arg))) 387 thread_id = (objc_thread_t) new_thread_handle; 388 else 389 thread_id = NULL; 390 391 return thread_id; 392} 393 394/* Set the current thread's priority. */ 395static inline int 396__gthread_objc_thread_set_priority (int priority) 397{ 398 if (!__gthread_active_p ()) 399 return -1; 400 else 401 { 402#ifdef _POSIX_PRIORITY_SCHEDULING 403#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 404 pthread_t thread_id = __gthrw_(pthread_self) (); 405 int policy; 406 struct sched_param params; 407 int priority_min, priority_max; 408 409 if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) 410 { 411 if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) 412 return -1; 413 414 if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) 415 return -1; 416 417 if (priority > priority_max) 418 priority = priority_max; 419 else if (priority < priority_min) 420 priority = priority_min; 421 params.sched_priority = priority; 422 423 /* 424 * The solaris 7 and several other man pages incorrectly state that 425 * this should be a pointer to policy but pthread.h is universally 426 * at odds with this. 427 */ 428 if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) 429 return 0; 430 } 431#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 432#endif /* _POSIX_PRIORITY_SCHEDULING */ 433 return -1; 434 } 435} 436 437/* Return the current thread's priority. */ 438static inline int 439__gthread_objc_thread_get_priority (void) 440{ 441#ifdef _POSIX_PRIORITY_SCHEDULING 442#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 443 if (__gthread_active_p ()) 444 { 445 int policy; 446 struct sched_param params; 447 448 if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) 449 return params.sched_priority; 450 else 451 return -1; 452 } 453 else 454#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 455#endif /* _POSIX_PRIORITY_SCHEDULING */ 456 return OBJC_THREAD_INTERACTIVE_PRIORITY; 457} 458 459/* Yield our process time to another thread. */ 460static inline void 461__gthread_objc_thread_yield (void) 462{ 463 if (__gthread_active_p ()) 464 __gthrw_(sched_yield) (); 465} 466 467/* Terminate the current thread. */ 468static inline int 469__gthread_objc_thread_exit (void) 470{ 471 if (__gthread_active_p ()) 472 /* exit the thread */ 473 __gthrw_(pthread_exit) (&__objc_thread_exit_status); 474 475 /* Failed if we reached here */ 476 return -1; 477} 478 479/* Returns an integer value which uniquely describes a thread. */ 480static inline objc_thread_t 481__gthread_objc_thread_id (void) 482{ 483 if (__gthread_active_p ()) 484 return (objc_thread_t) __gthrw_(pthread_self) (); 485 else 486 return (objc_thread_t) 1; 487} 488 489/* Sets the thread's local storage pointer. */ 490static inline int 491__gthread_objc_thread_set_data (void *value) 492{ 493 if (__gthread_active_p ()) 494 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); 495 else 496 { 497 thread_local_storage = value; 498 return 0; 499 } 500} 501 502/* Returns the thread's local storage pointer. */ 503static inline void * 504__gthread_objc_thread_get_data (void) 505{ 506 if (__gthread_active_p ()) 507 return __gthrw_(pthread_getspecific) (_objc_thread_storage); 508 else 509 return thread_local_storage; 510} 511 512/* Backend mutex functions */ 513 514/* Allocate a mutex. */ 515static inline int 516__gthread_objc_mutex_allocate (objc_mutex_t mutex) 517{ 518 if (__gthread_active_p ()) 519 { 520 mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); 521 522 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) 523 { 524 objc_free (mutex->backend); 525 mutex->backend = NULL; 526 return -1; 527 } 528 } 529 530 return 0; 531} 532 533/* Deallocate a mutex. */ 534static inline int 535__gthread_objc_mutex_deallocate (objc_mutex_t mutex) 536{ 537 if (__gthread_active_p ()) 538 { 539 int count; 540 541 /* 542 * Posix Threads specifically require that the thread be unlocked 543 * for __gthrw_(pthread_mutex_destroy) to work. 544 */ 545 546 do 547 { 548 count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); 549 if (count < 0) 550 return -1; 551 } 552 while (count); 553 554 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) 555 return -1; 556 557 objc_free (mutex->backend); 558 mutex->backend = NULL; 559 } 560 return 0; 561} 562 563/* Grab a lock on a mutex. */ 564static inline int 565__gthread_objc_mutex_lock (objc_mutex_t mutex) 566{ 567 if (__gthread_active_p () 568 && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) 569 { 570 return -1; 571 } 572 573 return 0; 574} 575 576/* Try to grab a lock on a mutex. */ 577static inline int 578__gthread_objc_mutex_trylock (objc_mutex_t mutex) 579{ 580 if (__gthread_active_p () 581 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) 582 { 583 return -1; 584 } 585 586 return 0; 587} 588 589/* Unlock the mutex */ 590static inline int 591__gthread_objc_mutex_unlock (objc_mutex_t mutex) 592{ 593 if (__gthread_active_p () 594 && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) 595 { 596 return -1; 597 } 598 599 return 0; 600} 601 602/* Backend condition mutex functions */ 603 604/* Allocate a condition. */ 605static inline int 606__gthread_objc_condition_allocate (objc_condition_t condition) 607{ 608 if (__gthread_active_p ()) 609 { 610 condition->backend = objc_malloc (sizeof (pthread_cond_t)); 611 612 if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) 613 { 614 objc_free (condition->backend); 615 condition->backend = NULL; 616 return -1; 617 } 618 } 619 620 return 0; 621} 622 623/* Deallocate a condition. */ 624static inline int 625__gthread_objc_condition_deallocate (objc_condition_t condition) 626{ 627 if (__gthread_active_p ()) 628 { 629 if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) 630 return -1; 631 632 objc_free (condition->backend); 633 condition->backend = NULL; 634 } 635 return 0; 636} 637 638/* Wait on the condition */ 639static inline int 640__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) 641{ 642 if (__gthread_active_p ()) 643 return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, 644 (pthread_mutex_t *) mutex->backend); 645 else 646 return 0; 647} 648 649/* Wake up all threads waiting on this condition. */ 650static inline int 651__gthread_objc_condition_broadcast (objc_condition_t condition) 652{ 653 if (__gthread_active_p ()) 654 return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); 655 else 656 return 0; 657} 658 659/* Wake up one thread waiting on this condition. */ 660static inline int 661__gthread_objc_condition_signal (objc_condition_t condition) 662{ 663 if (__gthread_active_p ()) 664 return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); 665 else 666 return 0; 667} 668 669#else /* _LIBOBJC */ 670 671static inline int 672__gthread_create (__gthread_t *__threadid, void *(*__func) (void*), 673 void *__args) 674{ 675 return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); 676} 677 678static inline int 679__gthread_join (__gthread_t __threadid, void **__value_ptr) 680{ 681 return __gthrw_(pthread_join) (__threadid, __value_ptr); 682} 683 684static inline int 685__gthread_detach (__gthread_t __threadid) 686{ 687 return __gthrw_(pthread_detach) (__threadid); 688} 689 690static inline int 691__gthread_equal (__gthread_t __t1, __gthread_t __t2) 692{ 693 return __gthrw_(pthread_equal) (__t1, __t2); 694} 695 696static inline __gthread_t 697__gthread_self (void) 698{ 699 return __gthrw_(pthread_self) (); 700} 701 702static inline int 703__gthread_yield (void) 704{ 705 return __gthrw_(sched_yield) (); 706} 707 708static inline int 709__gthread_once (__gthread_once_t *__once, void (*__func) (void)) 710{ 711 if (__gthread_active_p ()) 712 return __gthrw_(pthread_once) (__once, __func); 713 else 714 return -1; 715} 716 717static inline int 718__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) 719{ 720 return __gthrw_(pthread_key_create) (__key, __dtor); 721} 722 723static inline int 724__gthread_key_delete (__gthread_key_t __key) 725{ 726 return __gthrw_(pthread_key_delete) (__key); 727} 728 729static inline void * 730__gthread_getspecific (__gthread_key_t __key) 731{ 732 return __gthrw_(pthread_getspecific) (__key); 733} 734 735static inline int 736__gthread_setspecific (__gthread_key_t __key, const void *__ptr) 737{ 738 return __gthrw_(pthread_setspecific) (__key, __ptr); 739} 740 741static inline void 742__gthread_mutex_init_function (__gthread_mutex_t *__mutex) 743{ 744 if (__gthread_active_p ()) 745 __gthrw_(pthread_mutex_init) (__mutex, NULL); 746} 747 748static inline int 749__gthread_mutex_destroy (__gthread_mutex_t *__mutex) 750{ 751 if (__gthread_active_p ()) 752 return __gthrw_(pthread_mutex_destroy) (__mutex); 753 else 754 return 0; 755} 756 757static inline int 758__gthread_mutex_lock (__gthread_mutex_t *__mutex) 759{ 760 if (__gthread_active_p ()) 761 return __gthrw_(pthread_mutex_lock) (__mutex); 762 else 763 return 0; 764} 765 766static inline int 767__gthread_mutex_trylock (__gthread_mutex_t *__mutex) 768{ 769 if (__gthread_active_p ()) 770 return __gthrw_(pthread_mutex_trylock) (__mutex); 771 else 772 return 0; 773} 774 775#if _GTHREAD_USE_MUTEX_TIMEDLOCK 776static inline int 777__gthread_mutex_timedlock (__gthread_mutex_t *__mutex, 778 const __gthread_time_t *__abs_timeout) 779{ 780 if (__gthread_active_p ()) 781 return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout); 782 else 783 return 0; 784} 785#endif 786 787static inline int 788__gthread_mutex_unlock (__gthread_mutex_t *__mutex) 789{ 790 if (__gthread_active_p ()) 791 return __gthrw_(pthread_mutex_unlock) (__mutex); 792 else 793 return 0; 794} 795 796#if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \ 797 || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) 798static inline int 799__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) 800{ 801 if (__gthread_active_p ()) 802 { 803 pthread_mutexattr_t __attr; 804 int __r; 805 806 __r = __gthrw_(pthread_mutexattr_init) (&__attr); 807 if (!__r) 808 __r = __gthrw_(pthread_mutexattr_settype) (&__attr, 809 PTHREAD_MUTEX_RECURSIVE); 810 if (!__r) 811 __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr); 812 if (!__r) 813 __r = __gthrw_(pthread_mutexattr_destroy) (&__attr); 814 return __r; 815 } 816 return 0; 817} 818#endif 819 820static inline int 821__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) 822{ 823 return __gthread_mutex_lock (__mutex); 824} 825 826static inline int 827__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) 828{ 829 return __gthread_mutex_trylock (__mutex); 830} 831 832#if _GTHREAD_USE_MUTEX_TIMEDLOCK 833static inline int 834__gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, 835 const __gthread_time_t *__abs_timeout) 836{ 837 return __gthread_mutex_timedlock (__mutex, __abs_timeout); 838} 839#endif 840 841static inline int 842__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) 843{ 844 return __gthread_mutex_unlock (__mutex); 845} 846 847static inline int 848__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) 849{ 850 return __gthread_mutex_destroy (__mutex); 851} 852 853#ifdef _GTHREAD_USE_COND_INIT_FUNC 854static inline void 855__gthread_cond_init_function (__gthread_cond_t *__cond) 856{ 857 if (__gthread_active_p ()) 858 __gthrw_(pthread_cond_init) (__cond, NULL); 859} 860#endif 861 862static inline int 863__gthread_cond_broadcast (__gthread_cond_t *__cond) 864{ 865 return __gthrw_(pthread_cond_broadcast) (__cond); 866} 867 868static inline int 869__gthread_cond_signal (__gthread_cond_t *__cond) 870{ 871 return __gthrw_(pthread_cond_signal) (__cond); 872} 873 874static inline int 875__gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) 876{ 877 return __gthrw_(pthread_cond_wait) (__cond, __mutex); 878} 879 880static inline int 881__gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, 882 const __gthread_time_t *__abs_timeout) 883{ 884 return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); 885} 886 887static inline int 888__gthread_cond_wait_recursive (__gthread_cond_t *__cond, 889 __gthread_recursive_mutex_t *__mutex) 890{ 891 return __gthread_cond_wait (__cond, __mutex); 892} 893 894static inline int 895__gthread_cond_destroy (__gthread_cond_t* __cond) 896{ 897 return __gthrw_(pthread_cond_destroy) (__cond); 898} 899 900#endif /* _LIBOBJC */ 901 902#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ 903