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