OSDN Git Service

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