2002-04-24 Aldy Hernandez <aldyh@redhat.com>
[official-gcc.git] / gcc / gthr-dce.h
blob957f227292470db52602684861150b1fdba779e1
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GCC.
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.
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.
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. */
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. */
29 #ifndef GCC_GTHR_DCE_H
30 #define GCC_GTHR_DCE_H
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. */
42 #define __GTHREADS 1
44 #include <pthread.h>
46 #ifdef __cplusplus
47 #define UNUSED(x) x
48 #else
49 #define UNUSED(x) x __attribute__((unused))
50 #endif
52 typedef pthread_key_t __gthread_key_t;
53 typedef pthread_once_t __gthread_once_t;
54 typedef pthread_mutex_t __gthread_mutex_t;
56 #define __GTHREAD_ONCE_INIT pthread_once_init
58 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
60 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
62 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
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
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
90 static inline int
91 __gthread_active_p (void)
93 static void *const __gthread_active_ptr = (void *) &pthread_create;
94 return __gthread_active_ptr != 0;
97 #else /* not SUPPORTS_WEAK */
99 static inline int
100 __gthread_active_p (void)
102 return 1;
105 #endif /* SUPPORTS_WEAK */
107 #ifdef _LIBOBJC
109 /* Key structure for maintaining thread specific storage */
110 static pthread_key_t _objc_thread_storage;
112 /* Thread local storage for a single thread */
113 static void *thread_local_storage = NULL;
115 /* Backend initialization functions */
117 /* Initialize the threads subsystem. */
118 static inline int
119 __gthread_objc_init_thread_system(void)
121 if (__gthread_active_p ())
122 /* Initialize the thread storage key */
123 return pthread_keycreate (&_objc_thread_storage, NULL);
124 else
125 return -1;
128 /* Close the threads subsystem. */
129 static inline int
130 __gthread_objc_close_thread_system(void)
132 if (__gthread_active_p ())
133 return 0;
134 else
135 return -1;
138 /* Backend thread functions */
140 /* Create a new thread of execution. */
141 static inline objc_thread_t
142 __gthread_objc_thread_detach(void (*func)(void *), void *arg)
144 objc_thread_t thread_id;
145 pthread_t new_thread_handle;
147 if (!__gthread_active_p ())
148 return NULL;
150 if ( !(pthread_create(&new_thread_handle, pthread_attr_default,
151 (void *)func, arg)) )
153 /* ??? May not work! (64bit) */
154 thread_id = *(objc_thread_t *)&new_thread_handle;
155 pthread_detach(&new_thread_handle); /* Fully detach thread. */
157 else
158 thread_id = NULL;
160 return thread_id;
163 /* Set the current thread's priority. */
164 static inline int
165 __gthread_objc_thread_set_priority(int priority)
167 int sys_priority = 0;
169 if (!__gthread_active_p ())
170 return -1;
172 switch (priority)
174 case OBJC_THREAD_INTERACTIVE_PRIORITY:
175 sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
176 break;
177 default:
178 case OBJC_THREAD_BACKGROUND_PRIORITY:
179 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
180 break;
181 case OBJC_THREAD_LOW_PRIORITY:
182 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
183 break;
186 /* Change the priority. */
187 if (pthread_setprio(pthread_self(), sys_priority) >= 0)
188 return 0;
189 else
190 /* Failed */
191 return -1;
194 /* Return the current thread's priority. */
195 static inline int
196 __gthread_objc_thread_get_priority(void)
198 int sys_priority;
200 if (__gthread_active_p ())
202 if ((sys_priority = pthread_getprio(pthread_self())) >= 0)
204 if (sys_priority >= PRI_FG_MIN_NP
205 && sys_priority <= PRI_FG_MAX_NP)
206 return OBJC_THREAD_INTERACTIVE_PRIORITY;
207 if (sys_priority >= PRI_BG_MIN_NP
208 && sys_priority <= PRI_BG_MAX_NP)
209 return OBJC_THREAD_BACKGROUND_PRIORITY;
210 return OBJC_THREAD_LOW_PRIORITY;
213 /* Failed */
214 return -1;
216 else
217 return OBJC_THREAD_INTERACTIVE_PRIORITY;
220 /* Yield our process time to another thread. */
221 static inline void
222 __gthread_objc_thread_yield(void)
224 if (__gthread_active_p ())
225 pthread_yield();
228 /* Terminate the current thread. */
229 static inline int
230 __gthread_objc_thread_exit(void)
232 if (__gthread_active_p ())
233 /* exit the thread */
234 pthread_exit(&__objc_thread_exit_status);
236 /* Failed if we reached here */
237 return -1;
240 /* Returns an integer value which uniquely describes a thread. */
241 static inline objc_thread_t
242 __gthread_objc_thread_id(void)
244 if (__gthread_active_p ())
246 pthread_t self = pthread_self();
248 return (objc_thread_t) pthread_getunique_np (&self);
250 else
251 return (objc_thread_t)1;
254 /* Sets the thread's local storage pointer. */
255 static inline int
256 __gthread_objc_thread_set_data(void *value)
258 if (__gthread_active_p ())
259 return pthread_setspecific(_objc_thread_storage, value);
260 else
262 thread_local_storage = value;
263 return 0;
267 /* Returns the thread's local storage pointer. */
268 static inline void *
269 __gthread_objc_thread_get_data(void)
271 void *value = NULL;
273 if (__gthread_active_p ())
275 if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
276 return value;
278 return NULL;
280 else
281 return thread_local_storage;
284 /* Backend mutex functions */
286 /* Allocate a mutex. */
287 static inline int
288 __gthread_objc_mutex_allocate(objc_mutex_t mutex)
290 if (__gthread_active_p ())
292 mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
294 if (pthread_mutex_init((pthread_mutex_t *)mutex->backend,
295 pthread_mutexattr_default))
297 objc_free(mutex->backend);
298 mutex->backend = NULL;
299 return -1;
303 return 0;
306 /* Deallocate a mutex. */
307 static inline int
308 __gthread_objc_mutex_deallocate(objc_mutex_t mutex)
310 if (__gthread_active_p ())
312 if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
313 return -1;
315 objc_free(mutex->backend);
316 mutex->backend = NULL;
319 return 0;
322 /* Grab a lock on a mutex. */
323 static inline int
324 __gthread_objc_mutex_lock(objc_mutex_t mutex)
326 if (__gthread_active_p ())
327 return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
328 else
329 return 0;
332 /* Try to grab a lock on a mutex. */
333 static inline int
334 __gthread_objc_mutex_trylock(objc_mutex_t mutex)
336 if (__gthread_active_p ()
337 && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 1)
338 return -1;
340 return 0;
343 /* Unlock the mutex */
344 static inline int
345 __gthread_objc_mutex_unlock(objc_mutex_t mutex)
347 if (__gthread_active_p ())
348 return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
349 else
350 return 0;
353 /* Backend condition mutex functions */
355 /* Allocate a condition. */
356 static inline int
357 __gthread_objc_condition_allocate(objc_condition_t condition)
359 if (__gthread_active_p ())
360 /* Unimplemented. */
361 return -1;
362 else
363 return 0;
366 /* Deallocate a condition. */
367 static inline int
368 __gthread_objc_condition_deallocate(objc_condition_t condition)
370 if (__gthread_active_p ())
371 /* Unimplemented. */
372 return -1;
373 else
374 return 0;
377 /* Wait on the condition */
378 static inline int
379 __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
381 if (__gthread_active_p ())
382 /* Unimplemented. */
383 return -1;
384 else
385 return 0;
388 /* Wake up all threads waiting on this condition. */
389 static inline int
390 __gthread_objc_condition_broadcast(objc_condition_t condition)
392 if (__gthread_active_p ())
393 /* Unimplemented. */
394 return -1;
395 else
396 return 0;
399 /* Wake up one thread waiting on this condition. */
400 static inline int
401 __gthread_objc_condition_signal(objc_condition_t condition)
403 if (__gthread_active_p ())
404 /* Unimplemented. */
405 return -1;
406 else
407 return 0;
410 #else /* _LIBOBJC */
412 static inline int
413 __gthread_once (__gthread_once_t *once, void (*func) (void))
415 if (__gthread_active_p ())
416 return pthread_once (once, func);
417 else
418 return -1;
421 static inline int
422 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
424 return pthread_keycreate (key, dtor);
427 static inline int
428 __gthread_key_dtor (UNUSED (__gthread_key_t key), UNUSED (void *ptr))
430 /* Nothing needed. */
431 return 0;
434 static inline int
435 __gthread_key_delete (UNUSED (__gthread_key_t key))
437 /* Operation is not supported. */
438 return -1;
441 static inline void *
442 __gthread_getspecific (__gthread_key_t key)
444 void *ptr;
445 if (pthread_getspecific (key, &ptr) == 0)
446 return ptr;
447 else
448 return 0;
451 static inline int
452 __gthread_setspecific (__gthread_key_t key, const void *ptr)
454 return pthread_setspecific (key, (void *) ptr);
457 static inline void
458 __gthread_mutex_init_function (__gthread_mutex_t *mutex)
460 if (__gthread_active_p ())
461 pthread_mutex_init (mutex, pthread_mutexattr_default);
464 static inline int
465 __gthread_mutex_lock (__gthread_mutex_t *mutex)
467 if (__gthread_active_p ())
468 return pthread_mutex_lock (mutex);
469 else
470 return 0;
473 static inline int
474 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
476 if (__gthread_active_p ())
477 return pthread_mutex_trylock (mutex);
478 else
479 return 0;
482 static inline int
483 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
485 if (__gthread_active_p ())
486 return pthread_mutex_unlock (mutex);
487 else
488 return 0;
491 #endif /* _LIBOBJC */
493 #undef UNUSED
495 #endif
496 #endif /* ! GCC_GTHR_DCE_H */