OSDN Git Service

c2c24cdfe3114d460cbe9cdaea3af5d6674e27cf
[pf3gnuchains/gcc-fork.git] / gcc / gthr-dce.h
1
2 /* Compile this one with gcc.  */
3 /* Copyright (C) 1997, 1999, 2000 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 __gthr_dce_h
30 #define __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 typedef pthread_key_t __gthread_key_t;
41 typedef pthread_once_t __gthread_once_t;
42 typedef pthread_mutex_t __gthread_mutex_t;
43
44 #define __GTHREAD_ONCE_INIT pthread_once_init
45 /* Howto define __GTHREAD_MUTEX_INIT? */
46
47 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
48
49 #pragma weak pthread_once
50 #pragma weak pthread_once_init
51 #pragma weak pthread_keycreate
52 #pragma weak pthread_key_delete
53 #pragma weak pthread_getspecific
54 #pragma weak pthread_setspecific
55 #pragma weak pthread_create
56
57 #pragma weak pthread_mutex_lock
58 #pragma weak pthread_mutex_trylock
59 #pragma weak pthread_mutex_unlock
60
61 #ifdef _LIBOBJC
62 /* Objective C. */
63 #pragma weak pthread_cond_broadcast
64 #pragma weak pthread_cond_destroy
65 #pragma weak pthread_cond_init
66 #pragma weak pthread_cond_signal
67 #pragma weak pthread_cond_wait
68 #pragma weak pthread_exit
69 #pragma weak pthread_getunique_np
70 #pragma weak pthread_mutex_init
71 #pragma weak pthread_mutex_destroy
72 #pragma weak pthread_self
73 #pragma weak pthread_yield
74 #endif
75
76 static void *__gthread_active_ptr = &pthread_create;
77
78 static inline int
79 __gthread_active_p (void)
80 {
81   return __gthread_active_ptr != 0;
82 }
83
84 #else /* not SUPPORTS_WEAK */
85
86 static inline int
87 __gthread_active_p (void)
88 {
89   return 1;
90 }
91
92 #endif /* SUPPORTS_WEAK */
93
94 #ifdef _LIBOBJC
95
96 /* Key structure for maintaining thread specific storage */
97 static pthread_key_t _objc_thread_storage;
98
99 /* Thread local storage for a single thread */
100 static void *thread_local_storage = NULL;
101
102 /* Backend initialization functions */
103
104 /* Initialize the threads subsystem. */
105 static inline int
106 __gthread_objc_init_thread_system(void)
107 {
108   if (__gthread_active_p ())
109     /* Initialize the thread storage key */
110     return pthread_keycreate (&_objc_thread_storage, NULL);
111   else
112     return -1;
113 }
114
115 /* Close the threads subsystem. */
116 static inline int
117 __gthread_objc_close_thread_system(void)
118 {
119   if (__gthread_active_p ())
120     return 0;
121   else
122     return -1;
123 }
124
125 /* Backend thread functions */
126
127 /* Create a new thread of execution. */
128 static inline objc_thread_t
129 __gthread_objc_thread_detach(void (*func)(void *), void *arg)
130 {
131   objc_thread_t thread_id;
132   pthread_t new_thread_handle;
133
134   if (!__gthread_active_p ())
135     return NULL;
136  
137   if ( !(pthread_create(&new_thread_handle, pthread_attr_default,
138                         (void *)func, arg)) )
139     {
140       /* ??? May not work! (64bit) */
141       thread_id = *(objc_thread_t *)&new_thread_handle;
142       pthread_detach(&new_thread_handle); /* Fully detach thread. */
143     }
144   else
145     thread_id = NULL;
146   
147   return thread_id;
148 }
149
150 /* Set the current thread's priority. */
151 static inline int
152 __gthread_objc_thread_set_priority(int priority)
153 {
154   int sys_priority = 0;
155
156   if (!__gthread_active_p ())
157     return -1;
158
159   switch (priority)
160     {
161     case OBJC_THREAD_INTERACTIVE_PRIORITY:
162       sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
163       break;
164     default:
165     case OBJC_THREAD_BACKGROUND_PRIORITY:
166       sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
167       break;
168     case OBJC_THREAD_LOW_PRIORITY:
169       sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
170       break;
171     }
172     
173   /* Change the priority. */
174   if (pthread_setprio(pthread_self(), sys_priority) >= 0)
175     return 0;
176   else
177     /* Failed */
178     return -1;
179 }
180
181 /* Return the current thread's priority. */
182 static inline int
183 __gthread_objc_thread_get_priority(void)
184 {
185   int sys_priority;
186
187   if (__gthread_active_p ())
188     {
189       if ((sys_priority = pthread_getprio(pthread_self())) >= 0)
190         {
191           if (sys_priority >= PRI_FG_MIN_NP
192               && sys_priority <= PRI_FG_MAX_NP)
193             return OBJC_THREAD_INTERACTIVE_PRIORITY;
194           if (sys_priority >= PRI_BG_MIN_NP
195               && sys_priority <= PRI_BG_MAX_NP)
196             return OBJC_THREAD_BACKGROUND_PRIORITY;
197           return OBJC_THREAD_LOW_PRIORITY;
198         }
199
200       /* Failed */
201       return -1;
202     }
203   else
204     return OBJC_THREAD_INTERACTIVE_PRIORITY;
205 }
206
207 /* Yield our process time to another thread. */
208 static inline void
209 __gthread_objc_thread_yield(void)
210 {
211   if (__gthread_active_p ())
212     pthread_yield();
213 }
214
215 /* Terminate the current thread. */
216 static inline int
217 __gthread_objc_thread_exit(void)
218 {
219   if (__gthread_active_p ())
220     /* exit the thread */
221     pthread_exit(&__objc_thread_exit_status);
222
223   /* Failed if we reached here */
224   return -1;
225 }
226
227 /* Returns an integer value which uniquely describes a thread. */
228 static inline objc_thread_t
229 __gthread_objc_thread_id(void)
230 {
231   if (__gthread_active_p ())
232     {
233       pthread_t self = pthread_self();
234
235       return (objc_thread_t) pthread_getunique_np (&self);
236     }
237   else
238     return (objc_thread_t)1;
239 }
240
241 /* Sets the thread's local storage pointer. */
242 static inline int
243 __gthread_objc_thread_set_data(void *value)
244 {
245   if (__gthread_active_p ())
246     return pthread_setspecific(_objc_thread_storage, value);
247   else
248     {
249       thread_local_storage = value;
250       return 0;
251     }
252 }
253
254 /* Returns the thread's local storage pointer. */
255 static inline void *
256 __gthread_objc_thread_get_data(void)
257 {
258   void *value = NULL;
259
260   if (__gthread_active_p ())
261     {
262       if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
263         return value;
264
265       return NULL;
266     }
267   else
268     return thread_local_storage;
269 }
270
271 /* Backend mutex functions */
272
273 /* Allocate a mutex. */
274 static inline int
275 __gthread_objc_mutex_allocate(objc_mutex_t mutex)
276 {
277   if (__gthread_active_p ())
278     {
279       mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
280
281       if (pthread_mutex_init((pthread_mutex_t *)mutex->backend,
282                             pthread_mutexattr_default))
283         {
284           objc_free(mutex->backend);
285           mutex->backend = NULL;
286           return -1;
287         }
288     }
289
290   return 0;
291 }
292
293 /* Deallocate a mutex. */
294 static inline int
295 __gthread_objc_mutex_deallocate(objc_mutex_t mutex)
296 {
297   if (__gthread_active_p ()
298       && pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
299     return -1;
300
301   return 0;
302 }
303
304 /* Grab a lock on a mutex. */
305 static inline int
306 __gthread_objc_mutex_lock(objc_mutex_t mutex)
307 {
308   if (__gthread_active_p ())
309     return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
310   else
311     return 0;
312 }
313
314 /* Try to grab a lock on a mutex. */
315 static inline int
316 __gthread_objc_mutex_trylock(objc_mutex_t mutex)
317 {
318   if (__gthread_active_p ()
319       && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 1)
320     return -1;
321
322   return 0;
323 }
324
325 /* Unlock the mutex */
326 static inline int
327 __gthread_objc_mutex_unlock(objc_mutex_t mutex)
328 {
329   if (__gthread_active_p ())
330     return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
331   else
332     return 0;
333 }
334
335 /* Backend condition mutex functions */
336
337 /* Allocate a condition. */
338 static inline int
339 __gthread_objc_condition_allocate(objc_condition_t condition)
340 {
341   if (__gthread_active_p ())
342     /* Unimplemented. */
343     return -1;
344   else
345     return 0;
346 }
347
348 /* Deallocate a condition. */
349 static inline int
350 __gthread_objc_condition_deallocate(objc_condition_t condition)
351 {
352   if (__gthread_active_p ())
353     /* Unimplemented. */
354     return -1;
355   else
356     return 0;
357 }
358
359 /* Wait on the condition */
360 static inline int
361 __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
362 {
363   if (__gthread_active_p ())
364     /* Unimplemented. */
365     return -1;
366   else
367     return 0;
368 }
369
370 /* Wake up all threads waiting on this condition. */
371 static inline int
372 __gthread_objc_condition_broadcast(objc_condition_t condition)
373 {
374   if (__gthread_active_p ())
375     /* Unimplemented. */
376     return -1;
377   else
378     return 0;
379 }
380
381 /* Wake up one thread waiting on this condition. */
382 static inline int
383 __gthread_objc_condition_signal(objc_condition_t condition)
384 {
385   if (__gthread_active_p ())
386     /* Unimplemented. */
387     return -1;
388   else
389     return 0;
390 }
391
392 #else /* _LIBOBJC */
393
394 static inline int
395 __gthread_once (__gthread_once_t *once, void (*func) (void))
396 {
397   if (__gthread_active_p ())
398     return pthread_once (once, func);
399   else
400     return -1;
401 }
402
403 static inline int
404 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
405 {
406   return pthread_keycreate (key, dtor);
407 }
408
409 static inline int
410 __gthread_key_dtor (__gthread_key_t key, void *ptr)
411 {
412   /* Nothing needed. */
413   return 0;
414 }
415
416 static inline int
417 __gthread_key_delete (__gthread_key_t key)
418 {
419   return pthread_key_delete (key);
420 }
421
422 static inline void *
423 __gthread_getspecific (__gthread_key_t key)
424 {
425   void *ptr;
426   if (pthread_getspecific (key, &ptr) == 0)
427     return ptr;
428   else
429     return 0;
430 }
431
432 static inline int
433 __gthread_setspecific (__gthread_key_t key, const void *ptr)
434 {
435   return pthread_setspecific (key, (void *) ptr);
436 }
437
438 static inline int
439 __gthread_mutex_lock (__gthread_mutex_t *mutex)
440 {
441   if (__gthread_active_p ())
442     return pthread_mutex_lock (mutex);
443   else
444     return 0;
445 }
446
447 static inline int
448 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
449 {
450   if (__gthread_active_p ())
451     return pthread_mutex_trylock (mutex);
452   else
453     return 0;
454 }
455
456 static inline int
457 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
458 {
459   if (__gthread_active_p ())
460     return pthread_mutex_unlock (mutex);
461   else
462     return 0;
463 }
464
465 #endif /* _LIBOBJC */
466
467 #endif /* not __gthr_dce_h */