]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gthr-dce.h
re PR target/37170 (gcc.dg/weak/weak-1.c)
[thirdparty/gcc.git] / gcc / gthr-dce.h
CommitLineData
40aac948 1/* Threads compatibility routines for libgcc2 and libobjc. */
f24af81b 2/* Compile this one with gcc. */
7ef67393
AO
3/* Copyright (C) 1997, 1999, 2000, 2001, 2004, 2005
4 Free Software Foundation, Inc.
f24af81b 5
1322177d 6This file is part of GCC.
f24af81b 7
1322177d
LB
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
f24af81b 12
1322177d
LB
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
f24af81b
TT
17
18You should have received a copy of the GNU General Public License
1322177d 19along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
f24af81b
TT
22
23/* As a special exception, if you link this library with other files,
24 some of which are compiled with GCC, to produce an executable,
25 this library does not by itself cause the resulting executable
26 to be covered by the GNU General Public License.
27 This exception does not however invalidate any other reasons why
28 the executable file might be covered by the GNU General Public License. */
29
88657302
RH
30#ifndef GCC_GTHR_DCE_H
31#define GCC_GTHR_DCE_H
f24af81b 32
c36b1123
JL
33/* If _DCE_THREADS is not defined, then we're building the single
34 threaded version of the libraries and do not want to reference
35 anything related to pthreads or dce. */
36#ifndef _DCE_THREADS
37#include "gthr-single.h"
38#else
f24af81b
TT
39/* DCE threads interface.
40 DCE threads are based on POSIX threads draft 4, and many things
71287280 41 have changed since then. */
f24af81b
TT
42
43#define __GTHREADS 1
44
45#include <pthread.h>
46
47typedef pthread_key_t __gthread_key_t;
48typedef pthread_once_t __gthread_once_t;
49typedef pthread_mutex_t __gthread_mutex_t;
40aac948 50typedef pthread_mutex_t __gthread_recursive_mutex_t;
f24af81b 51
72b16773 52#define __GTHREAD_ONCE_INIT pthread_once_init
5241c227
JDA
53
54#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
40aac948 55#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
5241c227 56
72b16773 57#define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
f24af81b
TT
58
59#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
7ef67393 60# define __gthrw(name) \
72b16773
AO
61 static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
62# define __gthrw_(name) __gthrw_ ## name
7ef67393 63#else
72b16773
AO
64# define __gthrw(name)
65# define __gthrw_(name) name
7ef67393 66#endif
f24af81b 67
72b16773
AO
68__gthrw(pthread_once)
69__gthrw(pthread_keycreate)
70__gthrw(pthread_getspecific)
71__gthrw(pthread_setspecific)
72__gthrw(pthread_create)
73__gthrw(pthread_mutex_init)
4dabf736 74__gthrw(pthread_mutex_destroy)
72b16773
AO
75__gthrw(pthread_mutex_lock)
76__gthrw(pthread_mutex_trylock)
77__gthrw(pthread_mutex_unlock)
78__gthrw(pthread_mutexattr_create)
79__gthrw(pthread_mutexattr_setkind_np)
80__gthrw(pthread_mutexattr_delete)
f24af81b 81
15794a95 82#ifdef _LIBOBJC
40f03658 83/* Objective-C. */
72b16773
AO
84__gthrw(pthread_cond_broadcast)
85__gthrw(pthread_cond_destroy)
86__gthrw(pthread_cond_init)
87__gthrw(pthread_cond_signal)
88__gthrw(pthread_cond_wait)
89__gthrw(pthread_exit)
90
91#ifdef pthread_getunique_np
92# define __gthrw_pthread_getunique_np pthread_getunique_np
93#else
94__gthrw(pthread_getunique_np)
95# define __gthrw_pthread_getunique_np __gthrw_(pthread_getunique_np)
96#endif
97
98__gthrw(pthread_mutex_destroy)
99__gthrw(pthread_self)
100__gthrw(pthread_yield)
15794a95
L
101#endif
102
7ef67393
AO
103#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
104
f24af81b 105static inline int
d1e51320 106__gthread_active_p (void)
f24af81b 107{
72b16773 108 static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create);
f24af81b
TT
109 return __gthread_active_ptr != 0;
110}
111
112#else /* not SUPPORTS_WEAK */
113
114static inline int
d1e51320 115__gthread_active_p (void)
f24af81b
TT
116{
117 return 1;
118}
119
120#endif /* SUPPORTS_WEAK */
121
15794a95
L
122#ifdef _LIBOBJC
123
124/* Key structure for maintaining thread specific storage */
125static pthread_key_t _objc_thread_storage;
126
127/* Thread local storage for a single thread */
128static void *thread_local_storage = NULL;
129
130/* Backend initialization functions */
131
71287280 132/* Initialize the threads subsystem. */
15794a95 133static inline int
dd697f8c 134__gthread_objc_init_thread_system (void)
15794a95
L
135{
136 if (__gthread_active_p ())
ea4b7848 137 /* Initialize the thread storage key. */
72b16773 138 return __gthrw_(pthread_keycreate) (&_objc_thread_storage, NULL);
15794a95
L
139 else
140 return -1;
141}
142
71287280 143/* Close the threads subsystem. */
15794a95 144static inline int
dd697f8c 145__gthread_objc_close_thread_system (void)
15794a95
L
146{
147 if (__gthread_active_p ())
148 return 0;
149 else
150 return -1;
151}
152
153/* Backend thread functions */
154
71287280 155/* Create a new thread of execution. */
15794a95 156static inline objc_thread_t
dd697f8c 157__gthread_objc_thread_detach (void (*func)(void *), void *arg)
15794a95
L
158{
159 objc_thread_t thread_id;
160 pthread_t new_thread_handle;
161
162 if (!__gthread_active_p ())
163 return NULL;
589005ff 164
72b16773 165 if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default,
dd697f8c 166 (void *) func, arg)))
15794a95
L
167 {
168 /* ??? May not work! (64bit) */
dd697f8c
KH
169 thread_id = *(objc_thread_t *) &new_thread_handle;
170 pthread_detach (&new_thread_handle); /* Fully detach thread. */
15794a95
L
171 }
172 else
173 thread_id = NULL;
589005ff 174
15794a95
L
175 return thread_id;
176}
177
71287280 178/* Set the current thread's priority. */
15794a95 179static inline int
dd697f8c 180__gthread_objc_thread_set_priority (int priority)
15794a95
L
181{
182 int sys_priority = 0;
183
184 if (!__gthread_active_p ())
185 return -1;
186
187 switch (priority)
188 {
189 case OBJC_THREAD_INTERACTIVE_PRIORITY:
190 sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
191 break;
192 default:
193 case OBJC_THREAD_BACKGROUND_PRIORITY:
194 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
195 break;
196 case OBJC_THREAD_LOW_PRIORITY:
197 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
198 break;
199 }
589005ff 200
71287280 201 /* Change the priority. */
72b16773 202 if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0)
15794a95
L
203 return 0;
204 else
205 /* Failed */
206 return -1;
207}
208
71287280 209/* Return the current thread's priority. */
15794a95 210static inline int
dd697f8c 211__gthread_objc_thread_get_priority (void)
15794a95
L
212{
213 int sys_priority;
214
215 if (__gthread_active_p ())
216 {
72b16773 217 if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0)
589005ff 218 {
15794a95
L
219 if (sys_priority >= PRI_FG_MIN_NP
220 && sys_priority <= PRI_FG_MAX_NP)
221 return OBJC_THREAD_INTERACTIVE_PRIORITY;
222 if (sys_priority >= PRI_BG_MIN_NP
223 && sys_priority <= PRI_BG_MAX_NP)
224 return OBJC_THREAD_BACKGROUND_PRIORITY;
225 return OBJC_THREAD_LOW_PRIORITY;
226 }
227
228 /* Failed */
229 return -1;
230 }
231 else
232 return OBJC_THREAD_INTERACTIVE_PRIORITY;
233}
234
71287280 235/* Yield our process time to another thread. */
15794a95 236static inline void
dd697f8c 237__gthread_objc_thread_yield (void)
15794a95
L
238{
239 if (__gthread_active_p ())
72b16773 240 __gthrw_(pthread_yield) ();
15794a95
L
241}
242
71287280 243/* Terminate the current thread. */
15794a95 244static inline int
dd697f8c 245__gthread_objc_thread_exit (void)
15794a95
L
246{
247 if (__gthread_active_p ())
248 /* exit the thread */
72b16773 249 __gthrw_(pthread_exit) (&__objc_thread_exit_status);
15794a95
L
250
251 /* Failed if we reached here */
252 return -1;
253}
254
71287280 255/* Returns an integer value which uniquely describes a thread. */
15794a95 256static inline objc_thread_t
dd697f8c 257__gthread_objc_thread_id (void)
15794a95
L
258{
259 if (__gthread_active_p ())
260 {
72b16773 261 pthread_t self = __gthrw_(pthread_self) ();
15794a95 262
7ef67393 263 return (objc_thread_t) __gthrw_pthread_getunique_np (&self);
15794a95
L
264 }
265 else
dd697f8c 266 return (objc_thread_t) 1;
15794a95
L
267}
268
71287280 269/* Sets the thread's local storage pointer. */
15794a95 270static inline int
dd697f8c 271__gthread_objc_thread_set_data (void *value)
15794a95
L
272{
273 if (__gthread_active_p ())
72b16773 274 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
15794a95
L
275 else
276 {
277 thread_local_storage = value;
278 return 0;
279 }
280}
281
71287280 282/* Returns the thread's local storage pointer. */
15794a95 283static inline void *
dd697f8c 284__gthread_objc_thread_get_data (void)
15794a95
L
285{
286 void *value = NULL;
287
288 if (__gthread_active_p ())
289 {
72b16773 290 if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value)))
15794a95
L
291 return value;
292
293 return NULL;
294 }
295 else
296 return thread_local_storage;
297}
298
299/* Backend mutex functions */
300
71287280 301/* Allocate a mutex. */
15794a95 302static inline int
dd697f8c 303__gthread_objc_mutex_allocate (objc_mutex_t mutex)
15794a95 304{
802a8181
DA
305 if (__gthread_active_p ())
306 {
dd697f8c 307 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
802a8181 308
72b16773 309 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend,
dd697f8c 310 pthread_mutexattr_default))
589005ff 311 {
dd697f8c 312 objc_free (mutex->backend);
589005ff
KH
313 mutex->backend = NULL;
314 return -1;
315 }
802a8181 316 }
15794a95
L
317
318 return 0;
319}
320
71287280 321/* Deallocate a mutex. */
15794a95 322static inline int
dd697f8c 323__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
15794a95 324{
6bb92770
DA
325 if (__gthread_active_p ())
326 {
72b16773 327 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
589005ff 328 return -1;
6bb92770 329
dd697f8c 330 objc_free (mutex->backend);
6bb92770
DA
331 mutex->backend = NULL;
332 }
15794a95
L
333
334 return 0;
335}
336
71287280 337/* Grab a lock on a mutex. */
15794a95 338static inline int
dd697f8c 339__gthread_objc_mutex_lock (objc_mutex_t mutex)
15794a95
L
340{
341 if (__gthread_active_p ())
72b16773 342 return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend);
15794a95
L
343 else
344 return 0;
345}
346
71287280 347/* Try to grab a lock on a mutex. */
15794a95 348static inline int
dd697f8c 349__gthread_objc_mutex_trylock (objc_mutex_t mutex)
15794a95
L
350{
351 if (__gthread_active_p ()
72b16773 352 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1)
15794a95
L
353 return -1;
354
355 return 0;
356}
357
358/* Unlock the mutex */
359static inline int
dd697f8c 360__gthread_objc_mutex_unlock (objc_mutex_t mutex)
15794a95
L
361{
362 if (__gthread_active_p ())
72b16773 363 return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
15794a95
L
364 else
365 return 0;
366}
367
368/* Backend condition mutex functions */
369
71287280 370/* Allocate a condition. */
15794a95 371static inline int
72b16773
AO
372__gthread_objc_condition_allocate (objc_condition_t condition
373 __attribute__ ((__unused__)))
15794a95 374{
c54dbf8b 375 if (__gthread_active_p ())
71287280 376 /* Unimplemented. */
15794a95
L
377 return -1;
378 else
379 return 0;
380}
381
71287280 382/* Deallocate a condition. */
15794a95 383static inline int
72b16773
AO
384__gthread_objc_condition_deallocate (objc_condition_t condition
385 __attribute__ ((__unused__)))
15794a95
L
386{
387 if (__gthread_active_p ())
71287280 388 /* Unimplemented. */
15794a95
L
389 return -1;
390 else
391 return 0;
392}
393
394/* Wait on the condition */
395static inline int
72b16773
AO
396__gthread_objc_condition_wait (objc_condition_t condition
397 __attribute__ ((__unused__)),
398 objc_mutex_t mutex __attribute__ ((__unused__)))
15794a95
L
399{
400 if (__gthread_active_p ())
71287280 401 /* Unimplemented. */
15794a95
L
402 return -1;
403 else
404 return 0;
405}
406
71287280 407/* Wake up all threads waiting on this condition. */
15794a95 408static inline int
72b16773
AO
409__gthread_objc_condition_broadcast (objc_condition_t condition
410 __attribute__ ((__unused__)))
15794a95
L
411{
412 if (__gthread_active_p ())
71287280 413 /* Unimplemented. */
15794a95
L
414 return -1;
415 else
416 return 0;
417}
418
71287280 419/* Wake up one thread waiting on this condition. */
15794a95 420static inline int
72b16773
AO
421__gthread_objc_condition_signal (objc_condition_t condition
422 __attribute__ ((__unused__)))
15794a95
L
423{
424 if (__gthread_active_p ())
71287280 425 /* Unimplemented. */
15794a95
L
426 return -1;
427 else
428 return 0;
429}
430
431#else /* _LIBOBJC */
432
f24af81b 433static inline int
d1e51320 434__gthread_once (__gthread_once_t *once, void (*func) (void))
f24af81b
TT
435{
436 if (__gthread_active_p ())
72b16773 437 return __gthrw_(pthread_once) (once, func);
f24af81b
TT
438 else
439 return -1;
440}
441
442static inline int
443__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
444{
72b16773 445 return __gthrw_(pthread_keycreate) (key, dtor);
f24af81b
TT
446}
447
5467baef 448static inline int
72b16773 449__gthread_key_delete (__gthread_key_t key __attribute__ ((__unused__)))
5467baef
JDA
450{
451 /* Operation is not supported. */
452 return -1;
453}
f24af81b
TT
454
455static inline void *
456__gthread_getspecific (__gthread_key_t key)
457{
458 void *ptr;
72b16773 459 if (__gthrw_(pthread_getspecific) (key, &ptr) == 0)
f24af81b
TT
460 return ptr;
461 else
462 return 0;
463}
464
465static inline int
466__gthread_setspecific (__gthread_key_t key, const void *ptr)
467{
72b16773 468 return __gthrw_(pthread_setspecific) (key, (void *) ptr);
f24af81b
TT
469}
470
5241c227
JDA
471static inline void
472__gthread_mutex_init_function (__gthread_mutex_t *mutex)
473{
474 if (__gthread_active_p ())
72b16773 475 __gthrw_(pthread_mutex_init) (mutex, pthread_mutexattr_default);
5241c227
JDA
476}
477
4dabf736
JB
478static inline int
479__gthread_mutx_destroy (__gthread_mutex_t *mutex)
480{
481 if (__gthread_active_p ())
482 return __gthrw_(pthread_mutex_destroy) (mutex);
483 else
484 return 0;
485}
486
f24af81b
TT
487static inline int
488__gthread_mutex_lock (__gthread_mutex_t *mutex)
489{
490 if (__gthread_active_p ())
72b16773 491 return __gthrw_(pthread_mutex_lock) (mutex);
f24af81b
TT
492 else
493 return 0;
494}
495
496static inline int
497__gthread_mutex_trylock (__gthread_mutex_t *mutex)
498{
499 if (__gthread_active_p ())
72b16773 500 return __gthrw_(pthread_mutex_trylock) (mutex);
f24af81b
TT
501 else
502 return 0;
503}
504
505static inline int
506__gthread_mutex_unlock (__gthread_mutex_t *mutex)
507{
508 if (__gthread_active_p ())
72b16773 509 return __gthrw_(pthread_mutex_unlock) (mutex);
f24af81b
TT
510 else
511 return 0;
512}
513
40aac948
JM
514static inline int
515__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
516{
517 if (__gthread_active_p ())
518 {
519 pthread_mutexattr_t attr;
520 int r;
521
72b16773 522 r = __gthrw_(pthread_mutexattr_create) (&attr);
40aac948 523 if (!r)
72b16773 524 r = __gthrw_(pthread_mutexattr_setkind_np) (&attr, MUTEX_RECURSIVE_NP);
40aac948 525 if (!r)
72b16773 526 r = __gthrw_(pthread_mutex_init) (mutex, attr);
40aac948 527 if (!r)
72b16773 528 r = __gthrw_(pthread_mutexattr_delete) (&attr);
40aac948
JM
529 return r;
530 }
72b16773 531 return 0;
40aac948
JM
532}
533
534static inline int
535__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
536{
537 return __gthread_mutex_lock (mutex);
538}
539
540static inline int
541__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
542{
543 return __gthread_mutex_trylock (mutex);
544}
545
546static inline int
547__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
548{
549 return __gthread_mutex_unlock (mutex);
550}
551
15794a95
L
552#endif /* _LIBOBJC */
553
c36b1123 554#endif
88657302 555#endif /* ! GCC_GTHR_DCE_H */