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