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 */