OSDN Git Service

ChangeLogs fixed, again.
[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 /* Make sure CONST_CAST2 (original in system.h) is defined.  */
41 #ifndef CONST_CAST2
42 #ifdef __cplusplus
43 #define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X))
44 #else
45 #define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
46 #endif
47 #endif
48
49 #define __GTHREADS 1
50
51 #include <pthread.h>
52
53 typedef pthread_key_t __gthread_key_t;
54 typedef pthread_once_t __gthread_once_t;
55 typedef pthread_mutex_t __gthread_mutex_t;
56 typedef pthread_mutex_t __gthread_recursive_mutex_t;
57
58 #define __GTHREAD_ONCE_INIT pthread_once_init
59
60 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
61 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
62
63 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
64
65 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
66 # define __gthrw(name) \
67   static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
68 # define __gthrw_(name) __gthrw_ ## name
69 #else
70 # define __gthrw(name)
71 # define __gthrw_(name) name
72 #endif
73
74 __gthrw(pthread_once)
75 __gthrw(pthread_keycreate)
76 __gthrw(pthread_getspecific)
77 __gthrw(pthread_setspecific)
78 __gthrw(pthread_create)
79 __gthrw(pthread_mutex_init)
80 __gthrw(pthread_mutex_destroy)
81 __gthrw(pthread_mutex_lock)
82 __gthrw(pthread_mutex_trylock)
83 __gthrw(pthread_mutex_unlock)
84 __gthrw(pthread_mutexattr_create)
85 __gthrw(pthread_mutexattr_setkind_np)
86 __gthrw(pthread_mutexattr_delete)
87
88 #ifdef _LIBOBJC
89 /* Objective-C.  */
90 __gthrw(pthread_cond_broadcast)
91 __gthrw(pthread_cond_destroy)
92 __gthrw(pthread_cond_init)
93 __gthrw(pthread_cond_signal)
94 __gthrw(pthread_cond_wait)
95 __gthrw(pthread_exit)
96
97 #ifdef pthread_getunique_np
98 # define __gthrw_pthread_getunique_np pthread_getunique_np
99 #else
100 __gthrw(pthread_getunique_np)
101 # define __gthrw_pthread_getunique_np __gthrw_(pthread_getunique_np)
102 #endif
103
104 __gthrw(pthread_mutex_destroy)
105 __gthrw(pthread_self)
106 __gthrw(pthread_yield)
107 #endif
108
109 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
110
111 static inline int
112 __gthread_active_p (void)
113 {
114   static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create);
115   return __gthread_active_ptr != 0;
116 }
117
118 #else /* not SUPPORTS_WEAK */
119
120 static inline int
121 __gthread_active_p (void)
122 {
123   return 1;
124 }
125
126 #endif /* SUPPORTS_WEAK */
127
128 #ifdef _LIBOBJC
129
130 /* Key structure for maintaining thread specific storage */
131 static pthread_key_t _objc_thread_storage;
132
133 /* Thread local storage for a single thread */
134 static void *thread_local_storage = NULL;
135
136 /* Backend initialization functions */
137
138 /* Initialize the threads subsystem.  */
139 static inline int
140 __gthread_objc_init_thread_system (void)
141 {
142   if (__gthread_active_p ())
143     /* Initialize the thread storage key.  */
144     return __gthrw_(pthread_keycreate) (&_objc_thread_storage, NULL);
145   else
146     return -1;
147 }
148
149 /* Close the threads subsystem.  */
150 static inline int
151 __gthread_objc_close_thread_system (void)
152 {
153   if (__gthread_active_p ())
154     return 0;
155   else
156     return -1;
157 }
158
159 /* Backend thread functions */
160
161 /* Create a new thread of execution.  */
162 static inline objc_thread_t
163 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
164 {
165   objc_thread_t thread_id;
166   pthread_t new_thread_handle;
167
168   if (!__gthread_active_p ())
169     return NULL;
170
171   if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default,
172                         (void *) func, arg)))
173     {
174       /* ??? May not work! (64bit) */
175       thread_id = *(objc_thread_t *) &new_thread_handle;
176       pthread_detach (&new_thread_handle); /* Fully detach thread.  */
177     }
178   else
179     thread_id = NULL;
180
181   return thread_id;
182 }
183
184 /* Set the current thread's priority.  */
185 static inline int
186 __gthread_objc_thread_set_priority (int priority)
187 {
188   int sys_priority = 0;
189
190   if (!__gthread_active_p ())
191     return -1;
192
193   switch (priority)
194     {
195     case OBJC_THREAD_INTERACTIVE_PRIORITY:
196       sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
197       break;
198     default:
199     case OBJC_THREAD_BACKGROUND_PRIORITY:
200       sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
201       break;
202     case OBJC_THREAD_LOW_PRIORITY:
203       sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
204       break;
205     }
206
207   /* Change the priority.  */
208   if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0)
209     return 0;
210   else
211     /* Failed */
212     return -1;
213 }
214
215 /* Return the current thread's priority.  */
216 static inline int
217 __gthread_objc_thread_get_priority (void)
218 {
219   int sys_priority;
220
221   if (__gthread_active_p ())
222     {
223       if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0)
224         {
225           if (sys_priority >= PRI_FG_MIN_NP
226               && sys_priority <= PRI_FG_MAX_NP)
227             return OBJC_THREAD_INTERACTIVE_PRIORITY;
228           if (sys_priority >= PRI_BG_MIN_NP
229               && sys_priority <= PRI_BG_MAX_NP)
230             return OBJC_THREAD_BACKGROUND_PRIORITY;
231           return OBJC_THREAD_LOW_PRIORITY;
232         }
233
234       /* Failed */
235       return -1;
236     }
237   else
238     return OBJC_THREAD_INTERACTIVE_PRIORITY;
239 }
240
241 /* Yield our process time to another thread.  */
242 static inline void
243 __gthread_objc_thread_yield (void)
244 {
245   if (__gthread_active_p ())
246     __gthrw_(pthread_yield) ();
247 }
248
249 /* Terminate the current thread.  */
250 static inline int
251 __gthread_objc_thread_exit (void)
252 {
253   if (__gthread_active_p ())
254     /* exit the thread */
255     __gthrw_(pthread_exit) (&__objc_thread_exit_status);
256
257   /* Failed if we reached here */
258   return -1;
259 }
260
261 /* Returns an integer value which uniquely describes a thread.  */
262 static inline objc_thread_t
263 __gthread_objc_thread_id (void)
264 {
265   if (__gthread_active_p ())
266     {
267       pthread_t self = __gthrw_(pthread_self) ();
268
269       return (objc_thread_t) __gthrw_pthread_getunique_np (&self);
270     }
271   else
272     return (objc_thread_t) 1;
273 }
274
275 /* Sets the thread's local storage pointer.  */
276 static inline int
277 __gthread_objc_thread_set_data (void *value)
278 {
279   if (__gthread_active_p ())
280     return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
281   else
282     {
283       thread_local_storage = value;
284       return 0;
285     }
286 }
287
288 /* Returns the thread's local storage pointer.  */
289 static inline void *
290 __gthread_objc_thread_get_data (void)
291 {
292   void *value = NULL;
293
294   if (__gthread_active_p ())
295     {
296       if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value)))
297         return value;
298
299       return NULL;
300     }
301   else
302     return thread_local_storage;
303 }
304
305 /* Backend mutex functions */
306
307 /* Allocate a mutex.  */
308 static inline int
309 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
310 {
311   if (__gthread_active_p ())
312     {
313       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
314
315       if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend,
316                               pthread_mutexattr_default))
317         {
318           objc_free (mutex->backend);
319           mutex->backend = NULL;
320           return -1;
321         }
322     }
323
324   return 0;
325 }
326
327 /* Deallocate a mutex.  */
328 static inline int
329 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
330 {
331   if (__gthread_active_p ())
332     {
333       if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
334         return -1;
335
336       objc_free (mutex->backend);
337       mutex->backend = NULL;
338     }
339
340   return 0;
341 }
342
343 /* Grab a lock on a mutex.  */
344 static inline int
345 __gthread_objc_mutex_lock (objc_mutex_t mutex)
346 {
347   if (__gthread_active_p ())
348     return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend);
349   else
350     return 0;
351 }
352
353 /* Try to grab a lock on a mutex.  */
354 static inline int
355 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
356 {
357   if (__gthread_active_p ()
358       && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1)
359     return -1;
360
361   return 0;
362 }
363
364 /* Unlock the mutex */
365 static inline int
366 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
367 {
368   if (__gthread_active_p ())
369     return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
370   else
371     return 0;
372 }
373
374 /* Backend condition mutex functions */
375
376 /* Allocate a condition.  */
377 static inline int
378 __gthread_objc_condition_allocate (objc_condition_t condition
379                                    __attribute__ ((__unused__)))
380 {
381   if (__gthread_active_p ())
382     /* Unimplemented.  */
383     return -1;
384   else
385     return 0;
386 }
387
388 /* Deallocate a condition.  */
389 static inline int
390 __gthread_objc_condition_deallocate (objc_condition_t condition
391                                      __attribute__ ((__unused__)))
392 {
393   if (__gthread_active_p ())
394     /* Unimplemented.  */
395     return -1;
396   else
397     return 0;
398 }
399
400 /* Wait on the condition */
401 static inline int
402 __gthread_objc_condition_wait (objc_condition_t condition
403                                __attribute__ ((__unused__)),
404                                objc_mutex_t mutex __attribute__ ((__unused__)))
405 {
406   if (__gthread_active_p ())
407     /* Unimplemented.  */
408     return -1;
409   else
410     return 0;
411 }
412
413 /* Wake up all threads waiting on this condition.  */
414 static inline int
415 __gthread_objc_condition_broadcast (objc_condition_t condition
416                                     __attribute__ ((__unused__)))
417 {
418   if (__gthread_active_p ())
419     /* Unimplemented.  */
420     return -1;
421   else
422     return 0;
423 }
424
425 /* Wake up one thread waiting on this condition.  */
426 static inline int
427 __gthread_objc_condition_signal (objc_condition_t condition
428                                  __attribute__ ((__unused__)))
429 {
430   if (__gthread_active_p ())
431     /* Unimplemented.  */
432     return -1;
433   else
434     return 0;
435 }
436
437 #else /* _LIBOBJC */
438
439 static inline int
440 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
441 {
442   if (__gthread_active_p ())
443     return __gthrw_(pthread_once) (__once, __func);
444   else
445     return -1;
446 }
447
448 static inline int
449 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
450 {
451   return __gthrw_(pthread_keycreate) (__key, __dtor);
452 }
453
454 static inline int
455 __gthread_key_delete (__gthread_key_t __key __attribute__ ((__unused__)))
456 {
457   /* Operation is not supported.  */
458   return -1;
459 }
460
461 static inline void *
462 __gthread_getspecific (__gthread_key_t __key)
463 {
464   void *__ptr;
465   if (__gthrw_(pthread_getspecific) (__key, &__ptr) == 0)
466     return __ptr;
467   else
468     return 0;
469 }
470
471 static inline int
472 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
473 {
474   return __gthrw_(pthread_setspecific)
475     (__key, CONST_CAST2(void *, const void *, __ptr));
476 }
477
478 static inline void
479 __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
480 {
481   if (__gthread_active_p ())
482     __gthrw_(pthread_mutex_init) (__mutex, pthread_mutexattr_default);
483 }
484
485 static inline int
486 __gthread_mutx_destroy (__gthread_mutex_t *__mutex)
487 {
488   if (__gthread_active_p ())
489     return __gthrw_(pthread_mutex_destroy) (__mutex);
490   else
491     return 0;
492 }
493
494 static inline int
495 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
496 {
497   if (__gthread_active_p ())
498     return __gthrw_(pthread_mutex_lock) (__mutex);
499   else
500     return 0;
501 }
502
503 static inline int
504 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
505 {
506   if (__gthread_active_p ())
507     return __gthrw_(pthread_mutex_trylock) (__mutex);
508   else
509     return 0;
510 }
511
512 static inline int
513 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
514 {
515   if (__gthread_active_p ())
516     return __gthrw_(pthread_mutex_unlock) (__mutex);
517   else
518     return 0;
519 }
520
521 static inline int
522 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
523 {
524   if (__gthread_active_p ())
525     {
526       pthread_mutexattr_t __attr;
527       int __r;
528
529       __r = __gthrw_(pthread_mutexattr_create) (&__attr);
530       if (!__r)
531         __r = __gthrw_(pthread_mutexattr_setkind_np) (&__attr,
532                                                       MUTEX_RECURSIVE_NP);
533       if (!__r)
534         __r = __gthrw_(pthread_mutex_init) (__mutex, __attr);
535       if (!__r)
536         __r = __gthrw_(pthread_mutexattr_delete) (&__attr);
537       return __r;
538     }
539   return 0;
540 }
541
542 static inline int
543 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
544 {
545   return __gthread_mutex_lock (__mutex);
546 }
547
548 static inline int
549 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
550 {
551   return __gthread_mutex_trylock (__mutex);
552 }
553
554 static inline int
555 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
556 {
557   return __gthread_mutex_unlock (__mutex);
558 }
559
560 #endif /* _LIBOBJC */
561
562 #endif
563 #endif /* ! GCC_GTHR_DCE_H */