OSDN Git Service

* config/darwin-driver.c (darwin_default_min_version): Fix
[pf3gnuchains/gcc-fork.git] / gcc / gthr-posix95.h
1 /* Threads compatibility routines for libgcc2 and libobjc.  */
2 /* Compile this one with gcc.  */
3 /* Copyright (C) 2004, 2005, 2007 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 2, 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 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.  */
21
22 /* As a special exception, if you link this library with other files,
23    some of which are compiled with GCC, to produce an executable,
24    this library does not by itself cause the resulting executable
25    to be covered by the GNU General Public License.
26    This exception does not however invalidate any other reasons why
27    the executable file might be covered by the GNU General Public License.  */
28
29 #ifndef GCC_GTHR_POSIX_H
30 #define GCC_GTHR_POSIX_H
31
32 /* POSIX threads specific definitions.
33    Easy, since the interface is just one-to-one mapping.  */
34
35 #define __GTHREADS 1
36
37 /* Some implementations of <pthread.h> require this to be defined.  */
38 #ifndef _REENTRANT
39 #define _REENTRANT 1
40 #endif
41
42 #include <pthread.h>
43 #include <unistd.h>
44
45 typedef pthread_key_t __gthread_key_t;
46 typedef pthread_once_t __gthread_once_t;
47 typedef pthread_mutex_t __gthread_mutex_t;
48 typedef pthread_cond_t __gthread_cond_t;
49
50 /* POSIX like conditional variables are supported.  Please look at comments
51    in gthr.h for details. */
52 #define __GTHREAD_HAS_COND      1
53
54 typedef struct {
55   long depth;
56   pthread_t owner;
57   pthread_mutex_t actual;
58 } __gthread_recursive_mutex_t;
59
60 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
61 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
62 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
63 #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
64
65 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
66 # define __gthrw(name) \
67   static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
68 # define __gthrw_(name) __gthrw_ ## name
69 #else
70 # define __gthrw(name)
71 # define __gthrw_(name) name
72 #endif
73
74 __gthrw(pthread_once)
75 __gthrw(pthread_key_create)
76 __gthrw(pthread_key_delete)
77 __gthrw(pthread_getspecific)
78 __gthrw(pthread_setspecific)
79 __gthrw(pthread_create)
80 __gthrw(pthread_cancel)
81 __gthrw(pthread_self)
82
83 __gthrw(pthread_mutex_init)
84 __gthrw(pthread_mutex_destroy)
85 __gthrw(pthread_mutex_lock)
86 __gthrw(pthread_mutex_trylock)
87 __gthrw(pthread_mutex_unlock)
88 __gthrw(pthread_mutexattr_init)
89 __gthrw(pthread_mutexattr_destroy)
90
91 __gthrw(pthread_cond_broadcast)
92 __gthrw(pthread_cond_wait)
93
94 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
95 /* Objective-C.  */
96 __gthrw(pthread_cond_destroy)
97 __gthrw(pthread_cond_init)
98 __gthrw(pthread_cond_signal)
99 __gthrw(pthread_exit)
100 #ifdef _POSIX_PRIORITY_SCHEDULING
101 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
102 __gthrw(sched_get_priority_max)
103 __gthrw(sched_get_priority_min)
104 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
105 #endif /* _POSIX_PRIORITY_SCHEDULING */
106 __gthrw(sched_yield)
107 __gthrw(pthread_attr_destroy)
108 __gthrw(pthread_attr_init)
109 __gthrw(pthread_attr_setdetachstate)
110 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
111 __gthrw(pthread_getschedparam)
112 __gthrw(pthread_setschedparam)
113 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
114 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
115
116 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
117
118 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
119    -pthreads is not specified.  The functions are dummies and most return an
120    error value.  However pthread_once returns 0 without invoking the routine
121    it is passed so we cannot pretend that the interface is active if -pthreads
122    is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
123    we need to play the usual game with weak symbols.  On Solaris 10 and up, a
124    working interface is always exposed.  On FreeBSD 6 and later, libc also
125    exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
126    to 9 does.  FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
127    which means the alternate __gthread_active_p below cannot be used there.  */
128
129 #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
130
131 static volatile int __gthread_active = -1;
132
133 static void
134 __gthread_trigger (void)
135 {
136   __gthread_active = 1;
137 }
138
139 static inline int
140 __gthread_active_p (void)
141 {
142   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
143   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
144
145   /* Avoid reading __gthread_active twice on the main code path.  */
146   int __gthread_active_latest_value = __gthread_active;
147
148   /* This test is not protected to avoid taking a lock on the main code
149      path so every update of __gthread_active in a threaded program must
150      be atomic with regard to the result of the test.  */
151   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
152     {
153       if (__gthrw_(pthread_once))
154         {
155           /* If this really is a threaded program, then we must ensure that
156              __gthread_active has been set to 1 before exiting this block.  */
157           __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
158           __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
159           __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
160         }
161
162       /* Make sure we'll never enter this block again.  */
163       if (__gthread_active < 0)
164         __gthread_active = 0;
165
166       __gthread_active_latest_value = __gthread_active;
167     }
168
169   return __gthread_active_latest_value != 0;
170 }
171
172 #else /* neither FreeBSD nor Solaris */
173
174 static inline int
175 __gthread_active_p (void)
176 {
177   static void *const __gthread_active_ptr 
178     = __extension__ (void *) &__gthrw_(pthread_cancel);
179   return __gthread_active_ptr != 0;
180 }
181
182 #endif /* FreeBSD or Solaris */
183
184 #else /* not SUPPORTS_WEAK */
185
186 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
187    calls in shared flavors of the HP-UX C library.  Most of the stubs
188    have no functionality.  The details are described in the "libc cumulative
189    patch" for each subversion of HP-UX 11.  There are two special interfaces
190    provided for checking whether an application is linked to a pthread
191    library or not.  However, these interfaces aren't available in early
192    libc versions.  We also can't use pthread_once as some libc versions
193    call the init function.  So, we use pthread_create to check whether it
194    is possible to create a thread or not.  The stub implementation returns
195    the error number ENOSYS.  */
196
197 #if defined(__hppa__) && defined(__hpux__)
198
199 #include <errno.h>
200
201 static volatile int __gthread_active = -1;
202
203 static void *
204 __gthread_start (void *arg __attribute__((unused)))
205 {
206   return NULL;
207 }
208
209 static void __gthread_active_init (void) __attribute__((noinline));
210 static void
211 __gthread_active_init (void)
212 {
213   static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
214   pthread_t t;
215   pthread_attr_t a;
216   int result;
217
218   __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
219   if (__gthread_active < 0)
220     {
221       __gthrw_(pthread_attr_init) (&a);
222       __gthrw_(pthread_attr_setdetachstate) (&a, PTHREAD_CREATE_DETACHED);
223       result = __gthrw_(pthread_create) (&t, &a, __gthread_start, NULL);
224       if (result != ENOSYS)
225         __gthread_active = 1;
226       else
227         __gthread_active = 0;
228       __gthrw_(pthread_attr_destroy) (&a);
229     }
230   __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
231 }
232
233 static inline int
234 __gthread_active_p (void)
235 {
236   /* Avoid reading __gthread_active twice on the main code path.  */
237   int __gthread_active_latest_value = __gthread_active;
238
239   /* This test is not protected to avoid taking a lock on the main code
240      path so every update of __gthread_active in a threaded program must
241      be atomic with regard to the result of the test.  */
242   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
243     {
244       __gthread_active_init ();
245       __gthread_active_latest_value = __gthread_active;
246     }
247
248   return __gthread_active_latest_value != 0;
249 }
250
251 #else /* not hppa-hpux */
252
253 static inline int
254 __gthread_active_p (void)
255 {
256   return 1;
257 }
258
259 #endif /* hppa-hpux */
260
261 #endif /* SUPPORTS_WEAK */
262
263 #ifdef _LIBOBJC
264
265 /* This is the config.h file in libobjc/ */
266 #include <config.h>
267
268 #ifdef HAVE_SCHED_H
269 # include <sched.h>
270 #endif
271
272 /* Key structure for maintaining thread specific storage */
273 static pthread_key_t _objc_thread_storage;
274 static pthread_attr_t _objc_thread_attribs;
275
276 /* Thread local storage for a single thread */
277 static void *thread_local_storage = NULL;
278
279 /* Backend initialization functions */
280
281 /* Initialize the threads subsystem.  */
282 static inline int
283 __gthread_objc_init_thread_system (void)
284 {
285   if (__gthread_active_p ())
286     {
287       /* Initialize the thread storage key.  */
288       if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
289         {
290           /* The normal default detach state for threads is
291            * PTHREAD_CREATE_JOINABLE which causes threads to not die
292            * when you think they should.  */
293           if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
294               && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
295                                               PTHREAD_CREATE_DETACHED) == 0)
296             return 0;
297         }
298     }
299
300   return -1;
301 }
302
303 /* Close the threads subsystem.  */
304 static inline int
305 __gthread_objc_close_thread_system (void)
306 {
307   if (__gthread_active_p ()
308       && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
309       && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
310     return 0;
311
312   return -1;
313 }
314
315 /* Backend thread functions */
316
317 /* Create a new thread of execution.  */
318 static inline objc_thread_t
319 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
320 {
321   objc_thread_t thread_id;
322   pthread_t new_thread_handle;
323
324   if (!__gthread_active_p ())
325     return NULL;
326
327   if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
328     thread_id = (objc_thread_t) new_thread_handle;
329   else
330     thread_id = NULL;
331
332   return thread_id;
333 }
334
335 /* Set the current thread's priority.  */
336 static inline int
337 __gthread_objc_thread_set_priority (int priority)
338 {
339   if (!__gthread_active_p ())
340     return -1;
341   else
342     {
343 #ifdef _POSIX_PRIORITY_SCHEDULING
344 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
345       pthread_t thread_id = __gthrw_(pthread_self) ();
346       int policy;
347       struct sched_param params;
348       int priority_min, priority_max;
349
350       if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
351         {
352           if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
353             return -1;
354
355           if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
356             return -1;
357
358           if (priority > priority_max)
359             priority = priority_max;
360           else if (priority < priority_min)
361             priority = priority_min;
362           params.sched_priority = priority;
363
364           /*
365            * The solaris 7 and several other man pages incorrectly state that
366            * this should be a pointer to policy but pthread.h is universally
367            * at odds with this.
368            */
369           if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
370             return 0;
371         }
372 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
373 #endif /* _POSIX_PRIORITY_SCHEDULING */
374       return -1;
375     }
376 }
377
378 /* Return the current thread's priority.  */
379 static inline int
380 __gthread_objc_thread_get_priority (void)
381 {
382 #ifdef _POSIX_PRIORITY_SCHEDULING
383 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
384   if (__gthread_active_p ())
385     {
386       int policy;
387       struct sched_param params;
388
389       if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
390         return params.sched_priority;
391       else
392         return -1;
393     }
394   else
395 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
396 #endif /* _POSIX_PRIORITY_SCHEDULING */
397     return OBJC_THREAD_INTERACTIVE_PRIORITY;
398 }
399
400 /* Yield our process time to another thread.  */
401 static inline void
402 __gthread_objc_thread_yield (void)
403 {
404   if (__gthread_active_p ())
405     __gthrw_(sched_yield) ();
406 }
407
408 /* Terminate the current thread.  */
409 static inline int
410 __gthread_objc_thread_exit (void)
411 {
412   if (__gthread_active_p ())
413     /* exit the thread */
414     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
415
416   /* Failed if we reached here */
417   return -1;
418 }
419
420 /* Returns an integer value which uniquely describes a thread.  */
421 static inline objc_thread_t
422 __gthread_objc_thread_id (void)
423 {
424   if (__gthread_active_p ())
425     return (objc_thread_t) __gthrw_(pthread_self) ();
426   else
427     return (objc_thread_t) 1;
428 }
429
430 /* Sets the thread's local storage pointer.  */
431 static inline int
432 __gthread_objc_thread_set_data (void *value)
433 {
434   if (__gthread_active_p ())
435     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
436   else
437     {
438       thread_local_storage = value;
439       return 0;
440     }
441 }
442
443 /* Returns the thread's local storage pointer.  */
444 static inline void *
445 __gthread_objc_thread_get_data (void)
446 {
447   if (__gthread_active_p ())
448     return __gthrw_(pthread_getspecific) (_objc_thread_storage);
449   else
450     return thread_local_storage;
451 }
452
453 /* Backend mutex functions */
454
455 /* Allocate a mutex.  */
456 static inline int
457 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
458 {
459   if (__gthread_active_p ())
460     {
461       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
462
463       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
464         {
465           objc_free (mutex->backend);
466           mutex->backend = NULL;
467           return -1;
468         }
469     }
470
471   return 0;
472 }
473
474 /* Deallocate a mutex.  */
475 static inline int
476 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
477 {
478   if (__gthread_active_p ())
479     {
480       int count;
481
482       /*
483        * Posix Threads specifically require that the thread be unlocked
484        * for __gthrw_(pthread_mutex_destroy) to work.
485        */
486
487       do
488         {
489           count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
490           if (count < 0)
491             return -1;
492         }
493       while (count);
494
495       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
496         return -1;
497
498       objc_free (mutex->backend);
499       mutex->backend = NULL;
500     }
501   return 0;
502 }
503
504 /* Grab a lock on a mutex.  */
505 static inline int
506 __gthread_objc_mutex_lock (objc_mutex_t mutex)
507 {
508   if (__gthread_active_p ()
509       && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
510     {
511       return -1;
512     }
513
514   return 0;
515 }
516
517 /* Try to grab a lock on a mutex.  */
518 static inline int
519 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
520 {
521   if (__gthread_active_p ()
522       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
523     {
524       return -1;
525     }
526
527   return 0;
528 }
529
530 /* Unlock the mutex */
531 static inline int
532 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
533 {
534   if (__gthread_active_p ()
535       && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
536     {
537       return -1;
538     }
539
540   return 0;
541 }
542
543 /* Backend condition mutex functions */
544
545 /* Allocate a condition.  */
546 static inline int
547 __gthread_objc_condition_allocate (objc_condition_t condition)
548 {
549   if (__gthread_active_p ())
550     {
551       condition->backend = objc_malloc (sizeof (pthread_cond_t));
552
553       if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
554         {
555           objc_free (condition->backend);
556           condition->backend = NULL;
557           return -1;
558         }
559     }
560
561   return 0;
562 }
563
564 /* Deallocate a condition.  */
565 static inline int
566 __gthread_objc_condition_deallocate (objc_condition_t condition)
567 {
568   if (__gthread_active_p ())
569     {
570       if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
571         return -1;
572
573       objc_free (condition->backend);
574       condition->backend = NULL;
575     }
576   return 0;
577 }
578
579 /* Wait on the condition */
580 static inline int
581 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
582 {
583   if (__gthread_active_p ())
584     return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
585                               (pthread_mutex_t *) mutex->backend);
586   else
587     return 0;
588 }
589
590 /* Wake up all threads waiting on this condition.  */
591 static inline int
592 __gthread_objc_condition_broadcast (objc_condition_t condition)
593 {
594   if (__gthread_active_p ())
595     return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
596   else
597     return 0;
598 }
599
600 /* Wake up one thread waiting on this condition.  */
601 static inline int
602 __gthread_objc_condition_signal (objc_condition_t condition)
603 {
604   if (__gthread_active_p ())
605     return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
606   else
607     return 0;
608 }
609
610 #else /* _LIBOBJC */
611
612 static inline int
613 __gthread_once (__gthread_once_t *once, void (*func) (void))
614 {
615   if (__gthread_active_p ())
616     return __gthrw_(pthread_once) (once, func);
617   else
618     return -1;
619 }
620
621 static inline int
622 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
623 {
624   return __gthrw_(pthread_key_create) (key, dtor);
625 }
626
627 static inline int
628 __gthread_key_delete (__gthread_key_t key)
629 {
630   return __gthrw_(pthread_key_delete) (key);
631 }
632
633 static inline void *
634 __gthread_getspecific (__gthread_key_t key)
635 {
636   return __gthrw_(pthread_getspecific) (key);
637 }
638
639 static inline int
640 __gthread_setspecific (__gthread_key_t key, const void *ptr)
641 {
642   return __gthrw_(pthread_setspecific) (key, ptr);
643 }
644
645 static inline int
646 __gthread_mutex_destroy (__gthread_mutex_t *mutex)
647 {
648   if (__gthread_active_p ())
649     return __gthrw_(pthread_mutex_destroy) (mutex);
650   else
651     return 0;
652 }
653
654 static inline int
655 __gthread_mutex_lock (__gthread_mutex_t *mutex)
656 {
657   if (__gthread_active_p ())
658     return __gthrw_(pthread_mutex_lock) (mutex);
659   else
660     return 0;
661 }
662
663 static inline int
664 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
665 {
666   if (__gthread_active_p ())
667     return __gthrw_(pthread_mutex_trylock) (mutex);
668   else
669     return 0;
670 }
671
672 static inline int
673 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
674 {
675   if (__gthread_active_p ())
676     return __gthrw_(pthread_mutex_unlock) (mutex);
677   else
678     return 0;
679 }
680
681 static inline int
682 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
683 {
684   mutex->depth = 0;
685   mutex->owner = (pthread_t) 0;
686   return __gthrw_(pthread_mutex_init) (&mutex->actual, NULL);
687 }
688
689 static inline int
690 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
691 {
692   if (__gthread_active_p ())
693     {
694       pthread_t me = __gthrw_(pthread_self) ();
695
696       if (mutex->owner != me)
697         {
698           __gthrw_(pthread_mutex_lock) (&mutex->actual);
699           mutex->owner = me;
700         }
701
702       mutex->depth++;
703     }
704   return 0;
705 }
706
707 static inline int
708 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
709 {
710   if (__gthread_active_p ())
711     {
712       pthread_t me = __gthrw_(pthread_self) ();
713
714       if (mutex->owner != me)
715         {
716           if (__gthrw_(pthread_mutex_trylock) (&mutex->actual))
717             return 1;
718           mutex->owner = me;
719         }
720
721       mutex->depth++;
722     }
723   return 0;
724 }
725
726 static inline int
727 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
728 {
729   if (__gthread_active_p ())
730     {
731       if (--mutex->depth == 0)
732         {
733            mutex->owner = (pthread_t) 0;
734            __gthrw_(pthread_mutex_unlock) (&mutex->actual);
735         }
736     }
737   return 0;
738 }
739
740 static inline int
741 __gthread_cond_broadcast (__gthread_cond_t *cond)
742 {
743   return __gthrw_(pthread_cond_broadcast) (cond);
744 }
745
746 static inline int
747 __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex)
748 {
749   return __gthrw_(pthread_cond_wait) (cond, mutex);
750 }
751
752 static inline int
753 __gthread_cond_wait_recursive (__gthread_cond_t *cond,
754                                __gthread_recursive_mutex_t *mutex)
755 {
756   return __gthrw_(pthread_cond_wait) (cond, &mutex->actual);
757 }
758
759 #endif /* _LIBOBJC */
760
761 #endif /* ! GCC_GTHR_POSIX_H */