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