gthr-posix95.h revision 169689
1169689Skan/* Threads compatibility routines for libgcc2 and libobjc. */ 2169689Skan/* Compile this one with gcc. */ 3169689Skan/* Copyright (C) 2004, 2005 Free Software Foundation, Inc. 4169689Skan 5169689SkanThis file is part of GCC. 6169689Skan 7169689SkanGCC is free software; you can redistribute it and/or modify it under 8169689Skanthe terms of the GNU General Public License as published by the Free 9169689SkanSoftware Foundation; either version 2, or (at your option) any later 10169689Skanversion. 11169689Skan 12169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 14169689SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15169689Skanfor more details. 16169689Skan 17169689SkanYou should have received a copy of the GNU General Public License 18169689Skanalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 21169689Skan 22169689Skan/* As a special exception, if you link this library with other files, 23169689Skan some of which are compiled with GCC, to produce an executable, 24169689Skan this library does not by itself cause the resulting executable 25169689Skan to be covered by the GNU General Public License. 26169689Skan This exception does not however invalidate any other reasons why 27169689Skan the executable file might be covered by the GNU General Public License. */ 28169689Skan 29169689Skan#ifndef GCC_GTHR_POSIX_H 30169689Skan#define GCC_GTHR_POSIX_H 31169689Skan 32169689Skan/* POSIX threads specific definitions. 33169689Skan Easy, since the interface is just one-to-one mapping. */ 34169689Skan 35169689Skan#define __GTHREADS 1 36169689Skan 37169689Skan/* Some implementations of <pthread.h> require this to be defined. */ 38169689Skan#ifndef _REENTRANT 39169689Skan#define _REENTRANT 1 40169689Skan#endif 41169689Skan 42169689Skan#include <pthread.h> 43169689Skan#include <unistd.h> 44169689Skan 45169689Skantypedef pthread_key_t __gthread_key_t; 46169689Skantypedef pthread_once_t __gthread_once_t; 47169689Skantypedef pthread_mutex_t __gthread_mutex_t; 48169689Skan 49169689Skantypedef struct { 50169689Skan long depth; 51169689Skan pthread_t owner; 52169689Skan pthread_mutex_t actual; 53169689Skan} __gthread_recursive_mutex_t; 54169689Skan 55169689Skan#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER 56169689Skan#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT 57169689Skan#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 58169689Skan 59169689Skan#if SUPPORTS_WEAK && GTHREAD_USE_WEAK 60169689Skan# define __gthrw(name) \ 61169689Skan static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))); 62169689Skan# define __gthrw_(name) __gthrw_ ## name 63169689Skan#else 64169689Skan# define __gthrw(name) 65169689Skan# define __gthrw_(name) name 66169689Skan#endif 67169689Skan 68169689Skan__gthrw(pthread_once) 69169689Skan__gthrw(pthread_key_create) 70169689Skan__gthrw(pthread_key_delete) 71169689Skan__gthrw(pthread_getspecific) 72169689Skan__gthrw(pthread_setspecific) 73169689Skan__gthrw(pthread_create) 74169689Skan__gthrw(pthread_cancel) 75169689Skan__gthrw(pthread_self) 76169689Skan 77169689Skan__gthrw(pthread_mutex_lock) 78169689Skan__gthrw(pthread_mutex_trylock) 79169689Skan__gthrw(pthread_mutex_unlock) 80169689Skan__gthrw(pthread_mutexattr_init) 81169689Skan__gthrw(pthread_mutexattr_destroy) 82169689Skan 83169689Skan__gthrw(pthread_mutex_init) 84169689Skan 85169689Skan#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) 86169689Skan/* Objective-C. */ 87169689Skan__gthrw(pthread_cond_broadcast) 88169689Skan__gthrw(pthread_cond_destroy) 89169689Skan__gthrw(pthread_cond_init) 90169689Skan__gthrw(pthread_cond_signal) 91169689Skan__gthrw(pthread_cond_wait) 92169689Skan__gthrw(pthread_exit) 93169689Skan__gthrw(pthread_mutex_destroy) 94169689Skan#ifdef _POSIX_PRIORITY_SCHEDULING 95169689Skan#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 96169689Skan__gthrw(sched_get_priority_max) 97169689Skan__gthrw(sched_get_priority_min) 98169689Skan#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 99169689Skan#endif /* _POSIX_PRIORITY_SCHEDULING */ 100169689Skan__gthrw(sched_yield) 101169689Skan__gthrw(pthread_attr_destroy) 102169689Skan__gthrw(pthread_attr_init) 103169689Skan__gthrw(pthread_attr_setdetachstate) 104169689Skan#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 105169689Skan__gthrw(pthread_getschedparam) 106169689Skan__gthrw(pthread_setschedparam) 107169689Skan#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 108169689Skan#endif /* _LIBOBJC || _LIBOBJC_WEAK */ 109169689Skan 110169689Skan#if SUPPORTS_WEAK && GTHREAD_USE_WEAK 111169689Skan 112169689Skan/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if 113169689Skan -pthreads is not specified. The functions are dummies and most return an 114169689Skan error value. However pthread_once returns 0 without invoking the routine 115169689Skan it is passed so we cannot pretend that the interface is active if -pthreads 116169689Skan is not specified. On Solaris 2.5.1, the interface is not exposed at all so 117169689Skan we need to play the usual game with weak symbols. On Solaris 10 and up, a 118169689Skan working interface is always exposed. */ 119169689Skan 120169689Skan#if defined(__sun) && defined(__svr4__) 121169689Skan 122169689Skanstatic volatile int __gthread_active = -1; 123169689Skan 124169689Skanstatic void 125169689Skan__gthread_trigger (void) 126169689Skan{ 127169689Skan __gthread_active = 1; 128169689Skan} 129169689Skan 130169689Skanstatic inline int 131169689Skan__gthread_active_p (void) 132169689Skan{ 133169689Skan static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; 134169689Skan static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; 135169689Skan 136169689Skan /* Avoid reading __gthread_active twice on the main code path. */ 137169689Skan int __gthread_active_latest_value = __gthread_active; 138169689Skan 139169689Skan /* This test is not protected to avoid taking a lock on the main code 140169689Skan path so every update of __gthread_active in a threaded program must 141169689Skan be atomic with regard to the result of the test. */ 142169689Skan if (__builtin_expect (__gthread_active_latest_value < 0, 0)) 143169689Skan { 144169689Skan if (__gthrw_(pthread_once)) 145169689Skan { 146169689Skan /* If this really is a threaded program, then we must ensure that 147169689Skan __gthread_active has been set to 1 before exiting this block. */ 148169689Skan __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); 149169689Skan __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); 150169689Skan __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); 151169689Skan } 152169689Skan 153169689Skan /* Make sure we'll never enter this block again. */ 154169689Skan if (__gthread_active < 0) 155169689Skan __gthread_active = 0; 156169689Skan 157169689Skan __gthread_active_latest_value = __gthread_active; 158169689Skan } 159169689Skan 160169689Skan return __gthread_active_latest_value != 0; 161169689Skan} 162169689Skan 163169689Skan#else /* not Solaris */ 164169689Skan 165169689Skanstatic inline int 166169689Skan__gthread_active_p (void) 167169689Skan{ 168169689Skan static void *const __gthread_active_ptr 169169689Skan = __extension__ (void *) &__gthrw_(pthread_cancel); 170169689Skan return __gthread_active_ptr != 0; 171169689Skan} 172169689Skan 173169689Skan#endif /* Solaris */ 174169689Skan 175169689Skan#else /* not SUPPORTS_WEAK */ 176169689Skan 177169689Skanstatic inline int 178169689Skan__gthread_active_p (void) 179169689Skan{ 180169689Skan return 1; 181169689Skan} 182169689Skan 183169689Skan#endif /* SUPPORTS_WEAK */ 184169689Skan 185169689Skan#ifdef _LIBOBJC 186169689Skan 187169689Skan/* This is the config.h file in libobjc/ */ 188169689Skan#include <config.h> 189169689Skan 190169689Skan#ifdef HAVE_SCHED_H 191169689Skan# include <sched.h> 192169689Skan#endif 193169689Skan 194169689Skan/* Key structure for maintaining thread specific storage */ 195169689Skanstatic pthread_key_t _objc_thread_storage; 196169689Skanstatic pthread_attr_t _objc_thread_attribs; 197169689Skan 198169689Skan/* Thread local storage for a single thread */ 199169689Skanstatic void *thread_local_storage = NULL; 200169689Skan 201169689Skan/* Backend initialization functions */ 202169689Skan 203169689Skan/* Initialize the threads subsystem. */ 204169689Skanstatic inline int 205169689Skan__gthread_objc_init_thread_system (void) 206169689Skan{ 207169689Skan if (__gthread_active_p ()) 208169689Skan { 209169689Skan /* Initialize the thread storage key. */ 210169689Skan if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) 211169689Skan { 212169689Skan /* The normal default detach state for threads is 213169689Skan * PTHREAD_CREATE_JOINABLE which causes threads to not die 214169689Skan * when you think they should. */ 215169689Skan if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 216169689Skan && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, 217169689Skan PTHREAD_CREATE_DETACHED) == 0) 218169689Skan return 0; 219169689Skan } 220169689Skan } 221169689Skan 222169689Skan return -1; 223169689Skan} 224169689Skan 225169689Skan/* Close the threads subsystem. */ 226169689Skanstatic inline int 227169689Skan__gthread_objc_close_thread_system (void) 228169689Skan{ 229169689Skan if (__gthread_active_p () 230169689Skan && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 231169689Skan && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) 232169689Skan return 0; 233169689Skan 234169689Skan return -1; 235169689Skan} 236169689Skan 237169689Skan/* Backend thread functions */ 238169689Skan 239169689Skan/* Create a new thread of execution. */ 240169689Skanstatic inline objc_thread_t 241169689Skan__gthread_objc_thread_detach (void (*func)(void *), void *arg) 242169689Skan{ 243169689Skan objc_thread_t thread_id; 244169689Skan pthread_t new_thread_handle; 245169689Skan 246169689Skan if (!__gthread_active_p ()) 247169689Skan return NULL; 248169689Skan 249169689Skan if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg))) 250169689Skan thread_id = (objc_thread_t) new_thread_handle; 251169689Skan else 252169689Skan thread_id = NULL; 253169689Skan 254169689Skan return thread_id; 255169689Skan} 256169689Skan 257169689Skan/* Set the current thread's priority. */ 258169689Skanstatic inline int 259169689Skan__gthread_objc_thread_set_priority (int priority) 260169689Skan{ 261169689Skan if (!__gthread_active_p ()) 262169689Skan return -1; 263169689Skan else 264169689Skan { 265169689Skan#ifdef _POSIX_PRIORITY_SCHEDULING 266169689Skan#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 267169689Skan pthread_t thread_id = __gthrw_(pthread_self) (); 268169689Skan int policy; 269169689Skan struct sched_param params; 270169689Skan int priority_min, priority_max; 271169689Skan 272169689Skan if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) 273169689Skan { 274169689Skan if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) 275169689Skan return -1; 276169689Skan 277169689Skan if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) 278169689Skan return -1; 279169689Skan 280169689Skan if (priority > priority_max) 281169689Skan priority = priority_max; 282169689Skan else if (priority < priority_min) 283169689Skan priority = priority_min; 284169689Skan params.sched_priority = priority; 285169689Skan 286169689Skan /* 287169689Skan * The solaris 7 and several other man pages incorrectly state that 288169689Skan * this should be a pointer to policy but pthread.h is universally 289169689Skan * at odds with this. 290169689Skan */ 291169689Skan if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) 292169689Skan return 0; 293169689Skan } 294169689Skan#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 295169689Skan#endif /* _POSIX_PRIORITY_SCHEDULING */ 296169689Skan return -1; 297169689Skan } 298169689Skan} 299169689Skan 300169689Skan/* Return the current thread's priority. */ 301169689Skanstatic inline int 302169689Skan__gthread_objc_thread_get_priority (void) 303169689Skan{ 304169689Skan#ifdef _POSIX_PRIORITY_SCHEDULING 305169689Skan#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 306169689Skan if (__gthread_active_p ()) 307169689Skan { 308169689Skan int policy; 309169689Skan struct sched_param params; 310169689Skan 311169689Skan if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) 312169689Skan return params.sched_priority; 313169689Skan else 314169689Skan return -1; 315169689Skan } 316169689Skan else 317169689Skan#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 318169689Skan#endif /* _POSIX_PRIORITY_SCHEDULING */ 319169689Skan return OBJC_THREAD_INTERACTIVE_PRIORITY; 320169689Skan} 321169689Skan 322169689Skan/* Yield our process time to another thread. */ 323169689Skanstatic inline void 324169689Skan__gthread_objc_thread_yield (void) 325169689Skan{ 326169689Skan if (__gthread_active_p ()) 327169689Skan __gthrw_(sched_yield) (); 328169689Skan} 329169689Skan 330169689Skan/* Terminate the current thread. */ 331169689Skanstatic inline int 332169689Skan__gthread_objc_thread_exit (void) 333169689Skan{ 334169689Skan if (__gthread_active_p ()) 335169689Skan /* exit the thread */ 336169689Skan __gthrw_(pthread_exit) (&__objc_thread_exit_status); 337169689Skan 338169689Skan /* Failed if we reached here */ 339169689Skan return -1; 340169689Skan} 341169689Skan 342169689Skan/* Returns an integer value which uniquely describes a thread. */ 343169689Skanstatic inline objc_thread_t 344169689Skan__gthread_objc_thread_id (void) 345169689Skan{ 346169689Skan if (__gthread_active_p ()) 347169689Skan return (objc_thread_t) __gthrw_(pthread_self) (); 348169689Skan else 349169689Skan return (objc_thread_t) 1; 350169689Skan} 351169689Skan 352169689Skan/* Sets the thread's local storage pointer. */ 353169689Skanstatic inline int 354169689Skan__gthread_objc_thread_set_data (void *value) 355169689Skan{ 356169689Skan if (__gthread_active_p ()) 357169689Skan return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); 358169689Skan else 359169689Skan { 360169689Skan thread_local_storage = value; 361169689Skan return 0; 362169689Skan } 363169689Skan} 364169689Skan 365169689Skan/* Returns the thread's local storage pointer. */ 366169689Skanstatic inline void * 367169689Skan__gthread_objc_thread_get_data (void) 368169689Skan{ 369169689Skan if (__gthread_active_p ()) 370169689Skan return __gthrw_(pthread_getspecific) (_objc_thread_storage); 371169689Skan else 372169689Skan return thread_local_storage; 373169689Skan} 374169689Skan 375169689Skan/* Backend mutex functions */ 376169689Skan 377169689Skan/* Allocate a mutex. */ 378169689Skanstatic inline int 379169689Skan__gthread_objc_mutex_allocate (objc_mutex_t mutex) 380169689Skan{ 381169689Skan if (__gthread_active_p ()) 382169689Skan { 383169689Skan mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); 384169689Skan 385169689Skan if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) 386169689Skan { 387169689Skan objc_free (mutex->backend); 388169689Skan mutex->backend = NULL; 389169689Skan return -1; 390169689Skan } 391169689Skan } 392169689Skan 393169689Skan return 0; 394169689Skan} 395169689Skan 396169689Skan/* Deallocate a mutex. */ 397169689Skanstatic inline int 398169689Skan__gthread_objc_mutex_deallocate (objc_mutex_t mutex) 399169689Skan{ 400169689Skan if (__gthread_active_p ()) 401169689Skan { 402169689Skan int count; 403169689Skan 404169689Skan /* 405169689Skan * Posix Threads specifically require that the thread be unlocked 406169689Skan * for __gthrw_(pthread_mutex_destroy) to work. 407169689Skan */ 408169689Skan 409169689Skan do 410169689Skan { 411169689Skan count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); 412169689Skan if (count < 0) 413169689Skan return -1; 414169689Skan } 415169689Skan while (count); 416169689Skan 417169689Skan if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) 418169689Skan return -1; 419169689Skan 420169689Skan objc_free (mutex->backend); 421169689Skan mutex->backend = NULL; 422169689Skan } 423169689Skan return 0; 424169689Skan} 425169689Skan 426169689Skan/* Grab a lock on a mutex. */ 427169689Skanstatic inline int 428169689Skan__gthread_objc_mutex_lock (objc_mutex_t mutex) 429169689Skan{ 430169689Skan if (__gthread_active_p () 431169689Skan && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) 432169689Skan { 433169689Skan return -1; 434169689Skan } 435169689Skan 436169689Skan return 0; 437169689Skan} 438169689Skan 439169689Skan/* Try to grab a lock on a mutex. */ 440169689Skanstatic inline int 441169689Skan__gthread_objc_mutex_trylock (objc_mutex_t mutex) 442169689Skan{ 443169689Skan if (__gthread_active_p () 444169689Skan && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) 445169689Skan { 446169689Skan return -1; 447169689Skan } 448169689Skan 449169689Skan return 0; 450169689Skan} 451169689Skan 452169689Skan/* Unlock the mutex */ 453169689Skanstatic inline int 454169689Skan__gthread_objc_mutex_unlock (objc_mutex_t mutex) 455169689Skan{ 456169689Skan if (__gthread_active_p () 457169689Skan && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) 458169689Skan { 459169689Skan return -1; 460169689Skan } 461169689Skan 462169689Skan return 0; 463169689Skan} 464169689Skan 465169689Skan/* Backend condition mutex functions */ 466169689Skan 467169689Skan/* Allocate a condition. */ 468169689Skanstatic inline int 469169689Skan__gthread_objc_condition_allocate (objc_condition_t condition) 470169689Skan{ 471169689Skan if (__gthread_active_p ()) 472169689Skan { 473169689Skan condition->backend = objc_malloc (sizeof (pthread_cond_t)); 474169689Skan 475169689Skan if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) 476169689Skan { 477169689Skan objc_free (condition->backend); 478169689Skan condition->backend = NULL; 479169689Skan return -1; 480169689Skan } 481169689Skan } 482169689Skan 483169689Skan return 0; 484169689Skan} 485169689Skan 486169689Skan/* Deallocate a condition. */ 487169689Skanstatic inline int 488169689Skan__gthread_objc_condition_deallocate (objc_condition_t condition) 489169689Skan{ 490169689Skan if (__gthread_active_p ()) 491169689Skan { 492169689Skan if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) 493169689Skan return -1; 494169689Skan 495169689Skan objc_free (condition->backend); 496169689Skan condition->backend = NULL; 497169689Skan } 498169689Skan return 0; 499169689Skan} 500169689Skan 501169689Skan/* Wait on the condition */ 502169689Skanstatic inline int 503169689Skan__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) 504169689Skan{ 505169689Skan if (__gthread_active_p ()) 506169689Skan return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, 507169689Skan (pthread_mutex_t *) mutex->backend); 508169689Skan else 509169689Skan return 0; 510169689Skan} 511169689Skan 512169689Skan/* Wake up all threads waiting on this condition. */ 513169689Skanstatic inline int 514169689Skan__gthread_objc_condition_broadcast (objc_condition_t condition) 515169689Skan{ 516169689Skan if (__gthread_active_p ()) 517169689Skan return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); 518169689Skan else 519169689Skan return 0; 520169689Skan} 521169689Skan 522169689Skan/* Wake up one thread waiting on this condition. */ 523169689Skanstatic inline int 524169689Skan__gthread_objc_condition_signal (objc_condition_t condition) 525169689Skan{ 526169689Skan if (__gthread_active_p ()) 527169689Skan return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); 528169689Skan else 529169689Skan return 0; 530169689Skan} 531169689Skan 532169689Skan#else /* _LIBOBJC */ 533169689Skan 534169689Skanstatic inline int 535169689Skan__gthread_once (__gthread_once_t *once, void (*func) (void)) 536169689Skan{ 537169689Skan if (__gthread_active_p ()) 538169689Skan return __gthrw_(pthread_once) (once, func); 539169689Skan else 540169689Skan return -1; 541169689Skan} 542169689Skan 543169689Skanstatic inline int 544169689Skan__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) 545169689Skan{ 546169689Skan return __gthrw_(pthread_key_create) (key, dtor); 547169689Skan} 548169689Skan 549169689Skanstatic inline int 550169689Skan__gthread_key_delete (__gthread_key_t key) 551169689Skan{ 552169689Skan return __gthrw_(pthread_key_delete) (key); 553169689Skan} 554169689Skan 555169689Skanstatic inline void * 556169689Skan__gthread_getspecific (__gthread_key_t key) 557169689Skan{ 558169689Skan return __gthrw_(pthread_getspecific) (key); 559169689Skan} 560169689Skan 561169689Skanstatic inline int 562169689Skan__gthread_setspecific (__gthread_key_t key, const void *ptr) 563169689Skan{ 564169689Skan return __gthrw_(pthread_setspecific) (key, ptr); 565169689Skan} 566169689Skan 567169689Skanstatic inline int 568169689Skan__gthread_mutex_lock (__gthread_mutex_t *mutex) 569169689Skan{ 570169689Skan if (__gthread_active_p ()) 571169689Skan return __gthrw_(pthread_mutex_lock) (mutex); 572169689Skan else 573169689Skan return 0; 574169689Skan} 575169689Skan 576169689Skanstatic inline int 577169689Skan__gthread_mutex_trylock (__gthread_mutex_t *mutex) 578169689Skan{ 579169689Skan if (__gthread_active_p ()) 580169689Skan return __gthrw_(pthread_mutex_trylock) (mutex); 581169689Skan else 582169689Skan return 0; 583169689Skan} 584169689Skan 585169689Skanstatic inline int 586169689Skan__gthread_mutex_unlock (__gthread_mutex_t *mutex) 587169689Skan{ 588169689Skan if (__gthread_active_p ()) 589169689Skan return __gthrw_(pthread_mutex_unlock) (mutex); 590169689Skan else 591169689Skan return 0; 592169689Skan} 593169689Skan 594169689Skanstatic inline int 595169689Skan__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) 596169689Skan{ 597169689Skan mutex->depth = 0; 598169689Skan mutex->owner = (pthread_t) 0; 599169689Skan return __gthrw_(pthread_mutex_init) (&mutex->actual, NULL); 600169689Skan} 601169689Skan 602169689Skanstatic inline int 603169689Skan__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) 604169689Skan{ 605169689Skan if (__gthread_active_p ()) 606169689Skan { 607169689Skan pthread_t me = __gthrw_(pthread_self) (); 608169689Skan 609169689Skan if (mutex->owner != me) 610169689Skan { 611169689Skan __gthrw_(pthread_mutex_lock) (&mutex->actual); 612169689Skan mutex->owner = me; 613169689Skan } 614169689Skan 615169689Skan mutex->depth++; 616169689Skan } 617169689Skan return 0; 618169689Skan} 619169689Skan 620169689Skanstatic inline int 621169689Skan__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) 622169689Skan{ 623169689Skan if (__gthread_active_p ()) 624169689Skan { 625169689Skan pthread_t me = __gthrw_(pthread_self) (); 626169689Skan 627169689Skan if (mutex->owner != me) 628169689Skan { 629169689Skan if (__gthrw_(pthread_mutex_trylock) (&mutex->actual)) 630169689Skan return 1; 631169689Skan mutex->owner = me; 632169689Skan } 633169689Skan 634169689Skan mutex->depth++; 635169689Skan } 636169689Skan return 0; 637169689Skan} 638169689Skan 639169689Skanstatic inline int 640169689Skan__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) 641169689Skan{ 642169689Skan if (__gthread_active_p ()) 643169689Skan { 644169689Skan if (--mutex->depth == 0) 645169689Skan { 646169689Skan mutex->owner = (pthread_t) 0; 647169689Skan __gthrw_(pthread_mutex_unlock) (&mutex->actual); 648169689Skan } 649169689Skan } 650169689Skan return 0; 651169689Skan} 652169689Skan 653169689Skan#endif /* _LIBOBJC */ 654169689Skan 655169689Skan#endif /* ! GCC_GTHR_POSIX_H */ 656