Use __builtin_memmove for trivially copyable types
[official-gcc.git] / libgcc / config / pa / gthr-dce.h
blob2407100dfd1f8c799426be12f23e415c42a2fee3
1 /* Threads compatibility routines for libgcc2 and libobjc. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1997-2018 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 3, 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 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 #ifndef GCC_GTHR_DCE_H
27 #define GCC_GTHR_DCE_H
29 /* If _DCE_THREADS is not defined, then we're building the single
30 threaded version of the libraries and do not want to reference
31 anything related to pthreads or dce. */
32 #ifndef _DCE_THREADS
33 #include "gthr-single.h"
34 #else
35 /* DCE threads interface.
36 DCE threads are based on POSIX threads draft 4, and many things
37 have changed since then. */
39 /* Make sure CONST_CAST2 (original in system.h) is defined. */
40 #ifndef CONST_CAST2
41 #ifdef __cplusplus
42 #define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X))
43 #else
44 #define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
45 #endif
46 #endif
48 #define __GTHREADS 1
50 #include <pthread.h>
52 typedef pthread_key_t __gthread_key_t;
53 typedef pthread_once_t __gthread_once_t;
54 typedef pthread_mutex_t __gthread_mutex_t;
55 typedef pthread_mutex_t __gthread_recursive_mutex_t;
57 #define __GTHREAD_ONCE_INIT pthread_once_init
59 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
60 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
62 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
64 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
65 # define __gthrw(name) \
66 static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
67 # define __gthrw_(name) __gthrw_ ## name
68 #else
69 # define __gthrw(name)
70 # define __gthrw_(name) name
71 #endif
73 __gthrw(pthread_once)
74 __gthrw(pthread_keycreate)
75 __gthrw(pthread_getspecific)
76 __gthrw(pthread_setspecific)
77 __gthrw(pthread_create)
78 __gthrw(pthread_mutex_init)
79 __gthrw(pthread_mutex_destroy)
80 __gthrw(pthread_mutex_lock)
81 __gthrw(pthread_mutex_trylock)
82 __gthrw(pthread_mutex_unlock)
83 __gthrw(pthread_mutexattr_create)
84 __gthrw(pthread_mutexattr_setkind_np)
85 __gthrw(pthread_mutexattr_delete)
87 #ifdef _LIBOBJC
88 /* Objective-C. */
89 __gthrw(pthread_cond_broadcast)
90 __gthrw(pthread_cond_destroy)
91 __gthrw(pthread_cond_init)
92 __gthrw(pthread_cond_signal)
93 __gthrw(pthread_cond_wait)
94 __gthrw(pthread_exit)
96 #ifdef pthread_getunique_np
97 # define __gthrw_pthread_getunique_np pthread_getunique_np
98 #else
99 __gthrw(pthread_getunique_np)
100 # define __gthrw_pthread_getunique_np __gthrw_(pthread_getunique_np)
101 #endif
103 __gthrw(pthread_mutex_destroy)
104 __gthrw(pthread_self)
105 __gthrw(pthread_yield)
106 #endif
108 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
110 static inline int
111 __gthread_active_p (void)
113 static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create);
114 return __gthread_active_ptr != 0;
117 #else /* not SUPPORTS_WEAK */
119 static inline int
120 __gthread_active_p (void)
122 return 1;
125 #endif /* SUPPORTS_WEAK */
127 #ifdef _LIBOBJC
129 /* Key structure for maintaining thread specific storage */
130 static pthread_key_t _objc_thread_storage;
132 /* Thread local storage for a single thread */
133 static void *thread_local_storage = NULL;
135 /* Backend initialization functions */
137 /* Initialize the threads subsystem. */
138 static inline int
139 __gthread_objc_init_thread_system (void)
141 if (__gthread_active_p ())
142 /* Initialize the thread storage key. */
143 return __gthrw_(pthread_keycreate) (&_objc_thread_storage, NULL);
144 else
145 return -1;
148 /* Close the threads subsystem. */
149 static inline int
150 __gthread_objc_close_thread_system (void)
152 if (__gthread_active_p ())
153 return 0;
154 else
155 return -1;
158 /* Backend thread functions */
160 /* Create a new thread of execution. */
161 static inline objc_thread_t
162 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
164 objc_thread_t thread_id;
165 pthread_t new_thread_handle;
167 if (!__gthread_active_p ())
168 return NULL;
170 if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default,
171 (void *) func, arg)))
173 /* ??? May not work! (64bit) */
174 thread_id = *(objc_thread_t *) &new_thread_handle;
175 pthread_detach (&new_thread_handle); /* Fully detach thread. */
177 else
178 thread_id = NULL;
180 return thread_id;
183 /* Set the current thread's priority. */
184 static inline int
185 __gthread_objc_thread_set_priority (int priority)
187 int sys_priority = 0;
189 if (!__gthread_active_p ())
190 return -1;
192 switch (priority)
194 case OBJC_THREAD_INTERACTIVE_PRIORITY:
195 sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
196 break;
197 default:
198 case OBJC_THREAD_BACKGROUND_PRIORITY:
199 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
200 break;
201 case OBJC_THREAD_LOW_PRIORITY:
202 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
203 break;
206 /* Change the priority. */
207 if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0)
208 return 0;
209 else
210 /* Failed */
211 return -1;
214 /* Return the current thread's priority. */
215 static inline int
216 __gthread_objc_thread_get_priority (void)
218 int sys_priority;
220 if (__gthread_active_p ())
222 if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0)
224 if (sys_priority >= PRI_FG_MIN_NP
225 && sys_priority <= PRI_FG_MAX_NP)
226 return OBJC_THREAD_INTERACTIVE_PRIORITY;
227 if (sys_priority >= PRI_BG_MIN_NP
228 && sys_priority <= PRI_BG_MAX_NP)
229 return OBJC_THREAD_BACKGROUND_PRIORITY;
230 return OBJC_THREAD_LOW_PRIORITY;
233 /* Failed */
234 return -1;
236 else
237 return OBJC_THREAD_INTERACTIVE_PRIORITY;
240 /* Yield our process time to another thread. */
241 static inline void
242 __gthread_objc_thread_yield (void)
244 if (__gthread_active_p ())
245 __gthrw_(pthread_yield) ();
248 /* Terminate the current thread. */
249 static inline int
250 __gthread_objc_thread_exit (void)
252 if (__gthread_active_p ())
253 /* exit the thread */
254 __gthrw_(pthread_exit) (&__objc_thread_exit_status);
256 /* Failed if we reached here */
257 return -1;
260 /* Returns an integer value which uniquely describes a thread. */
261 static inline objc_thread_t
262 __gthread_objc_thread_id (void)
264 if (__gthread_active_p ())
266 pthread_t self = __gthrw_(pthread_self) ();
268 return (objc_thread_t) __gthrw_pthread_getunique_np (&self);
270 else
271 return (objc_thread_t) 1;
274 /* Sets the thread's local storage pointer. */
275 static inline int
276 __gthread_objc_thread_set_data (void *value)
278 if (__gthread_active_p ())
279 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
280 else
282 thread_local_storage = value;
283 return 0;
287 /* Returns the thread's local storage pointer. */
288 static inline void *
289 __gthread_objc_thread_get_data (void)
291 void *value = NULL;
293 if (__gthread_active_p ())
295 if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value)))
296 return value;
298 return NULL;
300 else
301 return thread_local_storage;
304 /* Backend mutex functions */
306 /* Allocate a mutex. */
307 static inline int
308 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
310 if (__gthread_active_p ())
312 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
314 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend,
315 pthread_mutexattr_default))
317 objc_free (mutex->backend);
318 mutex->backend = NULL;
319 return -1;
323 return 0;
326 /* Deallocate a mutex. */
327 static inline int
328 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
330 if (__gthread_active_p ())
332 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
333 return -1;
335 objc_free (mutex->backend);
336 mutex->backend = NULL;
339 return 0;
342 /* Grab a lock on a mutex. */
343 static inline int
344 __gthread_objc_mutex_lock (objc_mutex_t mutex)
346 if (__gthread_active_p ())
347 return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend);
348 else
349 return 0;
352 /* Try to grab a lock on a mutex. */
353 static inline int
354 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
356 if (__gthread_active_p ()
357 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1)
358 return -1;
360 return 0;
363 /* Unlock the mutex */
364 static inline int
365 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
367 if (__gthread_active_p ())
368 return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
369 else
370 return 0;
373 /* Backend condition mutex functions */
375 /* Allocate a condition. */
376 static inline int
377 __gthread_objc_condition_allocate (objc_condition_t condition
378 __attribute__ ((__unused__)))
380 if (__gthread_active_p ())
381 /* Unimplemented. */
382 return -1;
383 else
384 return 0;
387 /* Deallocate a condition. */
388 static inline int
389 __gthread_objc_condition_deallocate (objc_condition_t condition
390 __attribute__ ((__unused__)))
392 if (__gthread_active_p ())
393 /* Unimplemented. */
394 return -1;
395 else
396 return 0;
399 /* Wait on the condition */
400 static inline int
401 __gthread_objc_condition_wait (objc_condition_t condition
402 __attribute__ ((__unused__)),
403 objc_mutex_t mutex __attribute__ ((__unused__)))
405 if (__gthread_active_p ())
406 /* Unimplemented. */
407 return -1;
408 else
409 return 0;
412 /* Wake up all threads waiting on this condition. */
413 static inline int
414 __gthread_objc_condition_broadcast (objc_condition_t condition
415 __attribute__ ((__unused__)))
417 if (__gthread_active_p ())
418 /* Unimplemented. */
419 return -1;
420 else
421 return 0;
424 /* Wake up one thread waiting on this condition. */
425 static inline int
426 __gthread_objc_condition_signal (objc_condition_t condition
427 __attribute__ ((__unused__)))
429 if (__gthread_active_p ())
430 /* Unimplemented. */
431 return -1;
432 else
433 return 0;
436 #else /* _LIBOBJC */
438 static inline int
439 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
441 if (__gthread_active_p ())
442 return __gthrw_(pthread_once) (__once, __func);
443 else
444 return -1;
447 static inline int
448 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
450 return __gthrw_(pthread_keycreate) (__key, __dtor);
453 static inline int
454 __gthread_key_delete (__gthread_key_t __key __attribute__ ((__unused__)))
456 /* Operation is not supported. */
457 return -1;
460 static inline void *
461 __gthread_getspecific (__gthread_key_t __key)
463 void *__ptr;
464 if (__gthrw_(pthread_getspecific) (__key, &__ptr) == 0)
465 return __ptr;
466 else
467 return 0;
470 static inline int
471 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
473 return __gthrw_(pthread_setspecific)
474 (__key, CONST_CAST2(void *, const void *, __ptr));
477 static inline void
478 __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
480 if (__gthread_active_p ())
481 __gthrw_(pthread_mutex_init) (__mutex, pthread_mutexattr_default);
484 static inline int
485 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
487 if (__gthread_active_p ())
488 return __gthrw_(pthread_mutex_destroy) (__mutex);
489 else
490 return 0;
493 static inline int
494 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
496 if (__gthread_active_p ())
497 return __gthrw_(pthread_mutex_lock) (__mutex);
498 else
499 return 0;
502 static inline int
503 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
505 if (__gthread_active_p ())
506 return __gthrw_(pthread_mutex_trylock) (__mutex);
507 else
508 return 0;
511 static inline int
512 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
514 if (__gthread_active_p ())
515 return __gthrw_(pthread_mutex_unlock) (__mutex);
516 else
517 return 0;
520 static inline int
521 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
523 if (__gthread_active_p ())
525 pthread_mutexattr_t __attr;
526 int __r;
528 __r = __gthrw_(pthread_mutexattr_create) (&__attr);
529 if (!__r)
530 __r = __gthrw_(pthread_mutexattr_setkind_np) (&__attr,
531 MUTEX_RECURSIVE_NP);
532 if (!__r)
533 __r = __gthrw_(pthread_mutex_init) (__mutex, __attr);
534 if (!__r)
535 __r = __gthrw_(pthread_mutexattr_delete) (&__attr);
536 return __r;
538 return 0;
541 static inline int
542 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
544 return __gthread_mutex_lock (__mutex);
547 static inline int
548 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
550 return __gthread_mutex_trylock (__mutex);
553 static inline int
554 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
556 return __gthread_mutex_unlock (__mutex);
559 static inline int
560 __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
562 return __gthread_mutex_destroy (__mutex);
565 #endif /* _LIBOBJC */
567 #endif
568 #endif /* ! GCC_GTHR_DCE_H */