Mercurial > hg > CbC > CbC_gcc
comparison gcc/gthr-dce.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) 1997, 1999, 2000, 2001, 2004, 2005, 2008, 2009 | |
4 Free Software Foundation, Inc. | |
5 | |
6 This file is part of GCC. | |
7 | |
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 3, or (at your option) any later | |
11 version. | |
12 | |
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. | |
17 | |
18 Under Section 7 of GPL version 3, you are granted additional | |
19 permissions described in the GCC Runtime Library Exception, version | |
20 3.1, as published by the Free Software Foundation. | |
21 | |
22 You should have received a copy of the GNU General Public License and | |
23 a copy of the GCC Runtime Library Exception along with this program; | |
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
25 <http://www.gnu.org/licenses/>. */ | |
26 | |
27 #ifndef GCC_GTHR_DCE_H | |
28 #define GCC_GTHR_DCE_H | |
29 | |
30 /* If _DCE_THREADS is not defined, then we're building the single | |
31 threaded version of the libraries and do not want to reference | |
32 anything related to pthreads or dce. */ | |
33 #ifndef _DCE_THREADS | |
34 #include "gthr-single.h" | |
35 #else | |
36 /* DCE threads interface. | |
37 DCE threads are based on POSIX threads draft 4, and many things | |
38 have changed since then. */ | |
39 | |
40 #define __GTHREADS 1 | |
41 | |
42 #include <pthread.h> | |
43 | |
44 typedef pthread_key_t __gthread_key_t; | |
45 typedef pthread_once_t __gthread_once_t; | |
46 typedef pthread_mutex_t __gthread_mutex_t; | |
47 typedef pthread_mutex_t __gthread_recursive_mutex_t; | |
48 | |
49 #define __GTHREAD_ONCE_INIT pthread_once_init | |
50 | |
51 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function | |
52 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function | |
53 | |
54 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init | |
55 | |
56 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK | |
57 # define __gthrw(name) \ | |
58 static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))); | |
59 # define __gthrw_(name) __gthrw_ ## name | |
60 #else | |
61 # define __gthrw(name) | |
62 # define __gthrw_(name) name | |
63 #endif | |
64 | |
65 __gthrw(pthread_once) | |
66 __gthrw(pthread_keycreate) | |
67 __gthrw(pthread_getspecific) | |
68 __gthrw(pthread_setspecific) | |
69 __gthrw(pthread_create) | |
70 __gthrw(pthread_mutex_init) | |
71 __gthrw(pthread_mutex_destroy) | |
72 __gthrw(pthread_mutex_lock) | |
73 __gthrw(pthread_mutex_trylock) | |
74 __gthrw(pthread_mutex_unlock) | |
75 __gthrw(pthread_mutexattr_create) | |
76 __gthrw(pthread_mutexattr_setkind_np) | |
77 __gthrw(pthread_mutexattr_delete) | |
78 | |
79 #ifdef _LIBOBJC | |
80 /* Objective-C. */ | |
81 __gthrw(pthread_cond_broadcast) | |
82 __gthrw(pthread_cond_destroy) | |
83 __gthrw(pthread_cond_init) | |
84 __gthrw(pthread_cond_signal) | |
85 __gthrw(pthread_cond_wait) | |
86 __gthrw(pthread_exit) | |
87 | |
88 #ifdef pthread_getunique_np | |
89 # define __gthrw_pthread_getunique_np pthread_getunique_np | |
90 #else | |
91 __gthrw(pthread_getunique_np) | |
92 # define __gthrw_pthread_getunique_np __gthrw_(pthread_getunique_np) | |
93 #endif | |
94 | |
95 __gthrw(pthread_mutex_destroy) | |
96 __gthrw(pthread_self) | |
97 __gthrw(pthread_yield) | |
98 #endif | |
99 | |
100 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK | |
101 | |
102 static inline int | |
103 __gthread_active_p (void) | |
104 { | |
105 static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create); | |
106 return __gthread_active_ptr != 0; | |
107 } | |
108 | |
109 #else /* not SUPPORTS_WEAK */ | |
110 | |
111 static inline int | |
112 __gthread_active_p (void) | |
113 { | |
114 return 1; | |
115 } | |
116 | |
117 #endif /* SUPPORTS_WEAK */ | |
118 | |
119 #ifdef _LIBOBJC | |
120 | |
121 /* Key structure for maintaining thread specific storage */ | |
122 static pthread_key_t _objc_thread_storage; | |
123 | |
124 /* Thread local storage for a single thread */ | |
125 static void *thread_local_storage = NULL; | |
126 | |
127 /* Backend initialization functions */ | |
128 | |
129 /* Initialize the threads subsystem. */ | |
130 static inline int | |
131 __gthread_objc_init_thread_system (void) | |
132 { | |
133 if (__gthread_active_p ()) | |
134 /* Initialize the thread storage key. */ | |
135 return __gthrw_(pthread_keycreate) (&_objc_thread_storage, NULL); | |
136 else | |
137 return -1; | |
138 } | |
139 | |
140 /* Close the threads subsystem. */ | |
141 static inline int | |
142 __gthread_objc_close_thread_system (void) | |
143 { | |
144 if (__gthread_active_p ()) | |
145 return 0; | |
146 else | |
147 return -1; | |
148 } | |
149 | |
150 /* Backend thread functions */ | |
151 | |
152 /* Create a new thread of execution. */ | |
153 static inline objc_thread_t | |
154 __gthread_objc_thread_detach (void (*func)(void *), void *arg) | |
155 { | |
156 objc_thread_t thread_id; | |
157 pthread_t new_thread_handle; | |
158 | |
159 if (!__gthread_active_p ()) | |
160 return NULL; | |
161 | |
162 if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default, | |
163 (void *) func, arg))) | |
164 { | |
165 /* ??? May not work! (64bit) */ | |
166 thread_id = *(objc_thread_t *) &new_thread_handle; | |
167 pthread_detach (&new_thread_handle); /* Fully detach thread. */ | |
168 } | |
169 else | |
170 thread_id = NULL; | |
171 | |
172 return thread_id; | |
173 } | |
174 | |
175 /* Set the current thread's priority. */ | |
176 static inline int | |
177 __gthread_objc_thread_set_priority (int priority) | |
178 { | |
179 int sys_priority = 0; | |
180 | |
181 if (!__gthread_active_p ()) | |
182 return -1; | |
183 | |
184 switch (priority) | |
185 { | |
186 case OBJC_THREAD_INTERACTIVE_PRIORITY: | |
187 sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2; | |
188 break; | |
189 default: | |
190 case OBJC_THREAD_BACKGROUND_PRIORITY: | |
191 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; | |
192 break; | |
193 case OBJC_THREAD_LOW_PRIORITY: | |
194 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; | |
195 break; | |
196 } | |
197 | |
198 /* Change the priority. */ | |
199 if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0) | |
200 return 0; | |
201 else | |
202 /* Failed */ | |
203 return -1; | |
204 } | |
205 | |
206 /* Return the current thread's priority. */ | |
207 static inline int | |
208 __gthread_objc_thread_get_priority (void) | |
209 { | |
210 int sys_priority; | |
211 | |
212 if (__gthread_active_p ()) | |
213 { | |
214 if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0) | |
215 { | |
216 if (sys_priority >= PRI_FG_MIN_NP | |
217 && sys_priority <= PRI_FG_MAX_NP) | |
218 return OBJC_THREAD_INTERACTIVE_PRIORITY; | |
219 if (sys_priority >= PRI_BG_MIN_NP | |
220 && sys_priority <= PRI_BG_MAX_NP) | |
221 return OBJC_THREAD_BACKGROUND_PRIORITY; | |
222 return OBJC_THREAD_LOW_PRIORITY; | |
223 } | |
224 | |
225 /* Failed */ | |
226 return -1; | |
227 } | |
228 else | |
229 return OBJC_THREAD_INTERACTIVE_PRIORITY; | |
230 } | |
231 | |
232 /* Yield our process time to another thread. */ | |
233 static inline void | |
234 __gthread_objc_thread_yield (void) | |
235 { | |
236 if (__gthread_active_p ()) | |
237 __gthrw_(pthread_yield) (); | |
238 } | |
239 | |
240 /* Terminate the current thread. */ | |
241 static inline int | |
242 __gthread_objc_thread_exit (void) | |
243 { | |
244 if (__gthread_active_p ()) | |
245 /* exit the thread */ | |
246 __gthrw_(pthread_exit) (&__objc_thread_exit_status); | |
247 | |
248 /* Failed if we reached here */ | |
249 return -1; | |
250 } | |
251 | |
252 /* Returns an integer value which uniquely describes a thread. */ | |
253 static inline objc_thread_t | |
254 __gthread_objc_thread_id (void) | |
255 { | |
256 if (__gthread_active_p ()) | |
257 { | |
258 pthread_t self = __gthrw_(pthread_self) (); | |
259 | |
260 return (objc_thread_t) __gthrw_pthread_getunique_np (&self); | |
261 } | |
262 else | |
263 return (objc_thread_t) 1; | |
264 } | |
265 | |
266 /* Sets the thread's local storage pointer. */ | |
267 static inline int | |
268 __gthread_objc_thread_set_data (void *value) | |
269 { | |
270 if (__gthread_active_p ()) | |
271 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); | |
272 else | |
273 { | |
274 thread_local_storage = value; | |
275 return 0; | |
276 } | |
277 } | |
278 | |
279 /* Returns the thread's local storage pointer. */ | |
280 static inline void * | |
281 __gthread_objc_thread_get_data (void) | |
282 { | |
283 void *value = NULL; | |
284 | |
285 if (__gthread_active_p ()) | |
286 { | |
287 if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value))) | |
288 return value; | |
289 | |
290 return NULL; | |
291 } | |
292 else | |
293 return thread_local_storage; | |
294 } | |
295 | |
296 /* Backend mutex functions */ | |
297 | |
298 /* Allocate a mutex. */ | |
299 static inline int | |
300 __gthread_objc_mutex_allocate (objc_mutex_t mutex) | |
301 { | |
302 if (__gthread_active_p ()) | |
303 { | |
304 mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); | |
305 | |
306 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, | |
307 pthread_mutexattr_default)) | |
308 { | |
309 objc_free (mutex->backend); | |
310 mutex->backend = NULL; | |
311 return -1; | |
312 } | |
313 } | |
314 | |
315 return 0; | |
316 } | |
317 | |
318 /* Deallocate a mutex. */ | |
319 static inline int | |
320 __gthread_objc_mutex_deallocate (objc_mutex_t mutex) | |
321 { | |
322 if (__gthread_active_p ()) | |
323 { | |
324 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) | |
325 return -1; | |
326 | |
327 objc_free (mutex->backend); | |
328 mutex->backend = NULL; | |
329 } | |
330 | |
331 return 0; | |
332 } | |
333 | |
334 /* Grab a lock on a mutex. */ | |
335 static inline int | |
336 __gthread_objc_mutex_lock (objc_mutex_t mutex) | |
337 { | |
338 if (__gthread_active_p ()) | |
339 return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend); | |
340 else | |
341 return 0; | |
342 } | |
343 | |
344 /* Try to grab a lock on a mutex. */ | |
345 static inline int | |
346 __gthread_objc_mutex_trylock (objc_mutex_t mutex) | |
347 { | |
348 if (__gthread_active_p () | |
349 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1) | |
350 return -1; | |
351 | |
352 return 0; | |
353 } | |
354 | |
355 /* Unlock the mutex */ | |
356 static inline int | |
357 __gthread_objc_mutex_unlock (objc_mutex_t mutex) | |
358 { | |
359 if (__gthread_active_p ()) | |
360 return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); | |
361 else | |
362 return 0; | |
363 } | |
364 | |
365 /* Backend condition mutex functions */ | |
366 | |
367 /* Allocate a condition. */ | |
368 static inline int | |
369 __gthread_objc_condition_allocate (objc_condition_t condition | |
370 __attribute__ ((__unused__))) | |
371 { | |
372 if (__gthread_active_p ()) | |
373 /* Unimplemented. */ | |
374 return -1; | |
375 else | |
376 return 0; | |
377 } | |
378 | |
379 /* Deallocate a condition. */ | |
380 static inline int | |
381 __gthread_objc_condition_deallocate (objc_condition_t condition | |
382 __attribute__ ((__unused__))) | |
383 { | |
384 if (__gthread_active_p ()) | |
385 /* Unimplemented. */ | |
386 return -1; | |
387 else | |
388 return 0; | |
389 } | |
390 | |
391 /* Wait on the condition */ | |
392 static inline int | |
393 __gthread_objc_condition_wait (objc_condition_t condition | |
394 __attribute__ ((__unused__)), | |
395 objc_mutex_t mutex __attribute__ ((__unused__))) | |
396 { | |
397 if (__gthread_active_p ()) | |
398 /* Unimplemented. */ | |
399 return -1; | |
400 else | |
401 return 0; | |
402 } | |
403 | |
404 /* Wake up all threads waiting on this condition. */ | |
405 static inline int | |
406 __gthread_objc_condition_broadcast (objc_condition_t condition | |
407 __attribute__ ((__unused__))) | |
408 { | |
409 if (__gthread_active_p ()) | |
410 /* Unimplemented. */ | |
411 return -1; | |
412 else | |
413 return 0; | |
414 } | |
415 | |
416 /* Wake up one thread waiting on this condition. */ | |
417 static inline int | |
418 __gthread_objc_condition_signal (objc_condition_t condition | |
419 __attribute__ ((__unused__))) | |
420 { | |
421 if (__gthread_active_p ()) | |
422 /* Unimplemented. */ | |
423 return -1; | |
424 else | |
425 return 0; | |
426 } | |
427 | |
428 #else /* _LIBOBJC */ | |
429 | |
430 static inline int | |
431 __gthread_once (__gthread_once_t *__once, void (*__func) (void)) | |
432 { | |
433 if (__gthread_active_p ()) | |
434 return __gthrw_(pthread_once) (__once, __func); | |
435 else | |
436 return -1; | |
437 } | |
438 | |
439 static inline int | |
440 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) | |
441 { | |
442 return __gthrw_(pthread_keycreate) (__key, __dtor); | |
443 } | |
444 | |
445 static inline int | |
446 __gthread_key_delete (__gthread_key_t __key __attribute__ ((__unused__))) | |
447 { | |
448 /* Operation is not supported. */ | |
449 return -1; | |
450 } | |
451 | |
452 static inline void * | |
453 __gthread_getspecific (__gthread_key_t __key) | |
454 { | |
455 void *__ptr; | |
456 if (__gthrw_(pthread_getspecific) (__key, &__ptr) == 0) | |
457 return __ptr; | |
458 else | |
459 return 0; | |
460 } | |
461 | |
462 static inline int | |
463 __gthread_setspecific (__gthread_key_t __key, const void *__ptr) | |
464 { | |
465 return __gthrw_(pthread_setspecific) (__key, (void *) __ptr); | |
466 } | |
467 | |
468 static inline void | |
469 __gthread_mutex_init_function (__gthread_mutex_t *__mutex) | |
470 { | |
471 if (__gthread_active_p ()) | |
472 __gthrw_(pthread_mutex_init) (__mutex, pthread_mutexattr_default); | |
473 } | |
474 | |
475 static inline int | |
476 __gthread_mutx_destroy (__gthread_mutex_t *__mutex) | |
477 { | |
478 if (__gthread_active_p ()) | |
479 return __gthrw_(pthread_mutex_destroy) (__mutex); | |
480 else | |
481 return 0; | |
482 } | |
483 | |
484 static inline int | |
485 __gthread_mutex_lock (__gthread_mutex_t *__mutex) | |
486 { | |
487 if (__gthread_active_p ()) | |
488 return __gthrw_(pthread_mutex_lock) (__mutex); | |
489 else | |
490 return 0; | |
491 } | |
492 | |
493 static inline int | |
494 __gthread_mutex_trylock (__gthread_mutex_t *__mutex) | |
495 { | |
496 if (__gthread_active_p ()) | |
497 return __gthrw_(pthread_mutex_trylock) (__mutex); | |
498 else | |
499 return 0; | |
500 } | |
501 | |
502 static inline int | |
503 __gthread_mutex_unlock (__gthread_mutex_t *__mutex) | |
504 { | |
505 if (__gthread_active_p ()) | |
506 return __gthrw_(pthread_mutex_unlock) (__mutex); | |
507 else | |
508 return 0; | |
509 } | |
510 | |
511 static inline int | |
512 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) | |
513 { | |
514 if (__gthread_active_p ()) | |
515 { | |
516 pthread_mutexattr_t __attr; | |
517 int __r; | |
518 | |
519 __r = __gthrw_(pthread_mutexattr_create) (&__attr); | |
520 if (!__r) | |
521 __r = __gthrw_(pthread_mutexattr_setkind_np) (&__attr, | |
522 MUTEX_RECURSIVE_NP); | |
523 if (!__r) | |
524 __r = __gthrw_(pthread_mutex_init) (__mutex, __attr); | |
525 if (!__r) | |
526 __r = __gthrw_(pthread_mutexattr_delete) (&__attr); | |
527 return __r; | |
528 } | |
529 return 0; | |
530 } | |
531 | |
532 static inline int | |
533 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) | |
534 { | |
535 return __gthread_mutex_lock (__mutex); | |
536 } | |
537 | |
538 static inline int | |
539 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) | |
540 { | |
541 return __gthread_mutex_trylock (__mutex); | |
542 } | |
543 | |
544 static inline int | |
545 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) | |
546 { | |
547 return __gthread_mutex_unlock (__mutex); | |
548 } | |
549 | |
550 #endif /* _LIBOBJC */ | |
551 | |
552 #endif | |
553 #endif /* ! GCC_GTHR_DCE_H */ |