]>
Commit | Line | Data |
---|---|---|
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 | 6 | This file is part of GCC. |
f24af81b | 7 | |
1322177d LB |
8 | GCC is free software; you can redistribute it and/or modify it under |
9 | the terms of the GNU General Public License as published by the Free | |
10 | Software Foundation; either version 2, or (at your option) any later | |
11 | version. | |
f24af81b | 12 | |
1322177d LB |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
f24af81b TT |
17 | |
18 | You should have received a copy of the GNU General Public License | |
1322177d | 19 | along with GCC; see the file COPYING. If not, write to the Free |
366ccddb KC |
20 | Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA |
21 | 02110-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 | |
46 | typedef pthread_key_t __gthread_key_t; | |
47 | typedef pthread_once_t __gthread_once_t; | |
48 | typedef pthread_mutex_t __gthread_mutex_t; | |
40aac948 | 49 | typedef 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 | 145 | static 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 | ||
155 | static 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 */ |
173 | static pthread_key_t _objc_thread_storage; | |
447c11a5 | 174 | static pthread_attr_t _objc_thread_attribs; |
15794a95 L |
175 | |
176 | /* Thread local storage for a single thread */ | |
177 | static void *thread_local_storage = NULL; | |
178 | ||
179 | /* Backend initialization functions */ | |
180 | ||
71287280 | 181 | /* Initialize the threads subsystem. */ |
15794a95 | 182 | static 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 | 204 | static 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 | 218 | static 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 | 236 | static 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, ¶ms) == 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, ¶ms) == 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 | 279 | static 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, ¶ms) == 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 | 301 | static 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 | 309 | static 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 | 321 | static 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 | 331 | static 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 | 344 | static 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 | 356 | static 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 | 375 | static 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 | 405 | static 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 | 418 | static 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 */ | |
431 | static 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 | 446 | static 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 | 465 | static 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 */ | |
480 | static 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 | 491 | static 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 | 501 | static 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 | 512 | static 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 | ||
521 | static 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 |
527 | static inline int |
528 | __gthread_key_delete (__gthread_key_t key) | |
529 | { | |
72b16773 | 530 | return __gthrw_(pthread_key_delete) (key); |
f24af81b TT |
531 | } |
532 | ||
533 | static inline void * | |
534 | __gthread_getspecific (__gthread_key_t key) | |
535 | { | |
72b16773 | 536 | return __gthrw_(pthread_getspecific) (key); |
f24af81b TT |
537 | } |
538 | ||
539 | static 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 | ||
545 | static 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 | ||
554 | static 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 | ||
563 | static 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 |
573 | static 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 | ||
594 | static inline int | |
595 | __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) | |
596 | { | |
597 | return __gthread_mutex_lock (mutex); | |
598 | } | |
599 | ||
600 | static inline int | |
601 | __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) | |
602 | { | |
603 | return __gthread_mutex_trylock (mutex); | |
604 | } | |
605 | ||
606 | static 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 */ |