]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gthr-solaris.h
trans-array.c (gfc_conv_descriptor_data_get): Rename from gfc_conv_descriptor_data.
[thirdparty/gcc.git] / gcc / gthr-solaris.h
CommitLineData
15794a95 1/* Threads compatibility routines for libgcc2 and libobjc. */
f24af81b 2/* Compile this one with gcc. */
279b5b3c 3/* Copyright (C) 1997, 1999, 2000, 2004 Free Software Foundation, Inc.
f24af81b 4
1322177d 5This file is part of GCC.
f24af81b 6
1322177d
LB
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.
f24af81b 11
1322177d
LB
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.
f24af81b
TT
16
17You should have received a copy of the GNU General Public License
1322177d
LB
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. */
f24af81b
TT
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
88657302
RH
29#ifndef GCC_GTHR_SOLARIS_H
30#define GCC_GTHR_SOLARIS_H
f24af81b
TT
31
32/* Solaris threads as found in Solaris 2.[456].
33 Actually these are Unix International (UI) threads, but I don't
71287280 34 know if anyone else implements these. */
f24af81b
TT
35
36#define __GTHREADS 1
37
38#include <thread.h>
39#include <errno.h>
40
41typedef thread_key_t __gthread_key_t;
e6179f45 42typedef struct {
f24af81b
TT
43 mutex_t mutex;
44 int once;
45} __gthread_once_t;
46typedef mutex_t __gthread_mutex_t;
7ed5d5b2
EB
47
48typedef struct {
49 long depth;
50 thread_t owner;
51 mutex_t actual;
52} __gthread_recursive_mutex_t;
f24af81b
TT
53
54#define __GTHREAD_ONCE_INIT { DEFAULTMUTEX, 0 }
55#define __GTHREAD_MUTEX_INIT DEFAULTMUTEX
7ed5d5b2 56#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
f24af81b
TT
57
58#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
59
60#pragma weak thr_keycreate
61#pragma weak thr_getspecific
62#pragma weak thr_setspecific
63#pragma weak thr_create
64
65#pragma weak mutex_lock
66#pragma weak mutex_trylock
67#pragma weak mutex_unlock
68
15794a95
L
69#ifdef _LIBOBJC
70#pragma weak thr_exit
71#pragma weak thr_keycreate
72#pragma weak thr_getprio
73#pragma weak thr_self
74#pragma weak thr_setprio
75#pragma weak thr_yield
76
77#pragma weak cond_init
78#pragma weak cond_destroy
79#pragma weak cond_wait
80#pragma weak cond_broadcast
81#pragma weak cond_signal
82
83#pragma weak mutex_init
84#pragma weak mutex_destroy
85#endif
86
f24af81b 87/* This will not actually work in Solaris 2.5, since libc contains
71287280 88 dummy symbols of all thr_* routines. */
f24af81b 89
f24af81b 90static inline int
d1e51320 91__gthread_active_p (void)
f24af81b 92{
7a8de19b 93 static void *const __gthread_active_ptr = (void *) &thr_create;
f24af81b
TT
94 return __gthread_active_ptr != 0;
95}
96
97#else /* not SUPPORTS_WEAK */
98
99static inline int
d1e51320 100__gthread_active_p (void)
f24af81b
TT
101{
102 return 1;
103}
104
105#endif /* SUPPORTS_WEAK */
106
15794a95
L
107#ifdef _LIBOBJC
108
109/* Key structure for maintaining thread specific storage */
110static thread_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
71287280 117/* Initialize the threads subsystem. */
15794a95 118static inline int
e6179f45 119__gthread_objc_init_thread_system (void)
15794a95 120{
ea4b7848 121 /* Initialize the thread storage key. */
15794a95 122 if (__gthread_active_p ()
e6179f45 123 && thr_keycreate (&_objc_thread_storage, NULL) == 0)
15794a95
L
124 return 0;
125
126 return -1;
127}
128
71287280 129/* Close the threads subsystem. */
15794a95 130static inline int
e6179f45 131__gthread_objc_close_thread_system (void)
15794a95
L
132{
133 if (__gthread_active_p ())
134 return 0;
135 else
136 return -1;
137}
138
139/* Backend thread functions */
140
71287280 141/* Create a new thread of execution. */
15794a95 142static inline objc_thread_t
e6179f45 143__gthread_objc_thread_detach (void (*func)(void *), void *arg)
15794a95
L
144{
145 objc_thread_t thread_id;
146 thread_t new_thread_id = 0;
147
148 if (!__gthread_active_p ())
149 return NULL;
589005ff 150
e6179f45
KH
151 if (thr_create (NULL, 0, (void *) func, arg,
152 THR_DETACHED | THR_NEW_LWP,
153 &new_thread_id) == 0)
154 thread_id = *(objc_thread_t *) &new_thread_id;
15794a95
L
155 else
156 thread_id = NULL;
589005ff 157
15794a95
L
158 return thread_id;
159}
160
71287280 161/* Set the current thread's priority. */
15794a95 162static inline int
e6179f45 163__gthread_objc_thread_set_priority (int priority)
15794a95
L
164{
165 int sys_priority = 0;
166
167 if (!__gthread_active_p ())
168 return -1;
169
170 switch (priority)
171 {
172 case OBJC_THREAD_INTERACTIVE_PRIORITY:
173 sys_priority = 300;
174 break;
175 default:
176 case OBJC_THREAD_BACKGROUND_PRIORITY:
177 sys_priority = 200;
178 break;
179 case OBJC_THREAD_LOW_PRIORITY:
180 sys_priority = 1000;
181 break;
182 }
183
184 /* Change priority */
e6179f45 185 if (thr_setprio (thr_self (), sys_priority) == 0)
15794a95
L
186 return 0;
187 else
188 return -1;
189}
190
71287280 191/* Return the current thread's priority. */
15794a95 192static inline int
e6179f45 193__gthread_objc_thread_get_priority (void)
15794a95
L
194{
195 int sys_priority;
196
197 if (!__gthread_active_p ())
198 return OBJC_THREAD_INTERACTIVE_PRIORITY;
589005ff 199
e6179f45 200 if (thr_getprio (thr_self (), &sys_priority) == 0)
15794a95
L
201 {
202 if (sys_priority >= 250)
203 return OBJC_THREAD_INTERACTIVE_PRIORITY;
204 else if (sys_priority >= 150)
205 return OBJC_THREAD_BACKGROUND_PRIORITY;
206 return OBJC_THREAD_LOW_PRIORITY;
207 }
208
71287280 209 /* Couldn't get priority. */
15794a95
L
210 return -1;
211}
212
71287280 213/* Yield our process time to another thread. */
15794a95 214static inline void
e6179f45 215__gthread_objc_thread_yield (void)
15794a95
L
216{
217 if (__gthread_active_p ())
e6179f45 218 thr_yield ();
15794a95
L
219}
220
71287280 221/* Terminate the current thread. */
15794a95 222static inline int
e6179f45 223__gthread_objc_thread_exit (void)
15794a95
L
224{
225 if (__gthread_active_p ())
226 /* exit the thread */
e6179f45 227 thr_exit (&__objc_thread_exit_status);
15794a95
L
228
229 /* Failed if we reached here */
230 return -1;
231}
232
71287280 233/* Returns an integer value which uniquely describes a thread. */
15794a95 234static inline objc_thread_t
e6179f45 235__gthread_objc_thread_id (void)
15794a95
L
236{
237 if (__gthread_active_p ())
e6179f45 238 return (objc_thread_t) thr_self ();
15794a95 239 else
e6179f45 240 return (objc_thread_t) 1;
15794a95
L
241}
242
71287280 243/* Sets the thread's local storage pointer. */
15794a95 244static inline int
e6179f45 245__gthread_objc_thread_set_data (void *value)
15794a95
L
246{
247 if (__gthread_active_p ())
248 {
e6179f45 249 if (thr_setspecific (_objc_thread_storage, value) == 0)
15794a95
L
250 return 0;
251 else
252 return -1;
253 }
254 else
255 {
256 thread_local_storage = value;
257 return 0;
258 }
259}
260
71287280 261/* Returns the thread's local storage pointer. */
15794a95 262static inline void *
e6179f45 263__gthread_objc_thread_get_data (void)
15794a95
L
264{
265 void *value = NULL;
266
267 if (__gthread_active_p ())
268 {
e6179f45 269 if (thr_getspecific (_objc_thread_storage, &value) == 0)
15794a95
L
270 return value;
271 else
272 return NULL;
273 }
274 else
275 return thread_local_storage;
276}
277
278/* Backend mutex functions */
279
71287280 280/* Allocate a mutex. */
15794a95 281static inline int
e6179f45 282__gthread_objc_mutex_allocate (objc_mutex_t mutex)
15794a95
L
283{
284 if (__gthread_active_p ()
e6179f45 285 && mutex_init ((mutex_t *) (&(mutex->backend)), USYNC_THREAD, 0))
15794a95
L
286 return -1;
287
288 return 0;
289}
290
71287280 291/* Deallocate a mutex. */
15794a95 292static inline int
e6179f45 293__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
15794a95
L
294{
295 if (__gthread_active_p ())
e6179f45 296 mutex_destroy ((mutex_t *) (&(mutex->backend)));
15794a95
L
297
298 return 0;
299}
300
71287280 301/* Grab a lock on a mutex. */
15794a95 302static inline int
e6179f45 303__gthread_objc_mutex_lock (objc_mutex_t mutex)
15794a95
L
304{
305 if (__gthread_active_p ()
e6179f45 306 && mutex_lock ((mutex_t *) (&(mutex->backend))) != 0)
15794a95
L
307 return -1;
308
309 return 0;
310}
311
71287280 312/* Try to grab a lock on a mutex. */
15794a95 313static inline int
e6179f45 314__gthread_objc_mutex_trylock (objc_mutex_t mutex)
15794a95
L
315{
316 if (__gthread_active_p ()
e6179f45 317 && mutex_trylock ((mutex_t *) (&(mutex->backend))) != 0)
15794a95
L
318 return -1;
319
320 return 0;
321}
322
323/* Unlock the mutex */
324static inline int
e6179f45 325__gthread_objc_mutex_unlock (objc_mutex_t mutex)
15794a95
L
326{
327 if (__gthread_active_p ()
e6179f45 328 && mutex_unlock ((mutex_t *) (&(mutex->backend))) != 0)
15794a95
L
329 return -1;
330
331 return 0;
332}
333
334/* Backend condition mutex functions */
335
71287280 336/* Allocate a condition. */
15794a95 337static inline int
e6179f45 338__gthread_objc_condition_allocate (objc_condition_t condition)
15794a95
L
339{
340 if (__gthread_active_p ())
e6179f45
KH
341 return cond_init ((cond_t *) (&(condition->backend)), USYNC_THREAD,
342 NULL);
15794a95
L
343 else
344 return 0;
345}
346
71287280 347/* Deallocate a condition. */
15794a95 348static inline int
e6179f45 349__gthread_objc_condition_deallocate (objc_condition_t condition)
15794a95
L
350{
351 if (__gthread_active_p ())
e6179f45 352 return cond_destroy ((cond_t *) (&(condition->backend)));
15794a95
L
353 else
354 return 0;
355}
356
357/* Wait on the condition */
358static inline int
e6179f45 359__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
15794a95
L
360{
361 if (__gthread_active_p ())
e6179f45
KH
362 return cond_wait ((cond_t *) (&(condition->backend)),
363 (mutex_t *) (&(mutex->backend)));
15794a95
L
364 else
365 return 0;
366}
367
71287280 368/* Wake up all threads waiting on this condition. */
15794a95 369static inline int
e6179f45 370__gthread_objc_condition_broadcast (objc_condition_t condition)
15794a95
L
371{
372 if (__gthread_active_p ())
e6179f45 373 return cond_broadcast ((cond_t *) (&(condition->backend)));
15794a95
L
374 else
375 return 0;
376}
377
71287280 378/* Wake up one thread waiting on this condition. */
15794a95 379static inline int
e6179f45 380__gthread_objc_condition_signal (objc_condition_t condition)
15794a95
L
381{
382 if (__gthread_active_p ())
e6179f45 383 return cond_signal ((cond_t *) (&(condition->backend)));
15794a95
L
384 else
385 return 0;
386}
387
388#else /* _LIBOBJC */
389
f24af81b 390static inline int
d1e51320 391__gthread_once (__gthread_once_t *once, void (*func) (void))
f24af81b
TT
392{
393 if (! __gthread_active_p ())
394 return -1;
395
396 if (once == 0 || func == 0)
754d1a92 397 return EINVAL;
f24af81b
TT
398
399 if (once->once == 0)
400 {
754d1a92
TT
401 int status = mutex_lock (&once->mutex);
402 if (status != 0)
403 return status;
f24af81b
TT
404 if (once->once == 0)
405 {
406 (*func) ();
e6179f45 407 once->once++;
f24af81b
TT
408 }
409 mutex_unlock (&once->mutex);
410 }
411 return 0;
412}
413
414static inline int
415__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
416{
417 /* Solaris 2.5 contains thr_* routines no-op in libc, so test if we actually
71287280 418 got a reasonable key value, and if not, fail. */
7ed5d5b2
EB
419 *key = (__gthread_key_t)-1;
420 if (thr_keycreate (key, dtor) != 0 || *key == (__gthread_key_t)-1)
f24af81b
TT
421 return -1;
422 else
423 return 0;
424}
425
f24af81b
TT
426static inline int
427__gthread_key_delete (__gthread_key_t key)
428{
71287280 429 /* Not possible. */
f24af81b
TT
430 return -1;
431}
432
433static inline void *
434__gthread_getspecific (__gthread_key_t key)
435{
436 void *ptr;
437 if (thr_getspecific (key, &ptr) == 0)
438 return ptr;
439 else
440 return 0;
441}
442
443static inline int
444__gthread_setspecific (__gthread_key_t key, const void *ptr)
445{
446 return thr_setspecific (key, (void *) ptr);
447}
448
449static inline int
450__gthread_mutex_lock (__gthread_mutex_t *mutex)
451{
452 if (__gthread_active_p ())
453 return mutex_lock (mutex);
454 else
455 return 0;
456}
457
458static inline int
459__gthread_mutex_trylock (__gthread_mutex_t *mutex)
460{
461 if (__gthread_active_p ())
462 return mutex_trylock (mutex);
463 else
464 return 0;
465}
466
467static inline int
468__gthread_mutex_unlock (__gthread_mutex_t *mutex)
469{
470 if (__gthread_active_p ())
471 return mutex_unlock (mutex);
472 else
473 return 0;
474}
475
7ed5d5b2
EB
476static inline int
477__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
478{
479 mutex->depth = 0;
480 mutex->owner = (thread_t) 0;
6d861604 481 return mutex_init (&mutex->actual, USYNC_THREAD, 0);
7ed5d5b2
EB
482}
483
40aac948
JM
484static inline int
485__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
486{
7ed5d5b2
EB
487 if (__gthread_active_p ())
488 {
489 thread_t me = thr_self ();
490
491 if (mutex->owner != me)
492 {
493 mutex_lock (&mutex->actual);
494 mutex->owner = me;
495 }
496
497 mutex->depth++;
498 }
499 return 0;
40aac948
JM
500}
501
502static inline int
503__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
504{
7ed5d5b2
EB
505 if (__gthread_active_p ())
506 {
507 thread_t me = thr_self ();
508
509 if (mutex->owner != me)
510 {
511 if (mutex_trylock (&mutex->actual))
512 return 1;
513 mutex->owner = me;
514 }
515
516 mutex->depth++;
517 }
518 return 0;
40aac948
JM
519}
520
521static inline int
522__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
523{
7ed5d5b2
EB
524 if (__gthread_active_p ())
525 {
526 if (--mutex->depth == 0)
527 {
528 mutex->owner = (thread_t) 0;
529 mutex_unlock (&mutex->actual);
530 }
531 }
532 return 0;
40aac948
JM
533}
534
15794a95
L
535#endif /* _LIBOBJC */
536
88657302 537#endif /* ! GCC_GTHR_SOLARIS_H */