]> gcc.gnu.org Git - gcc.git/blame - gcc/gthr-solaris.h
flags.h (enum debug_info_type): Remove DWARF_DEBUG.
[gcc.git] / gcc / gthr-solaris.h
CommitLineData
15794a95 1/* Threads compatibility routines for libgcc2 and libobjc. */
f24af81b 2/* Compile this one with gcc. */
15794a95 3/* Copyright (C) 1997, 1999, 2000 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;
47
48#define __GTHREAD_ONCE_INIT { DEFAULTMUTEX, 0 }
49#define __GTHREAD_MUTEX_INIT DEFAULTMUTEX
50
51#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
52
53#pragma weak thr_keycreate
54#pragma weak thr_getspecific
55#pragma weak thr_setspecific
56#pragma weak thr_create
57
58#pragma weak mutex_lock
59#pragma weak mutex_trylock
60#pragma weak mutex_unlock
61
15794a95
L
62#ifdef _LIBOBJC
63#pragma weak thr_exit
64#pragma weak thr_keycreate
65#pragma weak thr_getprio
66#pragma weak thr_self
67#pragma weak thr_setprio
68#pragma weak thr_yield
69
70#pragma weak cond_init
71#pragma weak cond_destroy
72#pragma weak cond_wait
73#pragma weak cond_broadcast
74#pragma weak cond_signal
75
76#pragma weak mutex_init
77#pragma weak mutex_destroy
78#endif
79
f24af81b 80/* This will not actually work in Solaris 2.5, since libc contains
71287280 81 dummy symbols of all thr_* routines. */
f24af81b 82
f24af81b 83static inline int
d1e51320 84__gthread_active_p (void)
f24af81b 85{
7a8de19b 86 static void *const __gthread_active_ptr = (void *) &thr_create;
f24af81b
TT
87 return __gthread_active_ptr != 0;
88}
89
90#else /* not SUPPORTS_WEAK */
91
92static inline int
d1e51320 93__gthread_active_p (void)
f24af81b
TT
94{
95 return 1;
96}
97
98#endif /* SUPPORTS_WEAK */
99
15794a95
L
100#ifdef _LIBOBJC
101
102/* Key structure for maintaining thread specific storage */
103static thread_key_t _objc_thread_storage;
104
105/* Thread local storage for a single thread */
106static void *thread_local_storage = NULL;
107
108/* Backend initialization functions */
109
71287280 110/* Initialize the threads subsystem. */
15794a95 111static inline int
e6179f45 112__gthread_objc_init_thread_system (void)
15794a95
L
113{
114 /* Initialize the thread storage key */
115 if (__gthread_active_p ()
e6179f45 116 && thr_keycreate (&_objc_thread_storage, NULL) == 0)
15794a95
L
117 return 0;
118
119 return -1;
120}
121
71287280 122/* Close the threads subsystem. */
15794a95 123static inline int
e6179f45 124__gthread_objc_close_thread_system (void)
15794a95
L
125{
126 if (__gthread_active_p ())
127 return 0;
128 else
129 return -1;
130}
131
132/* Backend thread functions */
133
71287280 134/* Create a new thread of execution. */
15794a95 135static inline objc_thread_t
e6179f45 136__gthread_objc_thread_detach (void (*func)(void *), void *arg)
15794a95
L
137{
138 objc_thread_t thread_id;
139 thread_t new_thread_id = 0;
140
141 if (!__gthread_active_p ())
142 return NULL;
589005ff 143
e6179f45
KH
144 if (thr_create (NULL, 0, (void *) func, arg,
145 THR_DETACHED | THR_NEW_LWP,
146 &new_thread_id) == 0)
147 thread_id = *(objc_thread_t *) &new_thread_id;
15794a95
L
148 else
149 thread_id = NULL;
589005ff 150
15794a95
L
151 return thread_id;
152}
153
71287280 154/* Set the current thread's priority. */
15794a95 155static inline int
e6179f45 156__gthread_objc_thread_set_priority (int priority)
15794a95
L
157{
158 int sys_priority = 0;
159
160 if (!__gthread_active_p ())
161 return -1;
162
163 switch (priority)
164 {
165 case OBJC_THREAD_INTERACTIVE_PRIORITY:
166 sys_priority = 300;
167 break;
168 default:
169 case OBJC_THREAD_BACKGROUND_PRIORITY:
170 sys_priority = 200;
171 break;
172 case OBJC_THREAD_LOW_PRIORITY:
173 sys_priority = 1000;
174 break;
175 }
176
177 /* Change priority */
e6179f45 178 if (thr_setprio (thr_self (), sys_priority) == 0)
15794a95
L
179 return 0;
180 else
181 return -1;
182}
183
71287280 184/* Return the current thread's priority. */
15794a95 185static inline int
e6179f45 186__gthread_objc_thread_get_priority (void)
15794a95
L
187{
188 int sys_priority;
189
190 if (!__gthread_active_p ())
191 return OBJC_THREAD_INTERACTIVE_PRIORITY;
589005ff 192
e6179f45 193 if (thr_getprio (thr_self (), &sys_priority) == 0)
15794a95
L
194 {
195 if (sys_priority >= 250)
196 return OBJC_THREAD_INTERACTIVE_PRIORITY;
197 else if (sys_priority >= 150)
198 return OBJC_THREAD_BACKGROUND_PRIORITY;
199 return OBJC_THREAD_LOW_PRIORITY;
200 }
201
71287280 202 /* Couldn't get priority. */
15794a95
L
203 return -1;
204}
205
71287280 206/* Yield our process time to another thread. */
15794a95 207static inline void
e6179f45 208__gthread_objc_thread_yield (void)
15794a95
L
209{
210 if (__gthread_active_p ())
e6179f45 211 thr_yield ();
15794a95
L
212}
213
71287280 214/* Terminate the current thread. */
15794a95 215static inline int
e6179f45 216__gthread_objc_thread_exit (void)
15794a95
L
217{
218 if (__gthread_active_p ())
219 /* exit the thread */
e6179f45 220 thr_exit (&__objc_thread_exit_status);
15794a95
L
221
222 /* Failed if we reached here */
223 return -1;
224}
225
71287280 226/* Returns an integer value which uniquely describes a thread. */
15794a95 227static inline objc_thread_t
e6179f45 228__gthread_objc_thread_id (void)
15794a95
L
229{
230 if (__gthread_active_p ())
e6179f45 231 return (objc_thread_t) thr_self ();
15794a95 232 else
e6179f45 233 return (objc_thread_t) 1;
15794a95
L
234}
235
71287280 236/* Sets the thread's local storage pointer. */
15794a95 237static inline int
e6179f45 238__gthread_objc_thread_set_data (void *value)
15794a95
L
239{
240 if (__gthread_active_p ())
241 {
e6179f45 242 if (thr_setspecific (_objc_thread_storage, value) == 0)
15794a95
L
243 return 0;
244 else
245 return -1;
246 }
247 else
248 {
249 thread_local_storage = value;
250 return 0;
251 }
252}
253
71287280 254/* Returns the thread's local storage pointer. */
15794a95 255static inline void *
e6179f45 256__gthread_objc_thread_get_data (void)
15794a95
L
257{
258 void *value = NULL;
259
260 if (__gthread_active_p ())
261 {
e6179f45 262 if (thr_getspecific (_objc_thread_storage, &value) == 0)
15794a95
L
263 return value;
264 else
265 return NULL;
266 }
267 else
268 return thread_local_storage;
269}
270
271/* Backend mutex functions */
272
71287280 273/* Allocate a mutex. */
15794a95 274static inline int
e6179f45 275__gthread_objc_mutex_allocate (objc_mutex_t mutex)
15794a95
L
276{
277 if (__gthread_active_p ()
e6179f45 278 && mutex_init ((mutex_t *) (&(mutex->backend)), USYNC_THREAD, 0))
15794a95
L
279 return -1;
280
281 return 0;
282}
283
71287280 284/* Deallocate a mutex. */
15794a95 285static inline int
e6179f45 286__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
15794a95
L
287{
288 if (__gthread_active_p ())
e6179f45 289 mutex_destroy ((mutex_t *) (&(mutex->backend)));
15794a95
L
290
291 return 0;
292}
293
71287280 294/* Grab a lock on a mutex. */
15794a95 295static inline int
e6179f45 296__gthread_objc_mutex_lock (objc_mutex_t mutex)
15794a95
L
297{
298 if (__gthread_active_p ()
e6179f45 299 && mutex_lock ((mutex_t *) (&(mutex->backend))) != 0)
15794a95
L
300 return -1;
301
302 return 0;
303}
304
71287280 305/* Try to grab a lock on a mutex. */
15794a95 306static inline int
e6179f45 307__gthread_objc_mutex_trylock (objc_mutex_t mutex)
15794a95
L
308{
309 if (__gthread_active_p ()
e6179f45 310 && mutex_trylock ((mutex_t *) (&(mutex->backend))) != 0)
15794a95
L
311 return -1;
312
313 return 0;
314}
315
316/* Unlock the mutex */
317static inline int
e6179f45 318__gthread_objc_mutex_unlock (objc_mutex_t mutex)
15794a95
L
319{
320 if (__gthread_active_p ()
e6179f45 321 && mutex_unlock ((mutex_t *) (&(mutex->backend))) != 0)
15794a95
L
322 return -1;
323
324 return 0;
325}
326
327/* Backend condition mutex functions */
328
71287280 329/* Allocate a condition. */
15794a95 330static inline int
e6179f45 331__gthread_objc_condition_allocate (objc_condition_t condition)
15794a95
L
332{
333 if (__gthread_active_p ())
e6179f45
KH
334 return cond_init ((cond_t *) (&(condition->backend)), USYNC_THREAD,
335 NULL);
15794a95
L
336 else
337 return 0;
338}
339
71287280 340/* Deallocate a condition. */
15794a95 341static inline int
e6179f45 342__gthread_objc_condition_deallocate (objc_condition_t condition)
15794a95
L
343{
344 if (__gthread_active_p ())
e6179f45 345 return cond_destroy ((cond_t *) (&(condition->backend)));
15794a95
L
346 else
347 return 0;
348}
349
350/* Wait on the condition */
351static inline int
e6179f45 352__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
15794a95
L
353{
354 if (__gthread_active_p ())
e6179f45
KH
355 return cond_wait ((cond_t *) (&(condition->backend)),
356 (mutex_t *) (&(mutex->backend)));
15794a95
L
357 else
358 return 0;
359}
360
71287280 361/* Wake up all threads waiting on this condition. */
15794a95 362static inline int
e6179f45 363__gthread_objc_condition_broadcast (objc_condition_t condition)
15794a95
L
364{
365 if (__gthread_active_p ())
e6179f45 366 return cond_broadcast ((cond_t *) (&(condition->backend)));
15794a95
L
367 else
368 return 0;
369}
370
71287280 371/* Wake up one thread waiting on this condition. */
15794a95 372static inline int
e6179f45 373__gthread_objc_condition_signal (objc_condition_t condition)
15794a95
L
374{
375 if (__gthread_active_p ())
e6179f45 376 return cond_signal ((cond_t *) (&(condition->backend)));
15794a95
L
377 else
378 return 0;
379}
380
381#else /* _LIBOBJC */
382
f24af81b 383static inline int
d1e51320 384__gthread_once (__gthread_once_t *once, void (*func) (void))
f24af81b
TT
385{
386 if (! __gthread_active_p ())
387 return -1;
388
389 if (once == 0 || func == 0)
754d1a92 390 return EINVAL;
f24af81b
TT
391
392 if (once->once == 0)
393 {
754d1a92
TT
394 int status = mutex_lock (&once->mutex);
395 if (status != 0)
396 return status;
f24af81b
TT
397 if (once->once == 0)
398 {
399 (*func) ();
e6179f45 400 once->once++;
f24af81b
TT
401 }
402 mutex_unlock (&once->mutex);
403 }
404 return 0;
405}
406
407static inline int
408__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
409{
410 /* Solaris 2.5 contains thr_* routines no-op in libc, so test if we actually
71287280 411 got a reasonable key value, and if not, fail. */
f24af81b 412 *key = -1;
754d1a92 413 if (thr_keycreate (key, dtor) != 0 || *key == -1)
f24af81b
TT
414 return -1;
415 else
416 return 0;
417}
418
f24af81b
TT
419static inline int
420__gthread_key_delete (__gthread_key_t key)
421{
71287280 422 /* Not possible. */
f24af81b
TT
423 return -1;
424}
425
426static inline void *
427__gthread_getspecific (__gthread_key_t key)
428{
429 void *ptr;
430 if (thr_getspecific (key, &ptr) == 0)
431 return ptr;
432 else
433 return 0;
434}
435
436static inline int
437__gthread_setspecific (__gthread_key_t key, const void *ptr)
438{
439 return thr_setspecific (key, (void *) ptr);
440}
441
442static inline int
443__gthread_mutex_lock (__gthread_mutex_t *mutex)
444{
445 if (__gthread_active_p ())
446 return mutex_lock (mutex);
447 else
448 return 0;
449}
450
451static inline int
452__gthread_mutex_trylock (__gthread_mutex_t *mutex)
453{
454 if (__gthread_active_p ())
455 return mutex_trylock (mutex);
456 else
457 return 0;
458}
459
460static inline int
461__gthread_mutex_unlock (__gthread_mutex_t *mutex)
462{
463 if (__gthread_active_p ())
464 return mutex_unlock (mutex);
465 else
466 return 0;
467}
468
15794a95
L
469#endif /* _LIBOBJC */
470
88657302 471#endif /* ! GCC_GTHR_SOLARIS_H */
This page took 1.717762 seconds and 5 git commands to generate.