* config/h8300/h8300-protos.h: Update the prototype for
[official-gcc.git] / gcc / gthr-dce.h
blobafefaca7329bf80407dfaead9e82dfc59d9b99d2
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 void *__gthread_active_ptr = (void *) &pthread_create;
92 static inline int
93 __gthread_active_p (void)
95 return __gthread_active_ptr != 0;
98 #else /* not SUPPORTS_WEAK */
100 static inline int
101 __gthread_active_p (void)
103 return 1;
106 #endif /* SUPPORTS_WEAK */
108 #ifdef _LIBOBJC
110 /* Key structure for maintaining thread specific storage */
111 static pthread_key_t _objc_thread_storage;
113 /* Thread local storage for a single thread */
114 static void *thread_local_storage = NULL;
116 /* Backend initialization functions */
118 /* Initialize the threads subsystem. */
119 static inline int
120 __gthread_objc_init_thread_system(void)
122 if (__gthread_active_p ())
123 /* Initialize the thread storage key */
124 return pthread_keycreate (&_objc_thread_storage, NULL);
125 else
126 return -1;
129 /* Close the threads subsystem. */
130 static inline int
131 __gthread_objc_close_thread_system(void)
133 if (__gthread_active_p ())
134 return 0;
135 else
136 return -1;
139 /* Backend thread functions */
141 /* Create a new thread of execution. */
142 static inline objc_thread_t
143 __gthread_objc_thread_detach(void (*func)(void *), void *arg)
145 objc_thread_t thread_id;
146 pthread_t new_thread_handle;
148 if (!__gthread_active_p ())
149 return NULL;
151 if ( !(pthread_create(&new_thread_handle, pthread_attr_default,
152 (void *)func, arg)) )
154 /* ??? May not work! (64bit) */
155 thread_id = *(objc_thread_t *)&new_thread_handle;
156 pthread_detach(&new_thread_handle); /* Fully detach thread. */
158 else
159 thread_id = NULL;
161 return thread_id;
164 /* Set the current thread's priority. */
165 static inline int
166 __gthread_objc_thread_set_priority(int priority)
168 int sys_priority = 0;
170 if (!__gthread_active_p ())
171 return -1;
173 switch (priority)
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;
187 /* Change the priority. */
188 if (pthread_setprio(pthread_self(), sys_priority) >= 0)
189 return 0;
190 else
191 /* Failed */
192 return -1;
195 /* Return the current thread's priority. */
196 static inline int
197 __gthread_objc_thread_get_priority(void)
199 int sys_priority;
201 if (__gthread_active_p ())
203 if ((sys_priority = pthread_getprio(pthread_self())) >= 0)
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;
214 /* Failed */
215 return -1;
217 else
218 return OBJC_THREAD_INTERACTIVE_PRIORITY;
221 /* Yield our process time to another thread. */
222 static inline void
223 __gthread_objc_thread_yield(void)
225 if (__gthread_active_p ())
226 pthread_yield();
229 /* Terminate the current thread. */
230 static inline int
231 __gthread_objc_thread_exit(void)
233 if (__gthread_active_p ())
234 /* exit the thread */
235 pthread_exit(&__objc_thread_exit_status);
237 /* Failed if we reached here */
238 return -1;
241 /* Returns an integer value which uniquely describes a thread. */
242 static inline objc_thread_t
243 __gthread_objc_thread_id(void)
245 if (__gthread_active_p ())
247 pthread_t self = pthread_self();
249 return (objc_thread_t) pthread_getunique_np (&self);
251 else
252 return (objc_thread_t)1;
255 /* Sets the thread's local storage pointer. */
256 static inline int
257 __gthread_objc_thread_set_data(void *value)
259 if (__gthread_active_p ())
260 return pthread_setspecific(_objc_thread_storage, value);
261 else
263 thread_local_storage = value;
264 return 0;
268 /* Returns the thread's local storage pointer. */
269 static inline void *
270 __gthread_objc_thread_get_data(void)
272 void *value = NULL;
274 if (__gthread_active_p ())
276 if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
277 return value;
279 return NULL;
281 else
282 return thread_local_storage;
285 /* Backend mutex functions */
287 /* Allocate a mutex. */
288 static inline int
289 __gthread_objc_mutex_allocate(objc_mutex_t mutex)
291 if (__gthread_active_p ())
293 mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
295 if (pthread_mutex_init((pthread_mutex_t *)mutex->backend,
296 pthread_mutexattr_default))
298 objc_free(mutex->backend);
299 mutex->backend = NULL;
300 return -1;
304 return 0;
307 /* Deallocate a mutex. */
308 static inline int
309 __gthread_objc_mutex_deallocate(objc_mutex_t mutex)
311 if (__gthread_active_p ())
313 if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
314 return -1;
316 objc_free(mutex->backend);
317 mutex->backend = NULL;
320 return 0;
323 /* Grab a lock on a mutex. */
324 static inline int
325 __gthread_objc_mutex_lock(objc_mutex_t mutex)
327 if (__gthread_active_p ())
328 return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
329 else
330 return 0;
333 /* Try to grab a lock on a mutex. */
334 static inline int
335 __gthread_objc_mutex_trylock(objc_mutex_t mutex)
337 if (__gthread_active_p ()
338 && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 1)
339 return -1;
341 return 0;
344 /* Unlock the mutex */
345 static inline int
346 __gthread_objc_mutex_unlock(objc_mutex_t mutex)
348 if (__gthread_active_p ())
349 return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
350 else
351 return 0;
354 /* Backend condition mutex functions */
356 /* Allocate a condition. */
357 static inline int
358 __gthread_objc_condition_allocate(objc_condition_t condition)
360 if (__gthread_active_p ())
361 /* Unimplemented. */
362 return -1;
363 else
364 return 0;
367 /* Deallocate a condition. */
368 static inline int
369 __gthread_objc_condition_deallocate(objc_condition_t condition)
371 if (__gthread_active_p ())
372 /* Unimplemented. */
373 return -1;
374 else
375 return 0;
378 /* Wait on the condition */
379 static inline int
380 __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
382 if (__gthread_active_p ())
383 /* Unimplemented. */
384 return -1;
385 else
386 return 0;
389 /* Wake up all threads waiting on this condition. */
390 static inline int
391 __gthread_objc_condition_broadcast(objc_condition_t condition)
393 if (__gthread_active_p ())
394 /* Unimplemented. */
395 return -1;
396 else
397 return 0;
400 /* Wake up one thread waiting on this condition. */
401 static inline int
402 __gthread_objc_condition_signal(objc_condition_t condition)
404 if (__gthread_active_p ())
405 /* Unimplemented. */
406 return -1;
407 else
408 return 0;
411 #else /* _LIBOBJC */
413 static inline int
414 __gthread_once (__gthread_once_t *once, void (*func) (void))
416 if (__gthread_active_p ())
417 return pthread_once (once, func);
418 else
419 return -1;
422 static inline int
423 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
425 return pthread_keycreate (key, dtor);
428 static inline int
429 __gthread_key_dtor (UNUSED (__gthread_key_t key), UNUSED (void *ptr))
431 /* Nothing needed. */
432 return 0;
435 static inline int
436 __gthread_key_delete (UNUSED (__gthread_key_t key))
438 /* Operation is not supported. */
439 return -1;
442 static inline void *
443 __gthread_getspecific (__gthread_key_t key)
445 void *ptr;
446 if (pthread_getspecific (key, &ptr) == 0)
447 return ptr;
448 else
449 return 0;
452 static inline int
453 __gthread_setspecific (__gthread_key_t key, const void *ptr)
455 return pthread_setspecific (key, (void *) ptr);
458 static inline void
459 __gthread_mutex_init_function (__gthread_mutex_t *mutex)
461 if (__gthread_active_p ())
462 pthread_mutex_init (mutex, pthread_mutexattr_default);
465 static inline int
466 __gthread_mutex_lock (__gthread_mutex_t *mutex)
468 if (__gthread_active_p ())
469 return pthread_mutex_lock (mutex);
470 else
471 return 0;
474 static inline int
475 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
477 if (__gthread_active_p ())
478 return pthread_mutex_trylock (mutex);
479 else
480 return 0;
483 static inline int
484 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
486 if (__gthread_active_p ())
487 return pthread_mutex_unlock (mutex);
488 else
489 return 0;
492 #endif /* _LIBOBJC */
494 #undef UNUSED
496 #endif
497 #endif /* ! GCC_GTHR_DCE_H */