]>
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 | |
c2a8530e RS |
62 | # define __gthrw2(name,name2) \ |
63 | static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name2))); | |
72b16773 | 64 | # define __gthrw_(name) __gthrw_ ## name |
7ef67393 | 65 | #else |
c2a8530e | 66 | # define __gthrw2(name,name2) |
72b16773 | 67 | # define __gthrw_(name) name |
7ef67393 | 68 | #endif |
f24af81b | 69 | |
efbbbb61 | 70 | /* Typically, __gthrw_foo is a weak reference to symbol foo. */ |
c2a8530e RS |
71 | #define __gthrw(name) __gthrw2(name,name) |
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_) | |
77 | __gthrw2(pthread_once,__pthread_once) | |
78 | __gthrw2(pthread_getspecific,__pthread_getspecific) | |
79 | __gthrw2(pthread_setspecific,__pthread_setspecific) | |
80 | __gthrw2(pthread_create,__pthread_create) | |
81 | __gthrw2(pthread_cancel,__pthread_cancel) | |
82 | __gthrw2(pthread_mutex_lock,__pthread_mutex_lock) | |
83 | __gthrw2(pthread_mutex_trylock,__pthread_mutex_trylock) | |
84 | __gthrw2(pthread_mutex_unlock,__pthread_mutex_unlock) | |
85 | __gthrw2(pthread_mutex_init,__pthread_mutex_init) | |
86 | #else | |
72b16773 | 87 | __gthrw(pthread_once) |
72b16773 AO |
88 | __gthrw(pthread_getspecific) |
89 | __gthrw(pthread_setspecific) | |
90 | __gthrw(pthread_create) | |
91 | __gthrw(pthread_cancel) | |
72b16773 AO |
92 | __gthrw(pthread_mutex_lock) |
93 | __gthrw(pthread_mutex_trylock) | |
94 | __gthrw(pthread_mutex_unlock) | |
c2a8530e RS |
95 | __gthrw(pthread_mutex_init) |
96 | #endif | |
97 | ||
98 | __gthrw(pthread_key_create) | |
99 | __gthrw(pthread_key_delete) | |
72b16773 AO |
100 | __gthrw(pthread_mutexattr_init) |
101 | __gthrw(pthread_mutexattr_settype) | |
102 | __gthrw(pthread_mutexattr_destroy) | |
70008293 | 103 | |
15794a95 | 104 | |
2a4e8ebc | 105 | #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) |
40f03658 | 106 | /* Objective-C. */ |
c2a8530e RS |
107 | #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) |
108 | __gthrw2(pthread_cond_broadcast,__pthread_cond_broadcast) | |
109 | __gthrw2(pthread_cond_destroy,__pthread_cond_destroy) | |
110 | __gthrw2(pthread_cond_init,__pthread_cond_init) | |
111 | __gthrw2(pthread_cond_signal,__pthread_cond_signal) | |
112 | __gthrw2(pthread_cond_wait,__pthread_cond_wait) | |
113 | __gthrw2(pthread_exit,__pthread_exit) | |
114 | __gthrw2(pthread_mutex_destroy,__pthread_mutex_destroy) | |
115 | __gthrw2(pthread_self,__pthread_self) | |
116 | #else | |
72b16773 AO |
117 | __gthrw(pthread_cond_broadcast) |
118 | __gthrw(pthread_cond_destroy) | |
119 | __gthrw(pthread_cond_init) | |
120 | __gthrw(pthread_cond_signal) | |
121 | __gthrw(pthread_cond_wait) | |
122 | __gthrw(pthread_exit) | |
123 | __gthrw(pthread_mutex_destroy) | |
124 | __gthrw(pthread_self) | |
c2a8530e | 125 | #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */ |
45863ba3 | 126 | #ifdef _POSIX_PRIORITY_SCHEDULING |
c95d07f8 | 127 | #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING |
72b16773 AO |
128 | __gthrw(sched_get_priority_max) |
129 | __gthrw(sched_get_priority_min) | |
c95d07f8 | 130 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
45863ba3 | 131 | #endif /* _POSIX_PRIORITY_SCHEDULING */ |
72b16773 AO |
132 | __gthrw(sched_yield) |
133 | __gthrw(pthread_attr_destroy) | |
134 | __gthrw(pthread_attr_init) | |
135 | __gthrw(pthread_attr_setdetachstate) | |
c95d07f8 | 136 | #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING |
72b16773 AO |
137 | __gthrw(pthread_getschedparam) |
138 | __gthrw(pthread_setschedparam) | |
c95d07f8 | 139 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
2a4e8ebc | 140 | #endif /* _LIBOBJC || _LIBOBJC_WEAK */ |
f24af81b | 141 | |
7ef67393 AO |
142 | #if SUPPORTS_WEAK && GTHREAD_USE_WEAK |
143 | ||
f24af81b | 144 | static inline int |
d1e51320 | 145 | __gthread_active_p (void) |
f24af81b | 146 | { |
b235bd44 | 147 | static void *const __gthread_active_ptr |
72b16773 | 148 | = __extension__ (void *) &__gthrw_(pthread_cancel); |
f24af81b TT |
149 | return __gthread_active_ptr != 0; |
150 | } | |
151 | ||
152 | #else /* not SUPPORTS_WEAK */ | |
153 | ||
154 | static inline int | |
d1e51320 | 155 | __gthread_active_p (void) |
f24af81b TT |
156 | { |
157 | return 1; | |
158 | } | |
159 | ||
160 | #endif /* SUPPORTS_WEAK */ | |
161 | ||
15794a95 L |
162 | #ifdef _LIBOBJC |
163 | ||
5f974826 OP |
164 | /* This is the config.h file in libobjc/ */ |
165 | #include <config.h> | |
166 | ||
167 | #ifdef HAVE_SCHED_H | |
168 | # include <sched.h> | |
169 | #endif | |
170 | ||
15794a95 L |
171 | /* Key structure for maintaining thread specific storage */ |
172 | static pthread_key_t _objc_thread_storage; | |
447c11a5 | 173 | static pthread_attr_t _objc_thread_attribs; |
15794a95 L |
174 | |
175 | /* Thread local storage for a single thread */ | |
176 | static void *thread_local_storage = NULL; | |
177 | ||
178 | /* Backend initialization functions */ | |
179 | ||
71287280 | 180 | /* Initialize the threads subsystem. */ |
15794a95 | 181 | static inline int |
fe83a9ce | 182 | __gthread_objc_init_thread_system (void) |
15794a95 L |
183 | { |
184 | if (__gthread_active_p ()) | |
447c11a5 | 185 | { |
ea4b7848 | 186 | /* Initialize the thread storage key. */ |
72b16773 | 187 | if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) |
589005ff KH |
188 | { |
189 | /* The normal default detach state for threads is | |
190 | * PTHREAD_CREATE_JOINABLE which causes threads to not die | |
191 | * when you think they should. */ | |
72b16773 AO |
192 | if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 |
193 | && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, | |
fe83a9ce | 194 | PTHREAD_CREATE_DETACHED) == 0) |
589005ff KH |
195 | return 0; |
196 | } | |
447c11a5 | 197 | } |
abc0360c NP |
198 | |
199 | return -1; | |
15794a95 L |
200 | } |
201 | ||
71287280 | 202 | /* Close the threads subsystem. */ |
15794a95 | 203 | static inline int |
fe83a9ce | 204 | __gthread_objc_close_thread_system (void) |
15794a95 | 205 | { |
447c11a5 | 206 | if (__gthread_active_p () |
72b16773 AO |
207 | && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 |
208 | && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) | |
15794a95 | 209 | return 0; |
447c11a5 OP |
210 | |
211 | return -1; | |
15794a95 L |
212 | } |
213 | ||
214 | /* Backend thread functions */ | |
215 | ||
71287280 | 216 | /* Create a new thread of execution. */ |
15794a95 | 217 | static inline objc_thread_t |
fe83a9ce | 218 | __gthread_objc_thread_detach (void (*func)(void *), void *arg) |
15794a95 L |
219 | { |
220 | objc_thread_t thread_id; | |
221 | pthread_t new_thread_handle; | |
222 | ||
223 | if (!__gthread_active_p ()) | |
224 | return NULL; | |
589005ff | 225 | |
72b16773 | 226 | if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg))) |
fee013ef | 227 | thread_id = (objc_thread_t) new_thread_handle; |
15794a95 L |
228 | else |
229 | thread_id = NULL; | |
589005ff | 230 | |
15794a95 L |
231 | return thread_id; |
232 | } | |
233 | ||
71287280 | 234 | /* Set the current thread's priority. */ |
15794a95 | 235 | static inline int |
fe83a9ce | 236 | __gthread_objc_thread_set_priority (int priority) |
15794a95 | 237 | { |
fe83a9ce | 238 | if (!__gthread_active_p ()) |
447c11a5 | 239 | return -1; |
fe83a9ce KH |
240 | else |
241 | { | |
45863ba3 | 242 | #ifdef _POSIX_PRIORITY_SCHEDULING |
c95d07f8 | 243 | #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING |
72b16773 | 244 | pthread_t thread_id = __gthrw_(pthread_self) (); |
fe83a9ce KH |
245 | int policy; |
246 | struct sched_param params; | |
247 | int priority_min, priority_max; | |
589005ff | 248 | |
72b16773 | 249 | if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) |
fe83a9ce | 250 | { |
72b16773 | 251 | if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) |
fe83a9ce KH |
252 | return -1; |
253 | ||
72b16773 | 254 | if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) |
fe83a9ce | 255 | return -1; |
589005ff | 256 | |
fe83a9ce KH |
257 | if (priority > priority_max) |
258 | priority = priority_max; | |
259 | else if (priority < priority_min) | |
260 | priority = priority_min; | |
261 | params.sched_priority = priority; | |
262 | ||
263 | /* | |
264 | * The solaris 7 and several other man pages incorrectly state that | |
265 | * this should be a pointer to policy but pthread.h is universally | |
266 | * at odds with this. | |
267 | */ | |
72b16773 | 268 | if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) |
fe83a9ce KH |
269 | return 0; |
270 | } | |
c95d07f8 | 271 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
45863ba3 | 272 | #endif /* _POSIX_PRIORITY_SCHEDULING */ |
fe83a9ce KH |
273 | return -1; |
274 | } | |
15794a95 L |
275 | } |
276 | ||
71287280 | 277 | /* Return the current thread's priority. */ |
15794a95 | 278 | static inline int |
fe83a9ce | 279 | __gthread_objc_thread_get_priority (void) |
15794a95 | 280 | { |
45863ba3 | 281 | #ifdef _POSIX_PRIORITY_SCHEDULING |
c95d07f8 | 282 | #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING |
15794a95 | 283 | if (__gthread_active_p ()) |
447c11a5 OP |
284 | { |
285 | int policy; | |
286 | struct sched_param params; | |
287 | ||
72b16773 | 288 | if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) |
589005ff | 289 | return params.sched_priority; |
447c11a5 | 290 | else |
589005ff | 291 | return -1; |
447c11a5 | 292 | } |
15794a95 | 293 | else |
c95d07f8 | 294 | #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ |
45863ba3 | 295 | #endif /* _POSIX_PRIORITY_SCHEDULING */ |
15794a95 L |
296 | return OBJC_THREAD_INTERACTIVE_PRIORITY; |
297 | } | |
298 | ||
71287280 | 299 | /* Yield our process time to another thread. */ |
15794a95 | 300 | static inline void |
fe83a9ce | 301 | __gthread_objc_thread_yield (void) |
15794a95 L |
302 | { |
303 | if (__gthread_active_p ()) | |
72b16773 | 304 | __gthrw_(sched_yield) (); |
15794a95 L |
305 | } |
306 | ||
71287280 | 307 | /* Terminate the current thread. */ |
15794a95 | 308 | static inline int |
fe83a9ce | 309 | __gthread_objc_thread_exit (void) |
15794a95 L |
310 | { |
311 | if (__gthread_active_p ()) | |
312 | /* exit the thread */ | |
72b16773 | 313 | __gthrw_(pthread_exit) (&__objc_thread_exit_status); |
15794a95 L |
314 | |
315 | /* Failed if we reached here */ | |
316 | return -1; | |
317 | } | |
318 | ||
71287280 | 319 | /* Returns an integer value which uniquely describes a thread. */ |
15794a95 | 320 | static inline objc_thread_t |
fe83a9ce | 321 | __gthread_objc_thread_id (void) |
15794a95 L |
322 | { |
323 | if (__gthread_active_p ()) | |
72b16773 | 324 | return (objc_thread_t) __gthrw_(pthread_self) (); |
15794a95 | 325 | else |
fee013ef | 326 | return (objc_thread_t) 1; |
15794a95 L |
327 | } |
328 | ||
71287280 | 329 | /* Sets the thread's local storage pointer. */ |
15794a95 | 330 | static inline int |
fe83a9ce | 331 | __gthread_objc_thread_set_data (void *value) |
15794a95 L |
332 | { |
333 | if (__gthread_active_p ()) | |
72b16773 | 334 | return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); |
15794a95 L |
335 | else |
336 | { | |
337 | thread_local_storage = value; | |
338 | return 0; | |
339 | } | |
340 | } | |
341 | ||
71287280 | 342 | /* Returns the thread's local storage pointer. */ |
15794a95 | 343 | static inline void * |
fe83a9ce | 344 | __gthread_objc_thread_get_data (void) |
15794a95 L |
345 | { |
346 | if (__gthread_active_p ()) | |
72b16773 | 347 | return __gthrw_(pthread_getspecific) (_objc_thread_storage); |
15794a95 L |
348 | else |
349 | return thread_local_storage; | |
350 | } | |
351 | ||
352 | /* Backend mutex functions */ | |
353 | ||
71287280 | 354 | /* Allocate a mutex. */ |
15794a95 | 355 | static inline int |
fe83a9ce | 356 | __gthread_objc_mutex_allocate (objc_mutex_t mutex) |
15794a95 L |
357 | { |
358 | if (__gthread_active_p ()) | |
359 | { | |
fe83a9ce | 360 | mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); |
15794a95 | 361 | |
72b16773 | 362 | if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) |
15794a95 | 363 | { |
fe83a9ce | 364 | objc_free (mutex->backend); |
15794a95 L |
365 | mutex->backend = NULL; |
366 | return -1; | |
367 | } | |
368 | } | |
369 | ||
370 | return 0; | |
371 | } | |
372 | ||
71287280 | 373 | /* Deallocate a mutex. */ |
15794a95 | 374 | static inline int |
fe83a9ce | 375 | __gthread_objc_mutex_deallocate (objc_mutex_t mutex) |
15794a95 L |
376 | { |
377 | if (__gthread_active_p ()) | |
378 | { | |
379 | int count; | |
380 | ||
381 | /* | |
382 | * Posix Threads specifically require that the thread be unlocked | |
72b16773 | 383 | * for __gthrw_(pthread_mutex_destroy) to work. |
15794a95 L |
384 | */ |
385 | ||
386 | do | |
387 | { | |
72b16773 | 388 | count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); |
15794a95 L |
389 | if (count < 0) |
390 | return -1; | |
391 | } | |
392 | while (count); | |
393 | ||
72b16773 | 394 | if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) |
15794a95 L |
395 | return -1; |
396 | ||
fe83a9ce | 397 | objc_free (mutex->backend); |
15794a95 L |
398 | mutex->backend = NULL; |
399 | } | |
400 | return 0; | |
401 | } | |
402 | ||
71287280 | 403 | /* Grab a lock on a mutex. */ |
15794a95 | 404 | static inline int |
fe83a9ce | 405 | __gthread_objc_mutex_lock (objc_mutex_t mutex) |
15794a95 | 406 | { |
589005ff | 407 | if (__gthread_active_p () |
72b16773 | 408 | && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) |
054af139 NP |
409 | { |
410 | return -1; | |
411 | } | |
412 | ||
413 | return 0; | |
15794a95 L |
414 | } |
415 | ||
71287280 | 416 | /* Try to grab a lock on a mutex. */ |
15794a95 | 417 | static inline int |
fe83a9ce | 418 | __gthread_objc_mutex_trylock (objc_mutex_t mutex) |
15794a95 | 419 | { |
589005ff | 420 | if (__gthread_active_p () |
72b16773 | 421 | && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) |
054af139 NP |
422 | { |
423 | return -1; | |
424 | } | |
425 | ||
426 | return 0; | |
15794a95 L |
427 | } |
428 | ||
429 | /* Unlock the mutex */ | |
430 | static inline int | |
fe83a9ce | 431 | __gthread_objc_mutex_unlock (objc_mutex_t mutex) |
15794a95 | 432 | { |
589005ff | 433 | if (__gthread_active_p () |
72b16773 | 434 | && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) |
054af139 NP |
435 | { |
436 | return -1; | |
437 | } | |
438 | ||
439 | return 0; | |
15794a95 L |
440 | } |
441 | ||
442 | /* Backend condition mutex functions */ | |
443 | ||
71287280 | 444 | /* Allocate a condition. */ |
15794a95 | 445 | static inline int |
fe83a9ce | 446 | __gthread_objc_condition_allocate (objc_condition_t condition) |
15794a95 L |
447 | { |
448 | if (__gthread_active_p ()) | |
449 | { | |
fe83a9ce | 450 | condition->backend = objc_malloc (sizeof (pthread_cond_t)); |
15794a95 | 451 | |
72b16773 | 452 | if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) |
15794a95 | 453 | { |
fe83a9ce | 454 | objc_free (condition->backend); |
15794a95 L |
455 | condition->backend = NULL; |
456 | return -1; | |
457 | } | |
458 | } | |
459 | ||
460 | return 0; | |
461 | } | |
462 | ||
71287280 | 463 | /* Deallocate a condition. */ |
15794a95 | 464 | static inline int |
fe83a9ce | 465 | __gthread_objc_condition_deallocate (objc_condition_t condition) |
15794a95 L |
466 | { |
467 | if (__gthread_active_p ()) | |
468 | { | |
72b16773 | 469 | if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) |
15794a95 L |
470 | return -1; |
471 | ||
fe83a9ce | 472 | objc_free (condition->backend); |
15794a95 L |
473 | condition->backend = NULL; |
474 | } | |
475 | return 0; | |
476 | } | |
477 | ||
478 | /* Wait on the condition */ | |
479 | static inline int | |
fe83a9ce | 480 | __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) |
15794a95 L |
481 | { |
482 | if (__gthread_active_p ()) | |
72b16773 | 483 | return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, |
fe83a9ce | 484 | (pthread_mutex_t *) mutex->backend); |
15794a95 L |
485 | else |
486 | return 0; | |
487 | } | |
488 | ||
71287280 | 489 | /* Wake up all threads waiting on this condition. */ |
15794a95 | 490 | static inline int |
fe83a9ce | 491 | __gthread_objc_condition_broadcast (objc_condition_t condition) |
15794a95 L |
492 | { |
493 | if (__gthread_active_p ()) | |
72b16773 | 494 | return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); |
15794a95 L |
495 | else |
496 | return 0; | |
497 | } | |
498 | ||
71287280 | 499 | /* Wake up one thread waiting on this condition. */ |
15794a95 | 500 | static inline int |
fe83a9ce | 501 | __gthread_objc_condition_signal (objc_condition_t condition) |
15794a95 L |
502 | { |
503 | if (__gthread_active_p ()) | |
72b16773 | 504 | return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); |
15794a95 L |
505 | else |
506 | return 0; | |
507 | } | |
508 | ||
509 | #else /* _LIBOBJC */ | |
510 | ||
f24af81b | 511 | static inline int |
d1e51320 | 512 | __gthread_once (__gthread_once_t *once, void (*func) (void)) |
f24af81b TT |
513 | { |
514 | if (__gthread_active_p ()) | |
72b16773 | 515 | return __gthrw_(pthread_once) (once, func); |
f24af81b TT |
516 | else |
517 | return -1; | |
518 | } | |
519 | ||
520 | static inline int | |
521 | __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) | |
522 | { | |
72b16773 | 523 | return __gthrw_(pthread_key_create) (key, dtor); |
f24af81b TT |
524 | } |
525 | ||
f24af81b TT |
526 | static inline int |
527 | __gthread_key_delete (__gthread_key_t key) | |
528 | { | |
72b16773 | 529 | return __gthrw_(pthread_key_delete) (key); |
f24af81b TT |
530 | } |
531 | ||
532 | static inline void * | |
533 | __gthread_getspecific (__gthread_key_t key) | |
534 | { | |
72b16773 | 535 | return __gthrw_(pthread_getspecific) (key); |
f24af81b TT |
536 | } |
537 | ||
538 | static inline int | |
539 | __gthread_setspecific (__gthread_key_t key, const void *ptr) | |
540 | { | |
72b16773 | 541 | return __gthrw_(pthread_setspecific) (key, ptr); |
f24af81b TT |
542 | } |
543 | ||
544 | static inline int | |
545 | __gthread_mutex_lock (__gthread_mutex_t *mutex) | |
546 | { | |
547 | if (__gthread_active_p ()) | |
72b16773 | 548 | return __gthrw_(pthread_mutex_lock) (mutex); |
f24af81b TT |
549 | else |
550 | return 0; | |
551 | } | |
552 | ||
553 | static inline int | |
554 | __gthread_mutex_trylock (__gthread_mutex_t *mutex) | |
555 | { | |
556 | if (__gthread_active_p ()) | |
72b16773 | 557 | return __gthrw_(pthread_mutex_trylock) (mutex); |
f24af81b TT |
558 | else |
559 | return 0; | |
560 | } | |
561 | ||
562 | static inline int | |
563 | __gthread_mutex_unlock (__gthread_mutex_t *mutex) | |
564 | { | |
565 | if (__gthread_active_p ()) | |
72b16773 | 566 | return __gthrw_(pthread_mutex_unlock) (mutex); |
f24af81b TT |
567 | else |
568 | return 0; | |
569 | } | |
570 | ||
ab3d1049 | 571 | #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP |
40aac948 JM |
572 | static inline int |
573 | __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) | |
574 | { | |
575 | if (__gthread_active_p ()) | |
576 | { | |
577 | pthread_mutexattr_t attr; | |
578 | int r; | |
579 | ||
72b16773 | 580 | r = __gthrw_(pthread_mutexattr_init) (&attr); |
40aac948 | 581 | if (!r) |
72b16773 | 582 | r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE); |
40aac948 | 583 | if (!r) |
72b16773 | 584 | r = __gthrw_(pthread_mutex_init) (mutex, &attr); |
40aac948 | 585 | if (!r) |
72b16773 | 586 | r = __gthrw_(pthread_mutexattr_destroy) (&attr); |
40aac948 JM |
587 | return r; |
588 | } | |
7c68fabb | 589 | return 0; |
40aac948 JM |
590 | } |
591 | #endif | |
592 | ||
593 | static inline int | |
594 | __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) | |
595 | { | |
596 | return __gthread_mutex_lock (mutex); | |
597 | } | |
598 | ||
599 | static inline int | |
600 | __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) | |
601 | { | |
602 | return __gthread_mutex_trylock (mutex); | |
603 | } | |
604 | ||
605 | static inline int | |
606 | __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) | |
607 | { | |
608 | return __gthread_mutex_unlock (mutex); | |
609 | } | |
610 | ||
15794a95 L |
611 | #endif /* _LIBOBJC */ |
612 | ||
88657302 | 613 | #endif /* ! GCC_GTHR_POSIX_H */ |