]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/pa/gthr-dce.h
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / pa / gthr-dce.h
1 /* Threads compatibility routines for libgcc2 and libobjc. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1997-2024 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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.
11
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.
16
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.
20
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/>. */
25
26 #ifndef GCC_GTHR_DCE_H
27 #define GCC_GTHR_DCE_H
28
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. */
38
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
47
48 #define __GTHREADS 1
49
50 #include <pthread.h>
51
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;
56
57 #define __GTHREAD_ONCE_INIT pthread_once_init
58
59 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
60 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
61
62 #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
63
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
72
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)
86
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)
95
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
102
103 __gthrw(pthread_mutex_destroy)
104 __gthrw(pthread_self)
105 __gthrw(pthread_yield)
106 #endif
107
108 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
109
110 static inline int
111 __gthread_active_p (void)
112 {
113 static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create);
114 return __gthread_active_ptr != 0;
115 }
116
117 #else /* not SUPPORTS_WEAK */
118
119 static inline int
120 __gthread_active_p (void)
121 {
122 return 1;
123 }
124
125 #endif /* SUPPORTS_WEAK */
126
127 #ifdef _LIBOBJC
128
129 /* Key structure for maintaining thread specific storage */
130 static pthread_key_t _objc_thread_storage;
131
132 /* Thread local storage for a single thread */
133 static void *thread_local_storage = NULL;
134
135 /* Backend initialization functions */
136
137 /* Initialize the threads subsystem. */
138 static inline int
139 __gthread_objc_init_thread_system (void)
140 {
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;
146 }
147
148 /* Close the threads subsystem. */
149 static inline int
150 __gthread_objc_close_thread_system (void)
151 {
152 if (__gthread_active_p ())
153 return 0;
154 else
155 return -1;
156 }
157
158 /* Backend thread functions */
159
160 /* Create a new thread of execution. */
161 static inline objc_thread_t
162 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
163 {
164 objc_thread_t thread_id;
165 pthread_t new_thread_handle;
166
167 if (!__gthread_active_p ())
168 return NULL;
169
170 if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default,
171 (void *) func, arg)))
172 {
173 /* ??? May not work! (64bit) */
174 thread_id = *(objc_thread_t *) &new_thread_handle;
175 pthread_detach (&new_thread_handle); /* Fully detach thread. */
176 }
177 else
178 thread_id = NULL;
179
180 return thread_id;
181 }
182
183 /* Set the current thread's priority. */
184 static inline int
185 __gthread_objc_thread_set_priority (int priority)
186 {
187 int sys_priority = 0;
188
189 if (!__gthread_active_p ())
190 return -1;
191
192 switch (priority)
193 {
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;
204 }
205
206 /* Change the priority. */
207 if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0)
208 return 0;
209 else
210 /* Failed */
211 return -1;
212 }
213
214 /* Return the current thread's priority. */
215 static inline int
216 __gthread_objc_thread_get_priority (void)
217 {
218 int sys_priority;
219
220 if (__gthread_active_p ())
221 {
222 if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0)
223 {
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;
231 }
232
233 /* Failed */
234 return -1;
235 }
236 else
237 return OBJC_THREAD_INTERACTIVE_PRIORITY;
238 }
239
240 /* Yield our process time to another thread. */
241 static inline void
242 __gthread_objc_thread_yield (void)
243 {
244 if (__gthread_active_p ())
245 __gthrw_(pthread_yield) ();
246 }
247
248 /* Terminate the current thread. */
249 static inline int
250 __gthread_objc_thread_exit (void)
251 {
252 if (__gthread_active_p ())
253 /* exit the thread */
254 __gthrw_(pthread_exit) (&__objc_thread_exit_status);
255
256 /* Failed if we reached here */
257 return -1;
258 }
259
260 /* Returns an integer value which uniquely describes a thread. */
261 static inline objc_thread_t
262 __gthread_objc_thread_id (void)
263 {
264 if (__gthread_active_p ())
265 {
266 pthread_t self = __gthrw_(pthread_self) ();
267
268 return (objc_thread_t) __gthrw_pthread_getunique_np (&self);
269 }
270 else
271 return (objc_thread_t) 1;
272 }
273
274 /* Sets the thread's local storage pointer. */
275 static inline int
276 __gthread_objc_thread_set_data (void *value)
277 {
278 if (__gthread_active_p ())
279 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
280 else
281 {
282 thread_local_storage = value;
283 return 0;
284 }
285 }
286
287 /* Returns the thread's local storage pointer. */
288 static inline void *
289 __gthread_objc_thread_get_data (void)
290 {
291 void *value = NULL;
292
293 if (__gthread_active_p ())
294 {
295 if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value)))
296 return value;
297
298 return NULL;
299 }
300 else
301 return thread_local_storage;
302 }
303
304 /* Backend mutex functions */
305
306 /* Allocate a mutex. */
307 static inline int
308 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
309 {
310 if (__gthread_active_p ())
311 {
312 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
313
314 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend,
315 pthread_mutexattr_default))
316 {
317 objc_free (mutex->backend);
318 mutex->backend = NULL;
319 return -1;
320 }
321 }
322
323 return 0;
324 }
325
326 /* Deallocate a mutex. */
327 static inline int
328 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
329 {
330 if (__gthread_active_p ())
331 {
332 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
333 return -1;
334
335 objc_free (mutex->backend);
336 mutex->backend = NULL;
337 }
338
339 return 0;
340 }
341
342 /* Grab a lock on a mutex. */
343 static inline int
344 __gthread_objc_mutex_lock (objc_mutex_t mutex)
345 {
346 if (__gthread_active_p ())
347 return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend);
348 else
349 return 0;
350 }
351
352 /* Try to grab a lock on a mutex. */
353 static inline int
354 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
355 {
356 if (__gthread_active_p ()
357 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1)
358 return -1;
359
360 return 0;
361 }
362
363 /* Unlock the mutex */
364 static inline int
365 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
366 {
367 if (__gthread_active_p ())
368 return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
369 else
370 return 0;
371 }
372
373 /* Backend condition mutex functions */
374
375 /* Allocate a condition. */
376 static inline int
377 __gthread_objc_condition_allocate (objc_condition_t condition
378 __attribute__ ((__unused__)))
379 {
380 if (__gthread_active_p ())
381 /* Unimplemented. */
382 return -1;
383 else
384 return 0;
385 }
386
387 /* Deallocate a condition. */
388 static inline int
389 __gthread_objc_condition_deallocate (objc_condition_t condition
390 __attribute__ ((__unused__)))
391 {
392 if (__gthread_active_p ())
393 /* Unimplemented. */
394 return -1;
395 else
396 return 0;
397 }
398
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__)))
404 {
405 if (__gthread_active_p ())
406 /* Unimplemented. */
407 return -1;
408 else
409 return 0;
410 }
411
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__)))
416 {
417 if (__gthread_active_p ())
418 /* Unimplemented. */
419 return -1;
420 else
421 return 0;
422 }
423
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__)))
428 {
429 if (__gthread_active_p ())
430 /* Unimplemented. */
431 return -1;
432 else
433 return 0;
434 }
435
436 #else /* _LIBOBJC */
437
438 static inline int
439 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
440 {
441 if (__gthread_active_p ())
442 return __gthrw_(pthread_once) (__once, __func);
443 else
444 return -1;
445 }
446
447 static inline int
448 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
449 {
450 return __gthrw_(pthread_keycreate) (__key, __dtor);
451 }
452
453 static inline int
454 __gthread_key_delete (__gthread_key_t __key __attribute__ ((__unused__)))
455 {
456 /* Operation is not supported. */
457 return -1;
458 }
459
460 static inline void *
461 __gthread_getspecific (__gthread_key_t __key)
462 {
463 void *__ptr;
464 if (__gthrw_(pthread_getspecific) (__key, &__ptr) == 0)
465 return __ptr;
466 else
467 return 0;
468 }
469
470 static inline int
471 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
472 {
473 return __gthrw_(pthread_setspecific)
474 (__key, CONST_CAST2(void *, const void *, __ptr));
475 }
476
477 static inline void
478 __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
479 {
480 if (__gthread_active_p ())
481 __gthrw_(pthread_mutex_init) (__mutex, pthread_mutexattr_default);
482 }
483
484 static inline int
485 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
486 {
487 if (__gthread_active_p ())
488 return __gthrw_(pthread_mutex_destroy) (__mutex);
489 else
490 return 0;
491 }
492
493 static inline int
494 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
495 {
496 if (__gthread_active_p ())
497 return __gthrw_(pthread_mutex_lock) (__mutex);
498 else
499 return 0;
500 }
501
502 static inline int
503 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
504 {
505 if (__gthread_active_p ())
506 return __gthrw_(pthread_mutex_trylock) (__mutex);
507 else
508 return 0;
509 }
510
511 static inline int
512 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
513 {
514 if (__gthread_active_p ())
515 return __gthrw_(pthread_mutex_unlock) (__mutex);
516 else
517 return 0;
518 }
519
520 static inline int
521 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
522 {
523 if (__gthread_active_p ())
524 {
525 pthread_mutexattr_t __attr;
526 int __r;
527
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;
537 }
538 return 0;
539 }
540
541 static inline int
542 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
543 {
544 return __gthread_mutex_lock (__mutex);
545 }
546
547 static inline int
548 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
549 {
550 return __gthread_mutex_trylock (__mutex);
551 }
552
553 static inline int
554 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
555 {
556 return __gthread_mutex_unlock (__mutex);
557 }
558
559 static inline int
560 __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
561 {
562 return __gthread_mutex_destroy (__mutex);
563 }
564
565 #endif /* _LIBOBJC */
566
567 #endif
568 #endif /* ! GCC_GTHR_DCE_H */