Fix for PR39557
[official-gcc.git] / gcc / gthr-dce.h
blob50b6fdb51e6931e1cb119ba1eb4deb3bf349cf0d
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 2, 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 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 /* As a special exception, if you link this library with other files,
24 some of which are compiled with GCC, to produce an executable,
25 this library does not by itself cause the resulting executable
26 to be covered by the GNU General Public License.
27 This exception does not however invalidate any other reasons why
28 the executable file might be covered by the GNU General Public License. */
30 #ifndef GCC_GTHR_DCE_H
31 #define GCC_GTHR_DCE_H
33 /* If _DCE_THREADS is not defined, then we're building the single
34 threaded version of the libraries and do not want to reference
35 anything related to pthreads or dce. */
36 #ifndef _DCE_THREADS
37 #include "gthr-single.h"
38 #else
39 /* DCE threads interface.
40 DCE threads are based on POSIX threads draft 4, and many things
41 have changed since then. */
43 #define __GTHREADS 1
45 #include <pthread.h>
47 typedef pthread_key_t __gthread_key_t;
48 typedef pthread_once_t __gthread_once_t;
49 typedef pthread_mutex_t __gthread_mutex_t;
50 typedef pthread_mutex_t __gthread_recursive_mutex_t;
52 #define __GTHREAD_ONCE_INIT pthread_once_init
54 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
55 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
57 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
59 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
60 # define __gthrw(name) \
61 static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
62 # define __gthrw_(name) __gthrw_ ## name
63 #else
64 # define __gthrw(name)
65 # define __gthrw_(name) name
66 #endif
68 __gthrw(pthread_once)
69 __gthrw(pthread_keycreate)
70 __gthrw(pthread_getspecific)
71 __gthrw(pthread_setspecific)
72 __gthrw(pthread_create)
73 __gthrw(pthread_mutex_init)
74 __gthrw(pthread_mutex_destroy)
75 __gthrw(pthread_mutex_lock)
76 __gthrw(pthread_mutex_trylock)
77 __gthrw(pthread_mutex_unlock)
78 __gthrw(pthread_mutexattr_create)
79 __gthrw(pthread_mutexattr_setkind_np)
80 __gthrw(pthread_mutexattr_delete)
82 #ifdef _LIBOBJC
83 /* Objective-C. */
84 __gthrw(pthread_cond_broadcast)
85 __gthrw(pthread_cond_destroy)
86 __gthrw(pthread_cond_init)
87 __gthrw(pthread_cond_signal)
88 __gthrw(pthread_cond_wait)
89 __gthrw(pthread_exit)
91 #ifdef pthread_getunique_np
92 # define __gthrw_pthread_getunique_np pthread_getunique_np
93 #else
94 __gthrw(pthread_getunique_np)
95 # define __gthrw_pthread_getunique_np __gthrw_(pthread_getunique_np)
96 #endif
98 __gthrw(pthread_mutex_destroy)
99 __gthrw(pthread_self)
100 __gthrw(pthread_yield)
101 #endif
103 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
105 static inline int
106 __gthread_active_p (void)
108 static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create);
109 return __gthread_active_ptr != 0;
112 #else /* not SUPPORTS_WEAK */
114 static inline int
115 __gthread_active_p (void)
117 return 1;
120 #endif /* SUPPORTS_WEAK */
122 #ifdef _LIBOBJC
124 /* Key structure for maintaining thread specific storage */
125 static pthread_key_t _objc_thread_storage;
127 /* Thread local storage for a single thread */
128 static void *thread_local_storage = NULL;
130 /* Backend initialization functions */
132 /* Initialize the threads subsystem. */
133 static inline int
134 __gthread_objc_init_thread_system (void)
136 if (__gthread_active_p ())
137 /* Initialize the thread storage key. */
138 return __gthrw_(pthread_keycreate) (&_objc_thread_storage, NULL);
139 else
140 return -1;
143 /* Close the threads subsystem. */
144 static inline int
145 __gthread_objc_close_thread_system (void)
147 if (__gthread_active_p ())
148 return 0;
149 else
150 return -1;
153 /* Backend thread functions */
155 /* Create a new thread of execution. */
156 static inline objc_thread_t
157 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
159 objc_thread_t thread_id;
160 pthread_t new_thread_handle;
162 if (!__gthread_active_p ())
163 return NULL;
165 if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default,
166 (void *) func, arg)))
168 /* ??? May not work! (64bit) */
169 thread_id = *(objc_thread_t *) &new_thread_handle;
170 pthread_detach (&new_thread_handle); /* Fully detach thread. */
172 else
173 thread_id = NULL;
175 return thread_id;
178 /* Set the current thread's priority. */
179 static inline int
180 __gthread_objc_thread_set_priority (int priority)
182 int sys_priority = 0;
184 if (!__gthread_active_p ())
185 return -1;
187 switch (priority)
189 case OBJC_THREAD_INTERACTIVE_PRIORITY:
190 sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
191 break;
192 default:
193 case OBJC_THREAD_BACKGROUND_PRIORITY:
194 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
195 break;
196 case OBJC_THREAD_LOW_PRIORITY:
197 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
198 break;
201 /* Change the priority. */
202 if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0)
203 return 0;
204 else
205 /* Failed */
206 return -1;
209 /* Return the current thread's priority. */
210 static inline int
211 __gthread_objc_thread_get_priority (void)
213 int sys_priority;
215 if (__gthread_active_p ())
217 if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0)
219 if (sys_priority >= PRI_FG_MIN_NP
220 && sys_priority <= PRI_FG_MAX_NP)
221 return OBJC_THREAD_INTERACTIVE_PRIORITY;
222 if (sys_priority >= PRI_BG_MIN_NP
223 && sys_priority <= PRI_BG_MAX_NP)
224 return OBJC_THREAD_BACKGROUND_PRIORITY;
225 return OBJC_THREAD_LOW_PRIORITY;
228 /* Failed */
229 return -1;
231 else
232 return OBJC_THREAD_INTERACTIVE_PRIORITY;
235 /* Yield our process time to another thread. */
236 static inline void
237 __gthread_objc_thread_yield (void)
239 if (__gthread_active_p ())
240 __gthrw_(pthread_yield) ();
243 /* Terminate the current thread. */
244 static inline int
245 __gthread_objc_thread_exit (void)
247 if (__gthread_active_p ())
248 /* exit the thread */
249 __gthrw_(pthread_exit) (&__objc_thread_exit_status);
251 /* Failed if we reached here */
252 return -1;
255 /* Returns an integer value which uniquely describes a thread. */
256 static inline objc_thread_t
257 __gthread_objc_thread_id (void)
259 if (__gthread_active_p ())
261 pthread_t self = __gthrw_(pthread_self) ();
263 return (objc_thread_t) __gthrw_pthread_getunique_np (&self);
265 else
266 return (objc_thread_t) 1;
269 /* Sets the thread's local storage pointer. */
270 static inline int
271 __gthread_objc_thread_set_data (void *value)
273 if (__gthread_active_p ())
274 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
275 else
277 thread_local_storage = value;
278 return 0;
282 /* Returns the thread's local storage pointer. */
283 static inline void *
284 __gthread_objc_thread_get_data (void)
286 void *value = NULL;
288 if (__gthread_active_p ())
290 if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value)))
291 return value;
293 return NULL;
295 else
296 return thread_local_storage;
299 /* Backend mutex functions */
301 /* Allocate a mutex. */
302 static inline int
303 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
305 if (__gthread_active_p ())
307 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
309 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend,
310 pthread_mutexattr_default))
312 objc_free (mutex->backend);
313 mutex->backend = NULL;
314 return -1;
318 return 0;
321 /* Deallocate a mutex. */
322 static inline int
323 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
325 if (__gthread_active_p ())
327 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
328 return -1;
330 objc_free (mutex->backend);
331 mutex->backend = NULL;
334 return 0;
337 /* Grab a lock on a mutex. */
338 static inline int
339 __gthread_objc_mutex_lock (objc_mutex_t mutex)
341 if (__gthread_active_p ())
342 return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend);
343 else
344 return 0;
347 /* Try to grab a lock on a mutex. */
348 static inline int
349 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
351 if (__gthread_active_p ()
352 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1)
353 return -1;
355 return 0;
358 /* Unlock the mutex */
359 static inline int
360 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
362 if (__gthread_active_p ())
363 return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
364 else
365 return 0;
368 /* Backend condition mutex functions */
370 /* Allocate a condition. */
371 static inline int
372 __gthread_objc_condition_allocate (objc_condition_t condition
373 __attribute__ ((__unused__)))
375 if (__gthread_active_p ())
376 /* Unimplemented. */
377 return -1;
378 else
379 return 0;
382 /* Deallocate a condition. */
383 static inline int
384 __gthread_objc_condition_deallocate (objc_condition_t condition
385 __attribute__ ((__unused__)))
387 if (__gthread_active_p ())
388 /* Unimplemented. */
389 return -1;
390 else
391 return 0;
394 /* Wait on the condition */
395 static inline int
396 __gthread_objc_condition_wait (objc_condition_t condition
397 __attribute__ ((__unused__)),
398 objc_mutex_t mutex __attribute__ ((__unused__)))
400 if (__gthread_active_p ())
401 /* Unimplemented. */
402 return -1;
403 else
404 return 0;
407 /* Wake up all threads waiting on this condition. */
408 static inline int
409 __gthread_objc_condition_broadcast (objc_condition_t condition
410 __attribute__ ((__unused__)))
412 if (__gthread_active_p ())
413 /* Unimplemented. */
414 return -1;
415 else
416 return 0;
419 /* Wake up one thread waiting on this condition. */
420 static inline int
421 __gthread_objc_condition_signal (objc_condition_t condition
422 __attribute__ ((__unused__)))
424 if (__gthread_active_p ())
425 /* Unimplemented. */
426 return -1;
427 else
428 return 0;
431 #else /* _LIBOBJC */
433 static inline int
434 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
436 if (__gthread_active_p ())
437 return __gthrw_(pthread_once) (__once, __func);
438 else
439 return -1;
442 static inline int
443 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
445 return __gthrw_(pthread_keycreate) (__key, __dtor);
448 static inline int
449 __gthread_key_delete (__gthread_key_t __key __attribute__ ((__unused__)))
451 /* Operation is not supported. */
452 return -1;
455 static inline void *
456 __gthread_getspecific (__gthread_key_t __key)
458 void *__ptr;
459 if (__gthrw_(pthread_getspecific) (__key, &__ptr) == 0)
460 return __ptr;
461 else
462 return 0;
465 static inline int
466 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
468 return __gthrw_(pthread_setspecific) (__key, (void *) __ptr);
471 static inline void
472 __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
474 if (__gthread_active_p ())
475 __gthrw_(pthread_mutex_init) (__mutex, pthread_mutexattr_default);
478 static inline int
479 __gthread_mutx_destroy (__gthread_mutex_t *__mutex)
481 if (__gthread_active_p ())
482 return __gthrw_(pthread_mutex_destroy) (__mutex);
483 else
484 return 0;
487 static inline int
488 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
490 if (__gthread_active_p ())
491 return __gthrw_(pthread_mutex_lock) (__mutex);
492 else
493 return 0;
496 static inline int
497 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
499 if (__gthread_active_p ())
500 return __gthrw_(pthread_mutex_trylock) (__mutex);
501 else
502 return 0;
505 static inline int
506 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
508 if (__gthread_active_p ())
509 return __gthrw_(pthread_mutex_unlock) (__mutex);
510 else
511 return 0;
514 static inline int
515 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
517 if (__gthread_active_p ())
519 pthread_mutexattr_t __attr;
520 int __r;
522 __r = __gthrw_(pthread_mutexattr_create) (&__attr);
523 if (!__r)
524 __r = __gthrw_(pthread_mutexattr_setkind_np) (&__attr,
525 MUTEX_RECURSIVE_NP);
526 if (!__r)
527 __r = __gthrw_(pthread_mutex_init) (__mutex, __attr);
528 if (!__r)
529 __r = __gthrw_(pthread_mutexattr_delete) (&__attr);
530 return __r;
532 return 0;
535 static inline int
536 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
538 return __gthread_mutex_lock (__mutex);
541 static inline int
542 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
544 return __gthread_mutex_trylock (__mutex);
547 static inline int
548 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
550 return __gthread_mutex_unlock (__mutex);
553 #endif /* _LIBOBJC */
555 #endif
556 #endif /* ! GCC_GTHR_DCE_H */