OSDN Git Service

PR target/39942
[pf3gnuchains/gcc-fork.git] / gcc / gthr-dce.h
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 */