1 /* Threads compatibility routines for libgcc2 and libobjc. */ 2 /* Compile this one with gcc. */ 3 /* Copyright (C) 1997-2014 Free Software Foundation, Inc. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 Under Section 7 of GPL version 3, you are granted additional 18 permissions described in the GCC Runtime Library Exception, version 19 3.1, as published by the Free Software Foundation. 20 21 You should have received a copy of the GNU General Public License and 22 a copy of the GCC Runtime Library Exception along with this program; 23 see 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 60 typedef pthread_t __gthread_t; 61 typedef pthread_key_t __gthread_key_t; 62 typedef pthread_once_t __gthread_once_t; 63 typedef pthread_mutex_t __gthread_mutex_t; 64 typedef pthread_mutex_t __gthread_recursive_mutex_t; 65 typedef pthread_cond_t __gthread_cond_t; 66 typedef 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 184 static volatile int __gthread_active = -1; 185 186 static void 187 __gthread_trigger (void) 188 { 189 __gthread_active = 1; 190 } 191 192 static 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 259 static 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 290 static volatile int __gthread_active = -1; 291 292 static 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 311 static 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 */ 331 static pthread_key_t _objc_thread_storage; 332 static pthread_attr_t _objc_thread_attribs; 333 334 /* Thread local storage for a single thread */ 335 static void *thread_local_storage = NULL; 336 337 /* Backend initialization functions */ 338 339 /* Initialize the threads subsystem. */ 340 static 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. */ 362 static 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. */ 376 static 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. */ 395 static 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. */ 438 static 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. */ 460 static 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. */ 468 static 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. */ 480 static 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. */ 490 static 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. */ 503 static 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. */ 515 static 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. */ 534 static 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. */ 564 static 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. */ 577 static 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 */ 590 static 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. */ 605 static 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. */ 624 static 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 */ 639 static 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. */ 650 static 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. */ 660 static 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 671 static 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 678 static inline int 679 __gthread_join (__gthread_t __threadid, void **__value_ptr) 680 { 681 return __gthrw_(pthread_join) (__threadid, __value_ptr); 682 } 683 684 static inline int 685 __gthread_detach (__gthread_t __threadid) 686 { 687 return __gthrw_(pthread_detach) (__threadid); 688 } 689 690 static inline int 691 __gthread_equal (__gthread_t __t1, __gthread_t __t2) 692 { 693 return __gthrw_(pthread_equal) (__t1, __t2); 694 } 695 696 static inline __gthread_t 697 __gthread_self (void) 698 { 699 return __gthrw_(pthread_self) (); 700 } 701 702 static inline int 703 __gthread_yield (void) 704 { 705 return __gthrw_(sched_yield) (); 706 } 707 708 static 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 717 static inline int 718 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) 719 { 720 return __gthrw_(pthread_key_create) (__key, __dtor); 721 } 722 723 static inline int 724 __gthread_key_delete (__gthread_key_t __key) 725 { 726 return __gthrw_(pthread_key_delete) (__key); 727 } 728 729 static inline void * 730 __gthread_getspecific (__gthread_key_t __key) 731 { 732 return __gthrw_(pthread_getspecific) (__key); 733 } 734 735 static inline int 736 __gthread_setspecific (__gthread_key_t __key, const void *__ptr) 737 { 738 return __gthrw_(pthread_setspecific) (__key, __ptr); 739 } 740 741 static 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 748 static 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 757 static 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 766 static 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 776 static 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 787 static 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) 798 static 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 820 static inline int 821 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) 822 { 823 return __gthread_mutex_lock (__mutex); 824 } 825 826 static 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 833 static 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 841 static inline int 842 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) 843 { 844 return __gthread_mutex_unlock (__mutex); 845 } 846 847 static 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 854 static 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 862 static inline int 863 __gthread_cond_broadcast (__gthread_cond_t *__cond) 864 { 865 return __gthrw_(pthread_cond_broadcast) (__cond); 866 } 867 868 static inline int 869 __gthread_cond_signal (__gthread_cond_t *__cond) 870 { 871 return __gthrw_(pthread_cond_signal) (__cond); 872 } 873 874 static 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 880 static 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 887 static 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 894 static 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