OSDN Git Service

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