1 /* Threads compatibility routines for libgcc2 and libobjc. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1997, 1999, 2000 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 2, or (at your option) any later
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
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
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. */
29 #ifndef GCC_GTHR_SOLARIS_H
30 #define GCC_GTHR_SOLARIS_H
32 /* Solaris threads as found in Solaris 2.[456].
33 Actually these are Unix International (UI) threads, but I don't
34 know if anyone else implements these. */
41 typedef thread_key_t __gthread_key_t
;
46 typedef mutex_t __gthread_mutex_t
;
48 #define __GTHREAD_ONCE_INIT { DEFAULTMUTEX, 0 }
49 #define __GTHREAD_MUTEX_INIT DEFAULTMUTEX
51 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
53 #pragma weak thr_keycreate
54 #pragma weak thr_getspecific
55 #pragma weak thr_setspecific
56 #pragma weak thr_create
58 #pragma weak mutex_lock
59 #pragma weak mutex_trylock
60 #pragma weak mutex_unlock
64 #pragma weak thr_keycreate
65 #pragma weak thr_getprio
67 #pragma weak thr_setprio
68 #pragma weak thr_yield
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
76 #pragma weak mutex_init
77 #pragma weak mutex_destroy
80 /* This will not actually work in Solaris 2.5, since libc contains
81 dummy symbols of all thr_* routines. */
84 __gthread_active_p (void)
86 static void *const __gthread_active_ptr
= (void *) &thr_create
;
87 return __gthread_active_ptr
!= 0;
90 #else /* not SUPPORTS_WEAK */
93 __gthread_active_p (void)
98 #endif /* SUPPORTS_WEAK */
102 /* Key structure for maintaining thread specific storage */
103 static thread_key_t _objc_thread_storage
;
105 /* Thread local storage for a single thread */
106 static void *thread_local_storage
= NULL
;
108 /* Backend initialization functions */
110 /* Initialize the threads subsystem. */
112 __gthread_objc_init_thread_system (void)
114 /* Initialize the thread storage key */
115 if (__gthread_active_p ()
116 && thr_keycreate (&_objc_thread_storage
, NULL
) == 0)
122 /* Close the threads subsystem. */
124 __gthread_objc_close_thread_system (void)
126 if (__gthread_active_p ())
132 /* Backend thread functions */
134 /* Create a new thread of execution. */
135 static inline objc_thread_t
136 __gthread_objc_thread_detach (void (*func
)(void *), void *arg
)
138 objc_thread_t thread_id
;
139 thread_t new_thread_id
= 0;
141 if (!__gthread_active_p ())
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
;
154 /* Set the current thread's priority. */
156 __gthread_objc_thread_set_priority (int priority
)
158 int sys_priority
= 0;
160 if (!__gthread_active_p ())
165 case OBJC_THREAD_INTERACTIVE_PRIORITY
:
169 case OBJC_THREAD_BACKGROUND_PRIORITY
:
172 case OBJC_THREAD_LOW_PRIORITY
:
177 /* Change priority */
178 if (thr_setprio (thr_self (), sys_priority
) == 0)
184 /* Return the current thread's priority. */
186 __gthread_objc_thread_get_priority (void)
190 if (!__gthread_active_p ())
191 return OBJC_THREAD_INTERACTIVE_PRIORITY
;
193 if (thr_getprio (thr_self (), &sys_priority
) == 0)
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
;
202 /* Couldn't get priority. */
206 /* Yield our process time to another thread. */
208 __gthread_objc_thread_yield (void)
210 if (__gthread_active_p ())
214 /* Terminate the current thread. */
216 __gthread_objc_thread_exit (void)
218 if (__gthread_active_p ())
219 /* exit the thread */
220 thr_exit (&__objc_thread_exit_status
);
222 /* Failed if we reached here */
226 /* Returns an integer value which uniquely describes a thread. */
227 static inline objc_thread_t
228 __gthread_objc_thread_id (void)
230 if (__gthread_active_p ())
231 return (objc_thread_t
) thr_self ();
233 return (objc_thread_t
) 1;
236 /* Sets the thread's local storage pointer. */
238 __gthread_objc_thread_set_data (void *value
)
240 if (__gthread_active_p ())
242 if (thr_setspecific (_objc_thread_storage
, value
) == 0)
249 thread_local_storage
= value
;
254 /* Returns the thread's local storage pointer. */
256 __gthread_objc_thread_get_data (void)
260 if (__gthread_active_p ())
262 if (thr_getspecific (_objc_thread_storage
, &value
) == 0)
268 return thread_local_storage
;
271 /* Backend mutex functions */
273 /* Allocate a mutex. */
275 __gthread_objc_mutex_allocate (objc_mutex_t mutex
)
277 if (__gthread_active_p ()
278 && mutex_init ((mutex_t
*) (&(mutex
->backend
)), USYNC_THREAD
, 0))
284 /* Deallocate a mutex. */
286 __gthread_objc_mutex_deallocate (objc_mutex_t mutex
)
288 if (__gthread_active_p ())
289 mutex_destroy ((mutex_t
*) (&(mutex
->backend
)));
294 /* Grab a lock on a mutex. */
296 __gthread_objc_mutex_lock (objc_mutex_t mutex
)
298 if (__gthread_active_p ()
299 && mutex_lock ((mutex_t
*) (&(mutex
->backend
))) != 0)
305 /* Try to grab a lock on a mutex. */
307 __gthread_objc_mutex_trylock (objc_mutex_t mutex
)
309 if (__gthread_active_p ()
310 && mutex_trylock ((mutex_t
*) (&(mutex
->backend
))) != 0)
316 /* Unlock the mutex */
318 __gthread_objc_mutex_unlock (objc_mutex_t mutex
)
320 if (__gthread_active_p ()
321 && mutex_unlock ((mutex_t
*) (&(mutex
->backend
))) != 0)
327 /* Backend condition mutex functions */
329 /* Allocate a condition. */
331 __gthread_objc_condition_allocate (objc_condition_t condition
)
333 if (__gthread_active_p ())
334 return cond_init ((cond_t
*) (&(condition
->backend
)), USYNC_THREAD
,
340 /* Deallocate a condition. */
342 __gthread_objc_condition_deallocate (objc_condition_t condition
)
344 if (__gthread_active_p ())
345 return cond_destroy ((cond_t
*) (&(condition
->backend
)));
350 /* Wait on the condition */
352 __gthread_objc_condition_wait (objc_condition_t condition
, objc_mutex_t mutex
)
354 if (__gthread_active_p ())
355 return cond_wait ((cond_t
*) (&(condition
->backend
)),
356 (mutex_t
*) (&(mutex
->backend
)));
361 /* Wake up all threads waiting on this condition. */
363 __gthread_objc_condition_broadcast (objc_condition_t condition
)
365 if (__gthread_active_p ())
366 return cond_broadcast ((cond_t
*) (&(condition
->backend
)));
371 /* Wake up one thread waiting on this condition. */
373 __gthread_objc_condition_signal (objc_condition_t condition
)
375 if (__gthread_active_p ())
376 return cond_signal ((cond_t
*) (&(condition
->backend
)));
384 __gthread_once (__gthread_once_t
*once
, void (*func
) (void))
386 if (! __gthread_active_p ())
389 if (once
== 0 || func
== 0)
394 int status
= mutex_lock (&once
->mutex
);
402 mutex_unlock (&once
->mutex
);
408 __gthread_key_create (__gthread_key_t
*key
, void (*dtor
) (void *))
410 /* Solaris 2.5 contains thr_* routines no-op in libc, so test if we actually
411 got a reasonable key value, and if not, fail. */
413 if (thr_keycreate (key
, dtor
) != 0 || *key
== -1)
420 __gthread_key_delete (__gthread_key_t key
)
427 __gthread_getspecific (__gthread_key_t key
)
430 if (thr_getspecific (key
, &ptr
) == 0)
437 __gthread_setspecific (__gthread_key_t key
, const void *ptr
)
439 return thr_setspecific (key
, (void *) ptr
);
443 __gthread_mutex_lock (__gthread_mutex_t
*mutex
)
445 if (__gthread_active_p ())
446 return mutex_lock (mutex
);
452 __gthread_mutex_trylock (__gthread_mutex_t
*mutex
)
454 if (__gthread_active_p ())
455 return mutex_trylock (mutex
);
461 __gthread_mutex_unlock (__gthread_mutex_t
*mutex
)
463 if (__gthread_active_p ())
464 return mutex_unlock (mutex
);
469 #endif /* _LIBOBJC */
471 #endif /* ! GCC_GTHR_SOLARIS_H */