# gthr-posix.h

    00001 /* Threads compatibility routines for libgcc2 and libobjc.  */
    00002 /* Compile this one with gcc.  */
    00003 /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    00004    Free Software Foundation, Inc.
    00005
    00006 This file is part of GCC.
    00007
    00008 GCC is free software; you can redistribute it and/or modify it under
    00009 the terms of the GNU General Public License as published by the Free
    00010 Software Foundation; either version 2, or (at your option) any later
    00011 version.
    00012
    00013 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
    00014 WARRANTY; without even the implied warranty of MERCHANTABILITY or
    00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    00016 for more details.
    00017
    00018 You should have received a copy of the GNU General Public License
    00019 along with GCC; see the file COPYING.  If not, write to the Free
    00020 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    00021 02110-1301, USA.  */
    00022
    00023 /* As a special exception, if you link this library with other files,
    00024    some of which are compiled with GCC, to produce an executable,
    00025    this library does not by itself cause the resulting executable
    00026    to be covered by the GNU General Public License.
    00027    This exception does not however invalidate any other reasons why
    00028    the executable file might be covered by the GNU General Public License.  */
    00029
    00030 #ifndef _GLIBCXX_GCC_GTHR_POSIX_H
    00031 #define _GLIBCXX_GCC_GTHR_POSIX_H
    00032
    00033 /* POSIX threads specific definitions.
    00034    Easy, since the interface is just one-to-one mapping.  */
    00035
    00036 #define __GTHREADS 1
    00037
    00038 /* Some implementations of <pthread.h> require this to be defined.  */
    00039 #if !defined(_REENTRANT) && defined(__osf__)
    00040 #define _REENTRANT 1
    00041 #endif
    00042
    00043 #include <pthread.h>
    00044 #include <unistd.h>
    00045
    00046 typedef pthread_key_t __gthread_key_t;
    00047 typedef pthread_once_t __gthread_once_t;
    00048 typedef pthread_mutex_t __gthread_mutex_t;
    00049 typedef pthread_mutex_t __gthread_recursive_mutex_t;
    00050
    00051 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
    00052 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
    00053 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
    00054 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
    00055 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
    00056 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
    00057 #else
    00058 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
    00059 #endif
    00060
    00061 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
    00062 # ifndef __gthrw_pragma
    00063 #  define __gthrw_pragma(pragma)
    00064 # endif
    00065 # define __gthrw2(name,name2,type) \
    00066   static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
    00067   __gthrw_pragma(weak type)
    00068 # define __gthrw_(name) __gthrw_ ## name
    00069 #else
    00070 # define __gthrw2(name,name2,type)
    00071 # define __gthrw_(name) name
    00072 #endif
    00073
    00074 /* Typically, __gthrw_foo is a weak reference to symbol foo.  */
    00075 #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
    00076
    00077 /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
    00078    map a subset of the POSIX pthread API to mangled versions of their
    00079    names.  */
    00080 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
    00081 #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
    00082 __gthrw3(pthread_once)
    00083 __gthrw3(pthread_getspecific)
    00084 __gthrw3(pthread_setspecific)
    00085 __gthrw3(pthread_create)
    00086 __gthrw3(pthread_cancel)
    00087 __gthrw3(pthread_mutex_lock)
    00088 __gthrw3(pthread_mutex_trylock)
    00089 __gthrw3(pthread_mutex_unlock)
    00090 __gthrw3(pthread_mutex_init)
    00091 #else
    00092 __gthrw(pthread_once)
    00093 __gthrw(pthread_getspecific)
    00094 __gthrw(pthread_setspecific)
    00095 __gthrw(pthread_create)
    00096 __gthrw(pthread_cancel)
    00097 __gthrw(pthread_mutex_lock)
    00098 __gthrw(pthread_mutex_trylock)
    00099 __gthrw(pthread_mutex_unlock)
    00100 __gthrw(pthread_mutex_init)
    00101 #endif
    00102
    00103 __gthrw(pthread_key_create)
    00104 __gthrw(pthread_key_delete)
    00105 __gthrw(pthread_mutexattr_init)
    00106 __gthrw(pthread_mutexattr_settype)
    00107 __gthrw(pthread_mutexattr_destroy)
    00108
    00109
    00110 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
    00111 /* Objective-C.  */
    00112 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
    00113 __gthrw3(pthread_cond_broadcast)
    00114 __gthrw3(pthread_cond_destroy)
    00115 __gthrw3(pthread_cond_init)
    00116 __gthrw3(pthread_cond_signal)
    00117 __gthrw3(pthread_cond_wait)
    00118 __gthrw3(pthread_exit)
    00119 __gthrw3(pthread_mutex_destroy)
    00120 __gthrw3(pthread_self)
    00121 #else
    00122 __gthrw(pthread_cond_broadcast)
    00123 __gthrw(pthread_cond_destroy)
    00124 __gthrw(pthread_cond_init)
    00125 __gthrw(pthread_cond_signal)
    00126 __gthrw(pthread_cond_wait)
    00127 __gthrw(pthread_exit)
    00128 __gthrw(pthread_mutex_destroy)
    00129 __gthrw(pthread_self)
    00130 #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
    00131 #ifdef _POSIX_PRIORITY_SCHEDULING
    00132 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00133 __gthrw(sched_get_priority_max)
    00134 __gthrw(sched_get_priority_min)
    00135 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00136 #endif /* _POSIX_PRIORITY_SCHEDULING */
    00137 __gthrw(sched_yield)
    00138 __gthrw(pthread_attr_destroy)
    00139 __gthrw(pthread_attr_init)
    00140 __gthrw(pthread_attr_setdetachstate)
    00141 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00142 __gthrw(pthread_getschedparam)
    00143 __gthrw(pthread_setschedparam)
    00144 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00145 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
    00146
    00147 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
    00148
    00149 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
    00150    -pthreads is not specified.  The functions are dummies and most return an
    00151    error value.  However pthread_once returns 0 without invoking the routine
    00152    it is passed so we cannot pretend that the interface is active if -pthreads
    00153    is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
    00154    we need to play the usual game with weak symbols.  On Solaris 10 and up, a
    00155    working interface is always exposed.  */
    00156
    00157 #if defined(__sun) && defined(__svr4__)
    00158
    00159 static volatile int __gthread_active = -1;
    00160
    00161 static void
    00162 __gthread_trigger (void)
    00163 {
    00164   __gthread_active = 1;
    00165 }
    00166
    00167 static inline int
    00168 __gthread_active_p (void)
    00169 {
    00170   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
    00171   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
    00172
    00173   /* Avoid reading __gthread_active twice on the main code path.  */
    00174   int __gthread_active_latest_value = __gthread_active;
    00175
    00176   /* This test is not protected to avoid taking a lock on the main code
    00177      path so every update of __gthread_active in a threaded program must
    00178      be atomic with regard to the result of the test.  */
    00179   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
    00180     {
    00181       if (__gthrw_(pthread_once))
    00182     {
    00183       /* If this really is a threaded program, then we must ensure that
    00184          __gthread_active has been set to 1 before exiting this block.  */
    00185       __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
    00186       __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
    00187       __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
    00188     }
    00189
    00190       /* Make sure we'll never enter this block again.  */
    00191       if (__gthread_active < 0)
    00192     __gthread_active = 0;
    00193
    00194       __gthread_active_latest_value = __gthread_active;
    00195     }
    00196
    00197   return __gthread_active_latest_value != 0;
    00198 }
    00199
    00200 #else /* not Solaris */
    00201
    00202 static inline int
    00203 __gthread_active_p (void)
    00204 {
    00205   static void *const __gthread_active_ptr
    00206     = __extension__ (void *) &__gthrw_(pthread_cancel);
    00207   return __gthread_active_ptr != 0;
    00208 }
    00209
    00210 #endif /* Solaris */
    00211
    00212 #else /* not __GXX_WEAK__ */
    00213
    00214 static inline int
    00215 __gthread_active_p (void)
    00216 {
    00217   return 1;
    00218 }
    00219
    00220 #endif /* __GXX_WEAK__ */
    00221
    00222 #ifdef _LIBOBJC
    00223
    00224 /* This is the config.h file in libobjc/ */
    00225 #include <config.h>
    00226
    00227 #ifdef HAVE_SCHED_H
    00228 # include <sched.h>
    00229 #endif
    00230
    00231 /* Key structure for maintaining thread specific storage */
    00232 static pthread_key_t _objc_thread_storage;
    00233 static pthread_attr_t _objc_thread_attribs;
    00234
    00235 /* Thread local storage for a single thread */
    00236 static void *thread_local_storage = NULL;
    00237
    00238 /* Backend initialization functions */
    00239
    00240 /* Initialize the threads subsystem.  */
    00241 static inline int
    00242 __gthread_objc_init_thread_system (void)
    00243 {
    00244   if (__gthread_active_p ())
    00245     {
    00246       /* Initialize the thread storage key.  */
    00247       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
    00248     {
    00249       /* The normal default detach state for threads is
    00250        * PTHREAD_CREATE_JOINABLE which causes threads to not die
    00251        * when you think they should.  */
    00252       if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
    00253           && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
    00254                           PTHREAD_CREATE_DETACHED) == 0)
    00255         return 0;
    00256     }
    00257     }
    00258
    00259   return -1;
    00260 }
    00261
    00262 /* Close the threads subsystem.  */
    00263 static inline int
    00264 __gthread_objc_close_thread_system (void)
    00265 {
    00266   if (__gthread_active_p ()
    00267       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
    00268       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
    00269     return 0;
    00270
    00271   return -1;
    00272 }
    00273
    00274 /* Backend thread functions */
    00275
    00276 /* Create a new thread of execution.  */
    00277 static inline objc_thread_t
    00278 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
    00279 {
    00280   objc_thread_t thread_id;
    00281   pthread_t new_thread_handle;
    00282
    00283   if (!__gthread_active_p ())
    00284     return NULL;
    00285
    00286   if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
    00287     thread_id = (objc_thread_t) new_thread_handle;
    00288   else
    00289     thread_id = NULL;
    00290
    00291   return thread_id;
    00292 }
    00293
    00294 /* Set the current thread's priority.  */
    00295 static inline int
    00296 __gthread_objc_thread_set_priority (int priority)
    00297 {
    00298   if (!__gthread_active_p ())
    00299     return -1;
    00300   else
    00301     {
    00302 #ifdef _POSIX_PRIORITY_SCHEDULING
    00303 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00304       pthread_t thread_id = __gthrw_(pthread_self) ();
    00305       int policy;
    00306       struct sched_param params;
    00307       int priority_min, priority_max;
    00308
    00309       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
    00310     {
    00311       if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
    00312         return -1;
    00313
    00314       if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
    00315         return -1;
    00316
    00317       if (priority > priority_max)
    00318         priority = priority_max;
    00319       else if (priority < priority_min)
    00320         priority = priority_min;
    00321       params.sched_priority = priority;
    00322
    00323       /*
    00324        * The solaris 7 and several other man pages incorrectly state that
    00325        * this should be a pointer to policy but pthread.h is universally
    00326        * at odds with this.
    00327        */
    00328       if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
    00329         return 0;
    00330     }
    00331 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00332 #endif /* _POSIX_PRIORITY_SCHEDULING */
    00333       return -1;
    00334     }
    00335 }
    00336
    00337 /* Return the current thread's priority.  */
    00338 static inline int
    00339 __gthread_objc_thread_get_priority (void)
    00340 {
    00341 #ifdef _POSIX_PRIORITY_SCHEDULING
    00342 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    00343   if (__gthread_active_p ())
    00344     {
    00345       int policy;
    00346       struct sched_param params;
    00347
    00348       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
    00349     return params.sched_priority;
    00350       else
    00351     return -1;
    00352     }
    00353   else
    00354 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    00355 #endif /* _POSIX_PRIORITY_SCHEDULING */
    00356     return OBJC_THREAD_INTERACTIVE_PRIORITY;
    00357 }
    00358
    00359 /* Yield our process time to another thread.  */
    00360 static inline void
    00361 __gthread_objc_thread_yield (void)
    00362 {
    00363   if (__gthread_active_p ())
    00364     __gthrw_(sched_yield) ();
    00365 }
    00366
    00367 /* Terminate the current thread.  */
    00368 static inline int
    00369 __gthread_objc_thread_exit (void)
    00370 {
    00371   if (__gthread_active_p ())
    00372     /* exit the thread */
    00373     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
    00374
    00375   /* Failed if we reached here */
    00376   return -1;
    00377 }
    00378
    00379 /* Returns an integer value which uniquely describes a thread.  */
    00380 static inline objc_thread_t
    00381 __gthread_objc_thread_id (void)
    00382 {
    00383   if (__gthread_active_p ())
    00384     return (objc_thread_t) __gthrw_(pthread_self) ();
    00385   else
    00386     return (objc_thread_t) 1;
    00387 }
    00388
    00389 /* Sets the thread's local storage pointer.  */
    00390 static inline int
    00391 __gthread_objc_thread_set_data (void *value)
    00392 {
    00393   if (__gthread_active_p ())
    00394     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
    00395   else
    00396     {
    00397       thread_local_storage = value;
    00398       return 0;
    00399     }
    00400 }
    00401
    00402 /* Returns the thread's local storage pointer.  */
    00403 static inline void *
    00404 __gthread_objc_thread_get_data (void)
    00405 {
    00406   if (__gthread_active_p ())
    00407     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
    00408   else
    00409     return thread_local_storage;
    00410 }
    00411
    00412 /* Backend mutex functions */
    00413
    00414 /* Allocate a mutex.  */
    00415 static inline int
    00416 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
    00417 {
    00418   if (__gthread_active_p ())
    00419     {
    00420       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
    00421
    00422       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
    00423     {
    00424       objc_free (mutex->backend);
    00425       mutex->backend = NULL;
    00426       return -1;
    00427     }
    00428     }
    00429
    00430   return 0;
    00431 }
    00432
    00433 /* Deallocate a mutex.  */
    00434 static inline int
    00435 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
    00436 {
    00437   if (__gthread_active_p ())
    00438     {
    00439       int count;
    00440
    00441       /*
    00442        * Posix Threads specifically require that the thread be unlocked
    00443        * for __gthrw_(pthread_mutex_destroy) to work.
    00444        */
    00445
    00446       do
    00447     {
    00448       count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
    00449       if (count < 0)
    00450         return -1;
    00451     }
    00452       while (count);
    00453
    00454       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
    00455     return -1;
    00456
    00457       objc_free (mutex->backend);
    00458       mutex->backend = NULL;
    00459     }
    00460   return 0;
    00461 }
    00462
    00463 /* Grab a lock on a mutex.  */
    00464 static inline int
    00465 __gthread_objc_mutex_lock (objc_mutex_t mutex)
    00466 {
    00467   if (__gthread_active_p ()
    00468       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
    00469     {
    00470       return -1;
    00471     }
    00472
    00473   return 0;
    00474 }
    00475
    00476 /* Try to grab a lock on a mutex.  */
    00477 static inline int
    00478 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
    00479 {
    00480   if (__gthread_active_p ()
    00481       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
    00482     {
    00483       return -1;
    00484     }
    00485
    00486   return 0;
    00487 }
    00488
    00489 /* Unlock the mutex */
    00490 static inline int
    00491 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
    00492 {
    00493   if (__gthread_active_p ()
    00494       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
    00495     {
    00496       return -1;
    00497     }
    00498
    00499   return 0;
    00500 }
    00501
    00502 /* Backend condition mutex functions */
    00503
    00504 /* Allocate a condition.  */
    00505 static inline int
    00506 __gthread_objc_condition_allocate (objc_condition_t condition)
    00507 {
    00508   if (__gthread_active_p ())
    00509     {
    00510       condition->backend = objc_malloc (sizeof (pthread_cond_t));
    00511
    00512       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
    00513     {
    00514       objc_free (condition->backend);
    00515       condition->backend = NULL;
    00516       return -1;
    00517     }
    00518     }
    00519
    00520   return 0;
    00521 }
    00522
    00523 /* Deallocate a condition.  */
    00524 static inline int
    00525 __gthread_objc_condition_deallocate (objc_condition_t condition)
    00526 {
    00527   if (__gthread_active_p ())
    00528     {
    00529       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
    00530     return -1;
    00531
    00532       objc_free (condition->backend);
    00533       condition->backend = NULL;
    00534     }
    00535   return 0;
    00536 }
    00537
    00538 /* Wait on the condition */
    00539 static inline int
    00540 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
    00541 {
    00542   if (__gthread_active_p ())
    00543     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
    00544                   (pthread_mutex_t *) mutex->backend);
    00545   else
    00546     return 0;
    00547 }
    00548
    00549 /* Wake up all threads waiting on this condition.  */
    00550 static inline int
    00551 __gthread_objc_condition_broadcast (objc_condition_t condition)
    00552 {
    00553   if (__gthread_active_p ())
    00554     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
    00555   else
    00556     return 0;
    00557 }
    00558
    00559 /* Wake up one thread waiting on this condition.  */
    00560 static inline int
    00561 __gthread_objc_condition_signal (objc_condition_t condition)
    00562 {
    00563   if (__gthread_active_p ())
    00564     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
    00565   else
    00566     return 0;
    00567 }
    00568
    00569 #else /* _LIBOBJC */
    00570
    00571 static inline int
    00572 __gthread_once (__gthread_once_t *once, void (*func) (void))
    00573 {
    00574   if (__gthread_active_p ())
    00575     return __gthrw_(pthread_once) (once, func);
    00576   else
    00577     return -1;
    00578 }
    00579
    00580 static inline int
    00581 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
    00582 {
    00583   return __gthrw_(pthread_key_create) (key, dtor);
    00584 }
    00585
    00586 static inline int
    00587 __gthread_key_delete (__gthread_key_t key)
    00588 {
    00589   return __gthrw_(pthread_key_delete) (key);
    00590 }
    00591
    00592 static inline void *
    00593 __gthread_getspecific (__gthread_key_t key)
    00594 {
    00595   return __gthrw_(pthread_getspecific) (key);
    00596 }
    00597
    00598 static inline int
    00599 __gthread_setspecific (__gthread_key_t key, const void *ptr)
    00600 {
    00601   return __gthrw_(pthread_setspecific) (key, ptr);
    00602 }
    00603
    00604 static inline int
    00605 __gthread_mutex_lock (__gthread_mutex_t *mutex)
    00606 {
    00607   if (__gthread_active_p ())
    00608     return __gthrw_(pthread_mutex_lock) (mutex);
    00609   else
    00610     return 0;
    00611 }
    00612
    00613 static inline int
    00614 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
    00615 {
    00616   if (__gthread_active_p ())
    00617     return __gthrw_(pthread_mutex_trylock) (mutex);
    00618   else
    00619     return 0;
    00620 }
    00621
    00622 static inline int
    00623 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
    00624 {
    00625   if (__gthread_active_p ())
    00626     return __gthrw_(pthread_mutex_unlock) (mutex);
    00627   else
    00628     return 0;
    00629 }
    00630
    00631 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
    00632 static inline int
    00633 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
    00634 {
    00635   if (__gthread_active_p ())
    00636     {
    00637       pthread_mutexattr_t attr;
    00638       int r;
    00639
    00640       r = __gthrw_(pthread_mutexattr_init) (&attr);
    00641       if (!r)
    00642     r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
    00643       if (!r)
    00644     r = __gthrw_(pthread_mutex_init) (mutex, &attr);
    00645       if (!r)
    00646     r = __gthrw_(pthread_mutexattr_destroy) (&attr);
    00647       return r;
    00648     }
    00649   return 0;
    00650 }
    00651 #endif
    00652
    00653 static inline int
    00654 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
    00655 {
    00656   return __gthread_mutex_lock (mutex);
    00657 }
    00658
    00659 static inline int
    00660 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
    00661 {
    00662   return __gthread_mutex_trylock (mutex);
    00663 }
    00664
    00665 static inline int
    00666 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
    00667 {
    00668   return __gthread_mutex_unlock (mutex);
    00669 }
    00670
    00671 #endif /* _LIBOBJC */
    00672
    00673 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */