]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gthr-posix.h
exp_ch5.ads (Expand_N_Extended_Return_Statement): New procedure.
[thirdparty/gcc.git] / gcc / gthr-posix.h
CommitLineData
15794a95 1/* Threads compatibility routines for libgcc2 and libobjc. */
f24af81b 2/* Compile this one with gcc. */
c2a8530e 3/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
2a4e8ebc 4 Free Software Foundation, Inc.
f24af81b 5
1322177d 6This file is part of GCC.
f24af81b 7
1322177d
LB
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
f24af81b 12
1322177d
LB
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
f24af81b
TT
17
18You should have received a copy of the GNU General Public License
1322177d 19along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
f24af81b
TT
22
23/* As a special exception, if you link this library with other files,
24 some of which are compiled with GCC, to produce an executable,
25 this library does not by itself cause the resulting executable
26 to be covered by the GNU General Public License.
27 This exception does not however invalidate any other reasons why
28 the executable file might be covered by the GNU General Public License. */
29
88657302
RH
30#ifndef GCC_GTHR_POSIX_H
31#define GCC_GTHR_POSIX_H
f24af81b
TT
32
33/* POSIX threads specific definitions.
71287280 34 Easy, since the interface is just one-to-one mapping. */
f24af81b
TT
35
36#define __GTHREADS 1
37
2a4e8ebc
RO
38/* Some implementations of <pthread.h> require this to be defined. */
39#ifndef _REENTRANT
40#define _REENTRANT 1
41#endif
42
f24af81b 43#include <pthread.h>
c95d07f8 44#include <unistd.h>
f24af81b
TT
45
46typedef pthread_key_t __gthread_key_t;
47typedef pthread_once_t __gthread_once_t;
48typedef pthread_mutex_t __gthread_mutex_t;
40aac948 49typedef pthread_mutex_t __gthread_recursive_mutex_t;
f24af81b
TT
50
51#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
52#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
40aac948
JM
53#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
54#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
55#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
56#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
e95dc99b 57#else
ab3d1049 58#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
40aac948 59#endif
f24af81b
TT
60
61#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
a11dd268
RS
62# define __gthrw2(name,name2,type) \
63 static __typeof(type) name __attribute__ ((__weakref__(#name2)));
72b16773 64# define __gthrw_(name) __gthrw_ ## name
7ef67393 65#else
a11dd268 66# define __gthrw2(name,name2,type)
72b16773 67# define __gthrw_(name) name
7ef67393 68#endif
f24af81b 69
efbbbb61 70/* Typically, __gthrw_foo is a weak reference to symbol foo. */
a11dd268 71#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
c2a8530e
RS
72
73/* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
74 map a subset of the POSIX pthread API to mangled versions of their
75 names. */
76#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
a11dd268
RS
77#define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
78__gthrw3(pthread_once)
79__gthrw3(pthread_getspecific)
80__gthrw3(pthread_setspecific)
81__gthrw3(pthread_create)
82__gthrw3(pthread_cancel)
83__gthrw3(pthread_mutex_lock)
84__gthrw3(pthread_mutex_trylock)
85__gthrw3(pthread_mutex_unlock)
86__gthrw3(pthread_mutex_init)
c2a8530e 87#else
72b16773 88__gthrw(pthread_once)
72b16773
AO
89__gthrw(pthread_getspecific)
90__gthrw(pthread_setspecific)
91__gthrw(pthread_create)
92__gthrw(pthread_cancel)
72b16773
AO
93__gthrw(pthread_mutex_lock)
94__gthrw(pthread_mutex_trylock)
95__gthrw(pthread_mutex_unlock)
c2a8530e
RS
96__gthrw(pthread_mutex_init)
97#endif
98
99__gthrw(pthread_key_create)
100__gthrw(pthread_key_delete)
72b16773
AO
101__gthrw(pthread_mutexattr_init)
102__gthrw(pthread_mutexattr_settype)
103__gthrw(pthread_mutexattr_destroy)
70008293 104
15794a95 105
2a4e8ebc 106#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
40f03658 107/* Objective-C. */
c2a8530e 108#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
a11dd268
RS
109__gthrw3(pthread_cond_broadcast)
110__gthrw3(pthread_cond_destroy)
111__gthrw3(pthread_cond_init)
112__gthrw3(pthread_cond_signal)
113__gthrw3(pthread_cond_wait)
114__gthrw3(pthread_exit)
115__gthrw3(pthread_mutex_destroy)
116__gthrw3(pthread_self)
c2a8530e 117#else
72b16773
AO
118__gthrw(pthread_cond_broadcast)
119__gthrw(pthread_cond_destroy)
120__gthrw(pthread_cond_init)
121__gthrw(pthread_cond_signal)
122__gthrw(pthread_cond_wait)
123__gthrw(pthread_exit)
124__gthrw(pthread_mutex_destroy)
125__gthrw(pthread_self)
c2a8530e 126#endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
45863ba3 127#ifdef _POSIX_PRIORITY_SCHEDULING
c95d07f8 128#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773
AO
129__gthrw(sched_get_priority_max)
130__gthrw(sched_get_priority_min)
c95d07f8 131#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
45863ba3 132#endif /* _POSIX_PRIORITY_SCHEDULING */
72b16773
AO
133__gthrw(sched_yield)
134__gthrw(pthread_attr_destroy)
135__gthrw(pthread_attr_init)
136__gthrw(pthread_attr_setdetachstate)
c95d07f8 137#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773
AO
138__gthrw(pthread_getschedparam)
139__gthrw(pthread_setschedparam)
c95d07f8 140#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
2a4e8ebc 141#endif /* _LIBOBJC || _LIBOBJC_WEAK */
f24af81b 142
7ef67393
AO
143#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
144
f24af81b 145static inline int
d1e51320 146__gthread_active_p (void)
f24af81b 147{
b235bd44 148 static void *const __gthread_active_ptr
72b16773 149 = __extension__ (void *) &__gthrw_(pthread_cancel);
f24af81b
TT
150 return __gthread_active_ptr != 0;
151}
152
153#else /* not SUPPORTS_WEAK */
154
155static inline int
d1e51320 156__gthread_active_p (void)
f24af81b
TT
157{
158 return 1;
159}
160
161#endif /* SUPPORTS_WEAK */
162
15794a95
L
163#ifdef _LIBOBJC
164
5f974826
OP
165/* This is the config.h file in libobjc/ */
166#include <config.h>
167
168#ifdef HAVE_SCHED_H
169# include <sched.h>
170#endif
171
15794a95
L
172/* Key structure for maintaining thread specific storage */
173static pthread_key_t _objc_thread_storage;
447c11a5 174static pthread_attr_t _objc_thread_attribs;
15794a95
L
175
176/* Thread local storage for a single thread */
177static void *thread_local_storage = NULL;
178
179/* Backend initialization functions */
180
71287280 181/* Initialize the threads subsystem. */
15794a95 182static inline int
fe83a9ce 183__gthread_objc_init_thread_system (void)
15794a95
L
184{
185 if (__gthread_active_p ())
447c11a5 186 {
ea4b7848 187 /* Initialize the thread storage key. */
72b16773 188 if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
589005ff
KH
189 {
190 /* The normal default detach state for threads is
191 * PTHREAD_CREATE_JOINABLE which causes threads to not die
192 * when you think they should. */
72b16773
AO
193 if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
194 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
fe83a9ce 195 PTHREAD_CREATE_DETACHED) == 0)
589005ff
KH
196 return 0;
197 }
447c11a5 198 }
abc0360c
NP
199
200 return -1;
15794a95
L
201}
202
71287280 203/* Close the threads subsystem. */
15794a95 204static inline int
fe83a9ce 205__gthread_objc_close_thread_system (void)
15794a95 206{
447c11a5 207 if (__gthread_active_p ()
72b16773
AO
208 && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
209 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
15794a95 210 return 0;
447c11a5
OP
211
212 return -1;
15794a95
L
213}
214
215/* Backend thread functions */
216
71287280 217/* Create a new thread of execution. */
15794a95 218static inline objc_thread_t
fe83a9ce 219__gthread_objc_thread_detach (void (*func)(void *), void *arg)
15794a95
L
220{
221 objc_thread_t thread_id;
222 pthread_t new_thread_handle;
223
224 if (!__gthread_active_p ())
225 return NULL;
589005ff 226
72b16773 227 if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
fee013ef 228 thread_id = (objc_thread_t) new_thread_handle;
15794a95
L
229 else
230 thread_id = NULL;
589005ff 231
15794a95
L
232 return thread_id;
233}
234
71287280 235/* Set the current thread's priority. */
15794a95 236static inline int
fe83a9ce 237__gthread_objc_thread_set_priority (int priority)
15794a95 238{
fe83a9ce 239 if (!__gthread_active_p ())
447c11a5 240 return -1;
fe83a9ce
KH
241 else
242 {
45863ba3 243#ifdef _POSIX_PRIORITY_SCHEDULING
c95d07f8 244#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
72b16773 245 pthread_t thread_id = __gthrw_(pthread_self) ();
fe83a9ce
KH
246 int policy;
247 struct sched_param params;
248 int priority_min, priority_max;
589005ff 249
72b16773 250 if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
fe83a9ce 251 {
72b16773 252 if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
fe83a9ce
KH
253 return -1;
254
72b16773 255 if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
fe83a9ce 256 return -1;
589005ff 257
fe83a9ce
KH
258 if (priority > priority_max)
259 priority = priority_max;
260 else if (priority < priority_min)
261 priority = priority_min;
262 params.sched_priority = priority;
263
264 /*
265 * The solaris 7 and several other man pages incorrectly state that
266 * this should be a pointer to policy but pthread.h is universally
267 * at odds with this.
268 */
72b16773 269 if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
fe83a9ce
KH
270 return 0;
271 }
c95d07f8 272#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
45863ba3 273#endif /* _POSIX_PRIORITY_SCHEDULING */
fe83a9ce
KH
274 return -1;
275 }
15794a95
L
276}
277
71287280 278/* Return the current thread's priority. */
15794a95 279static inline int
fe83a9ce 280__gthread_objc_thread_get_priority (void)
15794a95 281{
45863ba3 282#ifdef _POSIX_PRIORITY_SCHEDULING
c95d07f8 283#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
15794a95 284 if (__gthread_active_p ())
447c11a5
OP
285 {
286 int policy;
287 struct sched_param params;
288
72b16773 289 if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
589005ff 290 return params.sched_priority;
447c11a5 291 else
589005ff 292 return -1;
447c11a5 293 }
15794a95 294 else
c95d07f8 295#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
45863ba3 296#endif /* _POSIX_PRIORITY_SCHEDULING */
15794a95
L
297 return OBJC_THREAD_INTERACTIVE_PRIORITY;
298}
299
71287280 300/* Yield our process time to another thread. */
15794a95 301static inline void
fe83a9ce 302__gthread_objc_thread_yield (void)
15794a95
L
303{
304 if (__gthread_active_p ())
72b16773 305 __gthrw_(sched_yield) ();
15794a95
L
306}
307
71287280 308/* Terminate the current thread. */
15794a95 309static inline int
fe83a9ce 310__gthread_objc_thread_exit (void)
15794a95
L
311{
312 if (__gthread_active_p ())
313 /* exit the thread */
72b16773 314 __gthrw_(pthread_exit) (&__objc_thread_exit_status);
15794a95
L
315
316 /* Failed if we reached here */
317 return -1;
318}
319
71287280 320/* Returns an integer value which uniquely describes a thread. */
15794a95 321static inline objc_thread_t
fe83a9ce 322__gthread_objc_thread_id (void)
15794a95
L
323{
324 if (__gthread_active_p ())
72b16773 325 return (objc_thread_t) __gthrw_(pthread_self) ();
15794a95 326 else
fee013ef 327 return (objc_thread_t) 1;
15794a95
L
328}
329
71287280 330/* Sets the thread's local storage pointer. */
15794a95 331static inline int
fe83a9ce 332__gthread_objc_thread_set_data (void *value)
15794a95
L
333{
334 if (__gthread_active_p ())
72b16773 335 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
15794a95
L
336 else
337 {
338 thread_local_storage = value;
339 return 0;
340 }
341}
342
71287280 343/* Returns the thread's local storage pointer. */
15794a95 344static inline void *
fe83a9ce 345__gthread_objc_thread_get_data (void)
15794a95
L
346{
347 if (__gthread_active_p ())
72b16773 348 return __gthrw_(pthread_getspecific) (_objc_thread_storage);
15794a95
L
349 else
350 return thread_local_storage;
351}
352
353/* Backend mutex functions */
354
71287280 355/* Allocate a mutex. */
15794a95 356static inline int
fe83a9ce 357__gthread_objc_mutex_allocate (objc_mutex_t mutex)
15794a95
L
358{
359 if (__gthread_active_p ())
360 {
fe83a9ce 361 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
15794a95 362
72b16773 363 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
15794a95 364 {
fe83a9ce 365 objc_free (mutex->backend);
15794a95
L
366 mutex->backend = NULL;
367 return -1;
368 }
369 }
370
371 return 0;
372}
373
71287280 374/* Deallocate a mutex. */
15794a95 375static inline int
fe83a9ce 376__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
15794a95
L
377{
378 if (__gthread_active_p ())
379 {
380 int count;
381
382 /*
383 * Posix Threads specifically require that the thread be unlocked
72b16773 384 * for __gthrw_(pthread_mutex_destroy) to work.
15794a95
L
385 */
386
387 do
388 {
72b16773 389 count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
15794a95
L
390 if (count < 0)
391 return -1;
392 }
393 while (count);
394
72b16773 395 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
15794a95
L
396 return -1;
397
fe83a9ce 398 objc_free (mutex->backend);
15794a95
L
399 mutex->backend = NULL;
400 }
401 return 0;
402}
403
71287280 404/* Grab a lock on a mutex. */
15794a95 405static inline int
fe83a9ce 406__gthread_objc_mutex_lock (objc_mutex_t mutex)
15794a95 407{
589005ff 408 if (__gthread_active_p ()
72b16773 409 && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
054af139
NP
410 {
411 return -1;
412 }
413
414 return 0;
15794a95
L
415}
416
71287280 417/* Try to grab a lock on a mutex. */
15794a95 418static inline int
fe83a9ce 419__gthread_objc_mutex_trylock (objc_mutex_t mutex)
15794a95 420{
589005ff 421 if (__gthread_active_p ()
72b16773 422 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
054af139
NP
423 {
424 return -1;
425 }
426
427 return 0;
15794a95
L
428}
429
430/* Unlock the mutex */
431static inline int
fe83a9ce 432__gthread_objc_mutex_unlock (objc_mutex_t mutex)
15794a95 433{
589005ff 434 if (__gthread_active_p ()
72b16773 435 && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
054af139
NP
436 {
437 return -1;
438 }
439
440 return 0;
15794a95
L
441}
442
443/* Backend condition mutex functions */
444
71287280 445/* Allocate a condition. */
15794a95 446static inline int
fe83a9ce 447__gthread_objc_condition_allocate (objc_condition_t condition)
15794a95
L
448{
449 if (__gthread_active_p ())
450 {
fe83a9ce 451 condition->backend = objc_malloc (sizeof (pthread_cond_t));
15794a95 452
72b16773 453 if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
15794a95 454 {
fe83a9ce 455 objc_free (condition->backend);
15794a95
L
456 condition->backend = NULL;
457 return -1;
458 }
459 }
460
461 return 0;
462}
463
71287280 464/* Deallocate a condition. */
15794a95 465static inline int
fe83a9ce 466__gthread_objc_condition_deallocate (objc_condition_t condition)
15794a95
L
467{
468 if (__gthread_active_p ())
469 {
72b16773 470 if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
15794a95
L
471 return -1;
472
fe83a9ce 473 objc_free (condition->backend);
15794a95
L
474 condition->backend = NULL;
475 }
476 return 0;
477}
478
479/* Wait on the condition */
480static inline int
fe83a9ce 481__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
15794a95
L
482{
483 if (__gthread_active_p ())
72b16773 484 return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
fe83a9ce 485 (pthread_mutex_t *) mutex->backend);
15794a95
L
486 else
487 return 0;
488}
489
71287280 490/* Wake up all threads waiting on this condition. */
15794a95 491static inline int
fe83a9ce 492__gthread_objc_condition_broadcast (objc_condition_t condition)
15794a95
L
493{
494 if (__gthread_active_p ())
72b16773 495 return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
15794a95
L
496 else
497 return 0;
498}
499
71287280 500/* Wake up one thread waiting on this condition. */
15794a95 501static inline int
fe83a9ce 502__gthread_objc_condition_signal (objc_condition_t condition)
15794a95
L
503{
504 if (__gthread_active_p ())
72b16773 505 return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
15794a95
L
506 else
507 return 0;
508}
509
510#else /* _LIBOBJC */
511
f24af81b 512static inline int
d1e51320 513__gthread_once (__gthread_once_t *once, void (*func) (void))
f24af81b
TT
514{
515 if (__gthread_active_p ())
72b16773 516 return __gthrw_(pthread_once) (once, func);
f24af81b
TT
517 else
518 return -1;
519}
520
521static inline int
522__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
523{
72b16773 524 return __gthrw_(pthread_key_create) (key, dtor);
f24af81b
TT
525}
526
f24af81b
TT
527static inline int
528__gthread_key_delete (__gthread_key_t key)
529{
72b16773 530 return __gthrw_(pthread_key_delete) (key);
f24af81b
TT
531}
532
533static inline void *
534__gthread_getspecific (__gthread_key_t key)
535{
72b16773 536 return __gthrw_(pthread_getspecific) (key);
f24af81b
TT
537}
538
539static inline int
540__gthread_setspecific (__gthread_key_t key, const void *ptr)
541{
72b16773 542 return __gthrw_(pthread_setspecific) (key, ptr);
f24af81b
TT
543}
544
545static inline int
546__gthread_mutex_lock (__gthread_mutex_t *mutex)
547{
548 if (__gthread_active_p ())
72b16773 549 return __gthrw_(pthread_mutex_lock) (mutex);
f24af81b
TT
550 else
551 return 0;
552}
553
554static inline int
555__gthread_mutex_trylock (__gthread_mutex_t *mutex)
556{
557 if (__gthread_active_p ())
72b16773 558 return __gthrw_(pthread_mutex_trylock) (mutex);
f24af81b
TT
559 else
560 return 0;
561}
562
563static inline int
564__gthread_mutex_unlock (__gthread_mutex_t *mutex)
565{
566 if (__gthread_active_p ())
72b16773 567 return __gthrw_(pthread_mutex_unlock) (mutex);
f24af81b
TT
568 else
569 return 0;
570}
571
ab3d1049 572#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
40aac948
JM
573static inline int
574__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
575{
576 if (__gthread_active_p ())
577 {
578 pthread_mutexattr_t attr;
579 int r;
580
72b16773 581 r = __gthrw_(pthread_mutexattr_init) (&attr);
40aac948 582 if (!r)
72b16773 583 r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
40aac948 584 if (!r)
72b16773 585 r = __gthrw_(pthread_mutex_init) (mutex, &attr);
40aac948 586 if (!r)
72b16773 587 r = __gthrw_(pthread_mutexattr_destroy) (&attr);
40aac948
JM
588 return r;
589 }
7c68fabb 590 return 0;
40aac948
JM
591}
592#endif
593
594static inline int
595__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
596{
597 return __gthread_mutex_lock (mutex);
598}
599
600static inline int
601__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
602{
603 return __gthread_mutex_trylock (mutex);
604}
605
606static inline int
607__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
608{
609 return __gthread_mutex_unlock (mutex);
610}
611
15794a95
L
612#endif /* _LIBOBJC */
613
88657302 614#endif /* ! GCC_GTHR_POSIX_H */