Mercurial > hg > CbC > CbC_gcc
annotate gcc/gthr-solaris.h @ 56:3c8a44c06a95
Added tag gcc-4.4.5 for changeset 77e2b8dfacca
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:41:23 +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, 2004, 2005, 2006, 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_SOLARIS_H | |
28 #define GCC_GTHR_SOLARIS_H | |
29 | |
30 /* Solaris threads as found in Solaris 2.[456]. | |
31 Actually these are Unix International (UI) threads, but I don't | |
32 know if anyone else implements these. */ | |
33 | |
34 #define __GTHREADS 1 | |
35 | |
36 #include <thread.h> | |
37 #include <errno.h> | |
38 | |
39 #ifdef __cplusplus | |
40 #define UNUSED(x) | |
41 #else | |
42 #define UNUSED(x) x __attribute__((unused)) | |
43 #endif | |
44 | |
45 typedef thread_key_t __gthread_key_t; | |
46 typedef struct { | |
47 mutex_t mutex; | |
48 int once; | |
49 } __gthread_once_t; | |
50 typedef mutex_t __gthread_mutex_t; | |
51 | |
52 typedef struct { | |
53 long depth; | |
54 thread_t owner; | |
55 mutex_t actual; | |
56 } __gthread_recursive_mutex_t; | |
57 | |
58 #define __GTHREAD_ONCE_INIT { DEFAULTMUTEX, 0 } | |
59 #define __GTHREAD_MUTEX_INIT DEFAULTMUTEX | |
60 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function | |
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(thr_keycreate) | |
72 __gthrw(thr_getspecific) | |
73 __gthrw(thr_setspecific) | |
74 __gthrw(thr_create) | |
75 __gthrw(thr_self) | |
76 | |
77 __gthrw(mutex_init) | |
78 __gthrw(mutex_destroy) | |
79 __gthrw(mutex_lock) | |
80 __gthrw(mutex_trylock) | |
81 __gthrw(mutex_unlock) | |
82 | |
83 #ifdef _LIBOBJC | |
84 __gthrw(thr_exit) | |
85 __gthrw(thr_getprio) | |
86 __gthrw(thr_setprio) | |
87 __gthrw(thr_yield) | |
88 | |
89 __gthrw(cond_init) | |
90 __gthrw(cond_destroy) | |
91 __gthrw(cond_wait) | |
92 __gthrw(cond_broadcast) | |
93 __gthrw(cond_signal) | |
94 | |
95 #endif | |
96 | |
97 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK | |
98 | |
99 /* This will not actually work in Solaris 2.5, since libc contains | |
100 dummy symbols of all thr_* routines. */ | |
101 | |
102 static inline int | |
103 __gthread_active_p (void) | |
104 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
105 static void *const __gthread_active_ptr |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
106 = __extension__ (void *) &__gthrw_(thr_create); |
0 | 107 return __gthread_active_ptr != 0; |
108 } | |
109 | |
110 #else /* not SUPPORTS_WEAK */ | |
111 | |
112 static inline int | |
113 __gthread_active_p (void) | |
114 { | |
115 return 1; | |
116 } | |
117 | |
118 #endif /* SUPPORTS_WEAK */ | |
119 | |
120 #ifdef _LIBOBJC | |
121 | |
122 /* Key structure for maintaining thread specific storage */ | |
123 static thread_key_t _objc_thread_storage; | |
124 | |
125 /* Thread local storage for a single thread */ | |
126 static void *thread_local_storage = NULL; | |
127 | |
128 /* Backend initialization functions */ | |
129 | |
130 /* Initialize the threads subsystem. */ | |
131 static inline int | |
132 __gthread_objc_init_thread_system (void) | |
133 { | |
134 /* Initialize the thread storage key. */ | |
135 if (__gthread_active_p () | |
136 && __gthrw_(thr_keycreate) (&_objc_thread_storage, NULL) == 0) | |
137 return 0; | |
138 | |
139 return -1; | |
140 } | |
141 | |
142 /* Close the threads subsystem. */ | |
143 static inline int | |
144 __gthread_objc_close_thread_system (void) | |
145 { | |
146 if (__gthread_active_p ()) | |
147 return 0; | |
148 else | |
149 return -1; | |
150 } | |
151 | |
152 /* Backend thread functions */ | |
153 | |
154 /* Create a new thread of execution. */ | |
155 static inline objc_thread_t | |
156 __gthread_objc_thread_detach (void (*func)(void *), void *arg) | |
157 { | |
158 objc_thread_t thread_id; | |
159 thread_t new_thread_id = 0; | |
160 | |
161 if (!__gthread_active_p ()) | |
162 return NULL; | |
163 | |
164 if (__gthrw_(thr_create) (NULL, 0, (void *) func, arg, | |
165 THR_DETACHED | THR_NEW_LWP, | |
166 &new_thread_id) == 0) | |
167 thread_id = *(objc_thread_t *) &new_thread_id; | |
168 else | |
169 thread_id = NULL; | |
170 | |
171 return thread_id; | |
172 } | |
173 | |
174 /* Set the current thread's priority. */ | |
175 static inline int | |
176 __gthread_objc_thread_set_priority (int priority) | |
177 { | |
178 int sys_priority = 0; | |
179 | |
180 if (!__gthread_active_p ()) | |
181 return -1; | |
182 | |
183 switch (priority) | |
184 { | |
185 case OBJC_THREAD_INTERACTIVE_PRIORITY: | |
186 sys_priority = 300; | |
187 break; | |
188 default: | |
189 case OBJC_THREAD_BACKGROUND_PRIORITY: | |
190 sys_priority = 200; | |
191 break; | |
192 case OBJC_THREAD_LOW_PRIORITY: | |
193 sys_priority = 1000; | |
194 break; | |
195 } | |
196 | |
197 /* Change priority */ | |
198 if (__gthrw_(thr_setprio) (__gthrw_(thr_self) (), sys_priority) == 0) | |
199 return 0; | |
200 else | |
201 return -1; | |
202 } | |
203 | |
204 /* Return the current thread's priority. */ | |
205 static inline int | |
206 __gthread_objc_thread_get_priority (void) | |
207 { | |
208 int sys_priority; | |
209 | |
210 if (!__gthread_active_p ()) | |
211 return OBJC_THREAD_INTERACTIVE_PRIORITY; | |
212 | |
213 if (__gthrw_(thr_getprio) (__gthrw_(thr_self) (), &sys_priority) == 0) | |
214 { | |
215 if (sys_priority >= 250) | |
216 return OBJC_THREAD_INTERACTIVE_PRIORITY; | |
217 else if (sys_priority >= 150) | |
218 return OBJC_THREAD_BACKGROUND_PRIORITY; | |
219 return OBJC_THREAD_LOW_PRIORITY; | |
220 } | |
221 | |
222 /* Couldn't get priority. */ | |
223 return -1; | |
224 } | |
225 | |
226 /* Yield our process time to another thread. */ | |
227 static inline void | |
228 __gthread_objc_thread_yield (void) | |
229 { | |
230 if (__gthread_active_p ()) | |
231 __gthrw_(thr_yield) (); | |
232 } | |
233 | |
234 /* Terminate the current thread. */ | |
235 static inline int | |
236 __gthread_objc_thread_exit (void) | |
237 { | |
238 if (__gthread_active_p ()) | |
239 /* exit the thread */ | |
240 __gthrw_(thr_exit) (&__objc_thread_exit_status); | |
241 | |
242 /* Failed if we reached here */ | |
243 return -1; | |
244 } | |
245 | |
246 /* Returns an integer value which uniquely describes a thread. */ | |
247 static inline objc_thread_t | |
248 __gthread_objc_thread_id (void) | |
249 { | |
250 if (__gthread_active_p ()) | |
251 return (objc_thread_t) __gthrw_(thr_self) (); | |
252 else | |
253 return (objc_thread_t) 1; | |
254 } | |
255 | |
256 /* Sets the thread's local storage pointer. */ | |
257 static inline int | |
258 __gthread_objc_thread_set_data (void *value) | |
259 { | |
260 if (__gthread_active_p ()) | |
261 { | |
262 if (__gthrw_(thr_setspecific) (_objc_thread_storage, value) == 0) | |
263 return 0; | |
264 else | |
265 return -1; | |
266 } | |
267 else | |
268 { | |
269 thread_local_storage = value; | |
270 return 0; | |
271 } | |
272 } | |
273 | |
274 /* Returns the thread's local storage pointer. */ | |
275 static inline void * | |
276 __gthread_objc_thread_get_data (void) | |
277 { | |
278 void *value = NULL; | |
279 | |
280 if (__gthread_active_p ()) | |
281 { | |
282 if (__gthrw_(thr_getspecific) (_objc_thread_storage, &value) == 0) | |
283 return value; | |
284 else | |
285 return NULL; | |
286 } | |
287 else | |
288 return thread_local_storage; | |
289 } | |
290 | |
291 /* Backend mutex functions */ | |
292 | |
293 /* Allocate a mutex. */ | |
294 static inline int | |
295 __gthread_objc_mutex_allocate (objc_mutex_t mutex) | |
296 { | |
297 if (__gthread_active_p () | |
298 && __gthrw_(mutex_init) ((mutex_t *) (&(mutex->backend)), USYNC_THREAD, 0)) | |
299 return -1; | |
300 | |
301 return 0; | |
302 } | |
303 | |
304 /* Deallocate a mutex. */ | |
305 static inline int | |
306 __gthread_objc_mutex_deallocate (objc_mutex_t mutex) | |
307 { | |
308 if (__gthread_active_p ()) | |
309 __gthrw_(mutex_destroy) ((mutex_t *) (&(mutex->backend))); | |
310 | |
311 return 0; | |
312 } | |
313 | |
314 /* Grab a lock on a mutex. */ | |
315 static inline int | |
316 __gthread_objc_mutex_lock (objc_mutex_t mutex) | |
317 { | |
318 if (__gthread_active_p () | |
319 && __gthrw_(mutex_lock) ((mutex_t *) (&(mutex->backend))) != 0) | |
320 return -1; | |
321 | |
322 return 0; | |
323 } | |
324 | |
325 /* Try to grab a lock on a mutex. */ | |
326 static inline int | |
327 __gthread_objc_mutex_trylock (objc_mutex_t mutex) | |
328 { | |
329 if (__gthread_active_p () | |
330 && __gthrw_(mutex_trylock) ((mutex_t *) (&(mutex->backend))) != 0) | |
331 return -1; | |
332 | |
333 return 0; | |
334 } | |
335 | |
336 /* Unlock the mutex */ | |
337 static inline int | |
338 __gthread_objc_mutex_unlock (objc_mutex_t mutex) | |
339 { | |
340 if (__gthread_active_p () | |
341 && __gthrw_(mutex_unlock) ((mutex_t *) (&(mutex->backend))) != 0) | |
342 return -1; | |
343 | |
344 return 0; | |
345 } | |
346 | |
347 /* Backend condition mutex functions */ | |
348 | |
349 /* Allocate a condition. */ | |
350 static inline int | |
351 __gthread_objc_condition_allocate (objc_condition_t condition) | |
352 { | |
353 if (__gthread_active_p ()) | |
354 return __gthrw_(cond_init) ((cond_t *) (&(condition->backend)), USYNC_THREAD, | |
355 NULL); | |
356 else | |
357 return 0; | |
358 } | |
359 | |
360 /* Deallocate a condition. */ | |
361 static inline int | |
362 __gthread_objc_condition_deallocate (objc_condition_t condition) | |
363 { | |
364 if (__gthread_active_p ()) | |
365 return __gthrw_(cond_destroy) ((cond_t *) (&(condition->backend))); | |
366 else | |
367 return 0; | |
368 } | |
369 | |
370 /* Wait on the condition */ | |
371 static inline int | |
372 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) | |
373 { | |
374 if (__gthread_active_p ()) | |
375 return __gthrw_(cond_wait) ((cond_t *) (&(condition->backend)), | |
376 (mutex_t *) (&(mutex->backend))); | |
377 else | |
378 return 0; | |
379 } | |
380 | |
381 /* Wake up all threads waiting on this condition. */ | |
382 static inline int | |
383 __gthread_objc_condition_broadcast (objc_condition_t condition) | |
384 { | |
385 if (__gthread_active_p ()) | |
386 return __gthrw_(cond_broadcast) ((cond_t *) (&(condition->backend))); | |
387 else | |
388 return 0; | |
389 } | |
390 | |
391 /* Wake up one thread waiting on this condition. */ | |
392 static inline int | |
393 __gthread_objc_condition_signal (objc_condition_t condition) | |
394 { | |
395 if (__gthread_active_p ()) | |
396 return __gthrw_(cond_signal) ((cond_t *) (&(condition->backend))); | |
397 else | |
398 return 0; | |
399 } | |
400 | |
401 #else /* _LIBOBJC */ | |
402 | |
403 static inline int | |
404 __gthread_once (__gthread_once_t *__once, void (*__func) (void)) | |
405 { | |
406 if (! __gthread_active_p ()) | |
407 return -1; | |
408 | |
409 if (__once == 0 || __func == 0) | |
410 return EINVAL; | |
411 | |
412 if (__once->once == 0) | |
413 { | |
414 int __status = __gthrw_(mutex_lock) (&__once->mutex); | |
415 if (__status != 0) | |
416 return __status; | |
417 if (__once->once == 0) | |
418 { | |
419 (*__func) (); | |
420 __once->once++; | |
421 } | |
422 __gthrw_(mutex_unlock) (&__once->mutex); | |
423 } | |
424 return 0; | |
425 } | |
426 | |
427 static inline int | |
428 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) | |
429 { | |
430 /* Solaris 2.5 contains thr_* routines no-op in libc, so test if we actually | |
431 got a reasonable key value, and if not, fail. */ | |
432 *__key = (__gthread_key_t)-1; | |
433 if (__gthrw_(thr_keycreate) (__key, __dtor) != 0 | |
434 || *__key == (__gthread_key_t)-1) | |
435 return -1; | |
436 else | |
437 return 0; | |
438 } | |
439 | |
440 static inline int | |
441 __gthread_key_delete (__gthread_key_t UNUSED (__key)) | |
442 { | |
443 /* Not possible. */ | |
444 return -1; | |
445 } | |
446 | |
447 static inline void * | |
448 __gthread_getspecific (__gthread_key_t __key) | |
449 { | |
450 void *__ptr; | |
451 if (__gthrw_(thr_getspecific) (__key, &__ptr) == 0) | |
452 return __ptr; | |
453 else | |
454 return 0; | |
455 } | |
456 | |
457 static inline int | |
458 __gthread_setspecific (__gthread_key_t __key, const void *__ptr) | |
459 { | |
460 return __gthrw_(thr_setspecific) (__key, (void *) __ptr); | |
461 } | |
462 | |
463 static inline int | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
464 __gthread_mutex_destroy (__gthread_mutex_t *__mutex) |
0 | 465 { |
466 if (__gthread_active_p ()) | |
467 return __gthrw_(mutex_destroy) (__mutex); | |
468 else | |
469 return 0; | |
470 } | |
471 | |
472 static inline int | |
473 __gthread_mutex_lock (__gthread_mutex_t *__mutex) | |
474 { | |
475 if (__gthread_active_p ()) | |
476 return __gthrw_(mutex_lock) (__mutex); | |
477 else | |
478 return 0; | |
479 } | |
480 | |
481 static inline int | |
482 __gthread_mutex_trylock (__gthread_mutex_t *__mutex) | |
483 { | |
484 if (__gthread_active_p ()) | |
485 return __gthrw_(mutex_trylock) (__mutex); | |
486 else | |
487 return 0; | |
488 } | |
489 | |
490 static inline int | |
491 __gthread_mutex_unlock (__gthread_mutex_t *__mutex) | |
492 { | |
493 if (__gthread_active_p ()) | |
494 return __gthrw_(mutex_unlock) (__mutex); | |
495 else | |
496 return 0; | |
497 } | |
498 | |
499 static inline int | |
500 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) | |
501 { | |
502 __mutex->depth = 0; | |
503 __mutex->owner = (thread_t) 0; | |
504 return __gthrw_(mutex_init) (&__mutex->actual, USYNC_THREAD, 0); | |
505 } | |
506 | |
507 static inline int | |
508 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) | |
509 { | |
510 if (__gthread_active_p ()) | |
511 { | |
512 thread_t __me = __gthrw_(thr_self) (); | |
513 | |
514 if (__mutex->owner != __me) | |
515 { | |
516 __gthrw_(mutex_lock) (&__mutex->actual); | |
517 __mutex->owner = __me; | |
518 } | |
519 | |
520 __mutex->depth++; | |
521 } | |
522 return 0; | |
523 } | |
524 | |
525 static inline int | |
526 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) | |
527 { | |
528 if (__gthread_active_p ()) | |
529 { | |
530 thread_t __me = __gthrw_(thr_self) (); | |
531 | |
532 if (__mutex->owner != __me) | |
533 { | |
534 if (__gthrw_(mutex_trylock) (&__mutex->actual)) | |
535 return 1; | |
536 __mutex->owner = __me; | |
537 } | |
538 | |
539 __mutex->depth++; | |
540 } | |
541 return 0; | |
542 } | |
543 | |
544 static inline int | |
545 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) | |
546 { | |
547 if (__gthread_active_p ()) | |
548 { | |
549 if (--__mutex->depth == 0) | |
550 { | |
551 __mutex->owner = (thread_t) 0; | |
552 __gthrw_(mutex_unlock) (&__mutex->actual); | |
553 } | |
554 } | |
555 return 0; | |
556 } | |
557 | |
558 #endif /* _LIBOBJC */ | |
559 | |
560 #undef UNUSED | |
561 | |
562 #endif /* ! GCC_GTHR_SOLARIS_H */ |