OSDN Git Service

* gcc.dg/asm-fs-1.c: Disable warnings when compiling.
[pf3gnuchains/gcc-fork.git] / gcc / gthr-dce.h
1
2 /* Compile this one with gcc.  */
3 /* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 /* As a special exception, if you link this library with other files,
23    some of which are compiled with GCC, to produce an executable,
24    this library does not by itself cause the resulting executable
25    to be covered by the GNU General Public License.
26    This exception does not however invalidate any other reasons why
27    the executable file might be covered by the GNU General Public License.  */
28
29 #ifndef GCC_GTHR_DCE_H
30 #define GCC_GTHR_DCE_H
31
32 /* If _DCE_THREADS is not defined, then we're building the single
33    threaded version of the libraries and do not want to reference
34    anything related to pthreads or dce.  */
35 #ifndef _DCE_THREADS
36 #include "gthr-single.h"
37 #else
38 /* DCE threads interface.
39    DCE threads are based on POSIX threads draft 4, and many things
40    have changed since then.  */
41
42 #define __GTHREADS 1
43
44 #include <pthread.h>
45
46 #ifdef __cplusplus
47 #define UNUSED(x) x
48 #else
49 #define UNUSED(x) x __attribute__((unused))
50 #endif
51
52 typedef pthread_key_t __gthread_key_t;
53 typedef pthread_once_t __gthread_once_t;
54 typedef pthread_mutex_t __gthread_mutex_t;
55
56 #define __GTHREAD_ONCE_INIT pthread_once_init
57
58 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
59
60 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
61
62 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
63
64 #pragma weak pthread_once
65 #pragma weak pthread_once_init
66 #pragma weak pthread_keycreate
67 #pragma weak pthread_key_delete
68 #pragma weak pthread_getspecific
69 #pragma weak pthread_setspecific
70 #pragma weak pthread_create
71 #pragma weak pthread_mutex_init
72 #pragma weak pthread_mutex_lock
73 #pragma weak pthread_mutex_trylock
74 #pragma weak pthread_mutex_unlock
75
76 #ifdef _LIBOBJC
77 /* Objective C.  */
78 #pragma weak pthread_cond_broadcast
79 #pragma weak pthread_cond_destroy
80 #pragma weak pthread_cond_init
81 #pragma weak pthread_cond_signal
82 #pragma weak pthread_cond_wait
83 #pragma weak pthread_exit
84 #pragma weak pthread_getunique_np
85 #pragma weak pthread_mutex_destroy
86 #pragma weak pthread_self
87 #pragma weak pthread_yield
88 #endif
89
90 static void *__gthread_active_ptr = (void *) &pthread_create;
91
92 static inline int
93 __gthread_active_p (void)
94 {
95   return __gthread_active_ptr != 0;
96 }
97
98 #else /* not SUPPORTS_WEAK */
99
100 static inline int
101 __gthread_active_p (void)
102 {
103   return 1;
104 }
105
106 #endif /* SUPPORTS_WEAK */
107
108 #ifdef _LIBOBJC
109
110 /* Key structure for maintaining thread specific storage */
111 static pthread_key_t _objc_thread_storage;
112
113 /* Thread local storage for a single thread */
114 static void *thread_local_storage = NULL;
115
116 /* Backend initialization functions */
117
118 /* Initialize the threads subsystem.  */
119 static inline int
120 __gthread_objc_init_thread_system(void)
121 {
122   if (__gthread_active_p ())
123     /* Initialize the thread storage key */
124     return pthread_keycreate (&_objc_thread_storage, NULL);
125   else
126     return -1;
127 }
128
129 /* Close the threads subsystem.  */
130 static inline int
131 __gthread_objc_close_thread_system(void)
132 {
133   if (__gthread_active_p ())
134     return 0;
135   else
136     return -1;
137 }
138
139 /* Backend thread functions */
140
141 /* Create a new thread of execution.  */
142 static inline objc_thread_t
143 __gthread_objc_thread_detach(void (*func)(void *), void *arg)
144 {
145   objc_thread_t thread_id;
146   pthread_t new_thread_handle;
147
148   if (!__gthread_active_p ())
149     return NULL;
150  
151   if ( !(pthread_create(&new_thread_handle, pthread_attr_default,
152                         (void *)func, arg)) )
153     {
154       /* ??? May not work! (64bit) */
155       thread_id = *(objc_thread_t *)&new_thread_handle;
156       pthread_detach(&new_thread_handle); /* Fully detach thread.  */
157     }
158   else
159     thread_id = NULL;
160   
161   return thread_id;
162 }
163
164 /* Set the current thread's priority.  */
165 static inline int
166 __gthread_objc_thread_set_priority(int priority)
167 {
168   int sys_priority = 0;
169
170   if (!__gthread_active_p ())
171     return -1;
172
173   switch (priority)
174     {
175     case OBJC_THREAD_INTERACTIVE_PRIORITY:
176       sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
177       break;
178     default:
179     case OBJC_THREAD_BACKGROUND_PRIORITY:
180       sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
181       break;
182     case OBJC_THREAD_LOW_PRIORITY:
183       sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
184       break;
185     }
186     
187   /* Change the priority.  */
188   if (pthread_setprio(pthread_self(), sys_priority) >= 0)
189     return 0;
190   else
191     /* Failed */
192     return -1;
193 }
194
195 /* Return the current thread's priority.  */
196 static inline int
197 __gthread_objc_thread_get_priority(void)
198 {
199   int sys_priority;
200
201   if (__gthread_active_p ())
202     {
203       if ((sys_priority = pthread_getprio(pthread_self())) >= 0)
204         {
205           if (sys_priority >= PRI_FG_MIN_NP
206               && sys_priority <= PRI_FG_MAX_NP)
207             return OBJC_THREAD_INTERACTIVE_PRIORITY;
208           if (sys_priority >= PRI_BG_MIN_NP
209               && sys_priority <= PRI_BG_MAX_NP)
210             return OBJC_THREAD_BACKGROUND_PRIORITY;
211           return OBJC_THREAD_LOW_PRIORITY;
212         }
213
214       /* Failed */
215       return -1;
216     }
217   else
218     return OBJC_THREAD_INTERACTIVE_PRIORITY;
219 }
220
221 /* Yield our process time to another thread.  */
222 static inline void
223 __gthread_objc_thread_yield(void)
224 {
225   if (__gthread_active_p ())
226     pthread_yield();
227 }
228
229 /* Terminate the current thread.  */
230 static inline int
231 __gthread_objc_thread_exit(void)
232 {
233   if (__gthread_active_p ())
234     /* exit the thread */
235     pthread_exit(&__objc_thread_exit_status);
236
237   /* Failed if we reached here */
238   return -1;
239 }
240
241 /* Returns an integer value which uniquely describes a thread.  */
242 static inline objc_thread_t
243 __gthread_objc_thread_id(void)
244 {
245   if (__gthread_active_p ())
246     {
247       pthread_t self = pthread_self();
248
249       return (objc_thread_t) pthread_getunique_np (&self);
250     }
251   else
252     return (objc_thread_t)1;
253 }
254
255 /* Sets the thread's local storage pointer.  */
256 static inline int
257 __gthread_objc_thread_set_data(void *value)
258 {
259   if (__gthread_active_p ())
260     return pthread_setspecific(_objc_thread_storage, value);
261   else
262     {
263       thread_local_storage = value;
264       return 0;
265     }
266 }
267
268 /* Returns the thread's local storage pointer.  */
269 static inline void *
270 __gthread_objc_thread_get_data(void)
271 {
272   void *value = NULL;
273
274   if (__gthread_active_p ())
275     {
276       if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
277         return value;
278
279       return NULL;
280     }
281   else
282     return thread_local_storage;
283 }
284
285 /* Backend mutex functions */
286
287 /* Allocate a mutex.  */
288 static inline int
289 __gthread_objc_mutex_allocate(objc_mutex_t mutex)
290 {
291   if (__gthread_active_p ())
292     {
293       mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
294
295       if (pthread_mutex_init((pthread_mutex_t *)mutex->backend,
296                             pthread_mutexattr_default))
297         {
298           objc_free(mutex->backend);
299           mutex->backend = NULL;
300           return -1;
301         }
302     }
303
304   return 0;
305 }
306
307 /* Deallocate a mutex.  */
308 static inline int
309 __gthread_objc_mutex_deallocate(objc_mutex_t mutex)
310 {
311   if (__gthread_active_p ())
312     {
313       if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
314         return -1;
315
316       objc_free(mutex->backend);
317       mutex->backend = NULL;
318     }
319
320   return 0;
321 }
322
323 /* Grab a lock on a mutex.  */
324 static inline int
325 __gthread_objc_mutex_lock(objc_mutex_t mutex)
326 {
327   if (__gthread_active_p ())
328     return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
329   else
330     return 0;
331 }
332
333 /* Try to grab a lock on a mutex.  */
334 static inline int
335 __gthread_objc_mutex_trylock(objc_mutex_t mutex)
336 {
337   if (__gthread_active_p ()
338       && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 1)
339     return -1;
340
341   return 0;
342 }
343
344 /* Unlock the mutex */
345 static inline int
346 __gthread_objc_mutex_unlock(objc_mutex_t mutex)
347 {
348   if (__gthread_active_p ())
349     return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
350   else
351     return 0;
352 }
353
354 /* Backend condition mutex functions */
355
356 /* Allocate a condition.  */
357 static inline int
358 __gthread_objc_condition_allocate(objc_condition_t condition)
359 {
360   if (__gthread_active_p ())
361     /* Unimplemented.  */
362     return -1;
363   else
364     return 0;
365 }
366
367 /* Deallocate a condition.  */
368 static inline int
369 __gthread_objc_condition_deallocate(objc_condition_t condition)
370 {
371   if (__gthread_active_p ())
372     /* Unimplemented.  */
373     return -1;
374   else
375     return 0;
376 }
377
378 /* Wait on the condition */
379 static inline int
380 __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
381 {
382   if (__gthread_active_p ())
383     /* Unimplemented.  */
384     return -1;
385   else
386     return 0;
387 }
388
389 /* Wake up all threads waiting on this condition.  */
390 static inline int
391 __gthread_objc_condition_broadcast(objc_condition_t condition)
392 {
393   if (__gthread_active_p ())
394     /* Unimplemented.  */
395     return -1;
396   else
397     return 0;
398 }
399
400 /* Wake up one thread waiting on this condition.  */
401 static inline int
402 __gthread_objc_condition_signal(objc_condition_t condition)
403 {
404   if (__gthread_active_p ())
405     /* Unimplemented.  */
406     return -1;
407   else
408     return 0;
409 }
410
411 #else /* _LIBOBJC */
412
413 static inline int
414 __gthread_once (__gthread_once_t *once, void (*func) (void))
415 {
416   if (__gthread_active_p ())
417     return pthread_once (once, func);
418   else
419     return -1;
420 }
421
422 static inline int
423 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
424 {
425   return pthread_keycreate (key, dtor);
426 }
427
428 static inline int
429 __gthread_key_dtor (UNUSED (__gthread_key_t key), UNUSED (void *ptr))
430 {
431   /* Nothing needed.  */
432   return 0;
433 }
434
435 static inline int
436 __gthread_key_delete (UNUSED (__gthread_key_t key))
437 {
438   /* Operation is not supported.  */
439   return -1;
440 }
441
442 static inline void *
443 __gthread_getspecific (__gthread_key_t key)
444 {
445   void *ptr;
446   if (pthread_getspecific (key, &ptr) == 0)
447     return ptr;
448   else
449     return 0;
450 }
451
452 static inline int
453 __gthread_setspecific (__gthread_key_t key, const void *ptr)
454 {
455   return pthread_setspecific (key, (void *) ptr);
456 }
457
458 static inline void
459 __gthread_mutex_init_function (__gthread_mutex_t *mutex)
460 {
461   if (__gthread_active_p ())
462     pthread_mutex_init (mutex, pthread_mutexattr_default);
463 }
464
465 static inline int
466 __gthread_mutex_lock (__gthread_mutex_t *mutex)
467 {
468   if (__gthread_active_p ())
469     return pthread_mutex_lock (mutex);
470   else
471     return 0;
472 }
473
474 static inline int
475 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
476 {
477   if (__gthread_active_p ())
478     return pthread_mutex_trylock (mutex);
479   else
480     return 0;
481 }
482
483 static inline int
484 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
485 {
486   if (__gthread_active_p ())
487     return pthread_mutex_unlock (mutex);
488   else
489     return 0;
490 }
491
492 #endif /* _LIBOBJC */
493
494 #undef UNUSED
495
496 #endif
497 #endif /* ! GCC_GTHR_DCE_H */