2009-05-06 Tobias Burnus <burnus@net-b.de>
[official-gcc/alias-decl.git] / gcc / gthr-dce.h
blobbe92813dc2394b3e10a9ae891aa5a0ef26d0d69c
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.
6 This file is part of GCC.
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.
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.
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.
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/>. */
27 #ifndef GCC_GTHR_DCE_H
28 #define GCC_GTHR_DCE_H
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. */
40 #define __GTHREADS 1
42 #include <pthread.h>
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;
49 #define __GTHREAD_ONCE_INIT pthread_once_init
51 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
52 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
54 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
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
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)
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)
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
95 __gthrw(pthread_mutex_destroy)
96 __gthrw(pthread_self)
97 __gthrw(pthread_yield)
98 #endif
100 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
102 static inline int
103 __gthread_active_p (void)
105 static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create);
106 return __gthread_active_ptr != 0;
109 #else /* not SUPPORTS_WEAK */
111 static inline int
112 __gthread_active_p (void)
114 return 1;
117 #endif /* SUPPORTS_WEAK */
119 #ifdef _LIBOBJC
121 /* Key structure for maintaining thread specific storage */
122 static pthread_key_t _objc_thread_storage;
124 /* Thread local storage for a single thread */
125 static void *thread_local_storage = NULL;
127 /* Backend initialization functions */
129 /* Initialize the threads subsystem. */
130 static inline int
131 __gthread_objc_init_thread_system (void)
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;
140 /* Close the threads subsystem. */
141 static inline int
142 __gthread_objc_close_thread_system (void)
144 if (__gthread_active_p ())
145 return 0;
146 else
147 return -1;
150 /* Backend thread functions */
152 /* Create a new thread of execution. */
153 static inline objc_thread_t
154 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
156 objc_thread_t thread_id;
157 pthread_t new_thread_handle;
159 if (!__gthread_active_p ())
160 return NULL;
162 if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default,
163 (void *) func, arg)))
165 /* ??? May not work! (64bit) */
166 thread_id = *(objc_thread_t *) &new_thread_handle;
167 pthread_detach (&new_thread_handle); /* Fully detach thread. */
169 else
170 thread_id = NULL;
172 return thread_id;
175 /* Set the current thread's priority. */
176 static inline int
177 __gthread_objc_thread_set_priority (int priority)
179 int sys_priority = 0;
181 if (!__gthread_active_p ())
182 return -1;
184 switch (priority)
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;
198 /* Change the priority. */
199 if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0)
200 return 0;
201 else
202 /* Failed */
203 return -1;
206 /* Return the current thread's priority. */
207 static inline int
208 __gthread_objc_thread_get_priority (void)
210 int sys_priority;
212 if (__gthread_active_p ())
214 if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0)
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;
225 /* Failed */
226 return -1;
228 else
229 return OBJC_THREAD_INTERACTIVE_PRIORITY;
232 /* Yield our process time to another thread. */
233 static inline void
234 __gthread_objc_thread_yield (void)
236 if (__gthread_active_p ())
237 __gthrw_(pthread_yield) ();
240 /* Terminate the current thread. */
241 static inline int
242 __gthread_objc_thread_exit (void)
244 if (__gthread_active_p ())
245 /* exit the thread */
246 __gthrw_(pthread_exit) (&__objc_thread_exit_status);
248 /* Failed if we reached here */
249 return -1;
252 /* Returns an integer value which uniquely describes a thread. */
253 static inline objc_thread_t
254 __gthread_objc_thread_id (void)
256 if (__gthread_active_p ())
258 pthread_t self = __gthrw_(pthread_self) ();
260 return (objc_thread_t) __gthrw_pthread_getunique_np (&self);
262 else
263 return (objc_thread_t) 1;
266 /* Sets the thread's local storage pointer. */
267 static inline int
268 __gthread_objc_thread_set_data (void *value)
270 if (__gthread_active_p ())
271 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
272 else
274 thread_local_storage = value;
275 return 0;
279 /* Returns the thread's local storage pointer. */
280 static inline void *
281 __gthread_objc_thread_get_data (void)
283 void *value = NULL;
285 if (__gthread_active_p ())
287 if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value)))
288 return value;
290 return NULL;
292 else
293 return thread_local_storage;
296 /* Backend mutex functions */
298 /* Allocate a mutex. */
299 static inline int
300 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
302 if (__gthread_active_p ())
304 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
306 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend,
307 pthread_mutexattr_default))
309 objc_free (mutex->backend);
310 mutex->backend = NULL;
311 return -1;
315 return 0;
318 /* Deallocate a mutex. */
319 static inline int
320 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
322 if (__gthread_active_p ())
324 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
325 return -1;
327 objc_free (mutex->backend);
328 mutex->backend = NULL;
331 return 0;
334 /* Grab a lock on a mutex. */
335 static inline int
336 __gthread_objc_mutex_lock (objc_mutex_t mutex)
338 if (__gthread_active_p ())
339 return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend);
340 else
341 return 0;
344 /* Try to grab a lock on a mutex. */
345 static inline int
346 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
348 if (__gthread_active_p ()
349 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1)
350 return -1;
352 return 0;
355 /* Unlock the mutex */
356 static inline int
357 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
359 if (__gthread_active_p ())
360 return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
361 else
362 return 0;
365 /* Backend condition mutex functions */
367 /* Allocate a condition. */
368 static inline int
369 __gthread_objc_condition_allocate (objc_condition_t condition
370 __attribute__ ((__unused__)))
372 if (__gthread_active_p ())
373 /* Unimplemented. */
374 return -1;
375 else
376 return 0;
379 /* Deallocate a condition. */
380 static inline int
381 __gthread_objc_condition_deallocate (objc_condition_t condition
382 __attribute__ ((__unused__)))
384 if (__gthread_active_p ())
385 /* Unimplemented. */
386 return -1;
387 else
388 return 0;
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__)))
397 if (__gthread_active_p ())
398 /* Unimplemented. */
399 return -1;
400 else
401 return 0;
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__)))
409 if (__gthread_active_p ())
410 /* Unimplemented. */
411 return -1;
412 else
413 return 0;
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__)))
421 if (__gthread_active_p ())
422 /* Unimplemented. */
423 return -1;
424 else
425 return 0;
428 #else /* _LIBOBJC */
430 static inline int
431 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
433 if (__gthread_active_p ())
434 return __gthrw_(pthread_once) (__once, __func);
435 else
436 return -1;
439 static inline int
440 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
442 return __gthrw_(pthread_keycreate) (__key, __dtor);
445 static inline int
446 __gthread_key_delete (__gthread_key_t __key __attribute__ ((__unused__)))
448 /* Operation is not supported. */
449 return -1;
452 static inline void *
453 __gthread_getspecific (__gthread_key_t __key)
455 void *__ptr;
456 if (__gthrw_(pthread_getspecific) (__key, &__ptr) == 0)
457 return __ptr;
458 else
459 return 0;
462 static inline int
463 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
465 return __gthrw_(pthread_setspecific) (__key, (void *) __ptr);
468 static inline void
469 __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
471 if (__gthread_active_p ())
472 __gthrw_(pthread_mutex_init) (__mutex, pthread_mutexattr_default);
475 static inline int
476 __gthread_mutx_destroy (__gthread_mutex_t *__mutex)
478 if (__gthread_active_p ())
479 return __gthrw_(pthread_mutex_destroy) (__mutex);
480 else
481 return 0;
484 static inline int
485 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
487 if (__gthread_active_p ())
488 return __gthrw_(pthread_mutex_lock) (__mutex);
489 else
490 return 0;
493 static inline int
494 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
496 if (__gthread_active_p ())
497 return __gthrw_(pthread_mutex_trylock) (__mutex);
498 else
499 return 0;
502 static inline int
503 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
505 if (__gthread_active_p ())
506 return __gthrw_(pthread_mutex_unlock) (__mutex);
507 else
508 return 0;
511 static inline int
512 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
514 if (__gthread_active_p ())
516 pthread_mutexattr_t __attr;
517 int __r;
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;
529 return 0;
532 static inline int
533 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
535 return __gthread_mutex_lock (__mutex);
538 static inline int
539 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
541 return __gthread_mutex_trylock (__mutex);
544 static inline int
545 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
547 return __gthread_mutex_unlock (__mutex);
550 #endif /* _LIBOBJC */
552 #endif
553 #endif /* ! GCC_GTHR_DCE_H */