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