2 /* Compile this one with gcc. */
3 /* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
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. */
32 /* DCE threads interface.
33 DCE threads are based on POSIX threads draft 4, and many things
34 have changed since then. */
40 typedef pthread_key_t __gthread_key_t
;
41 typedef pthread_once_t __gthread_once_t
;
42 typedef pthread_mutex_t __gthread_mutex_t
;
44 #define __GTHREAD_ONCE_INIT pthread_once_init
45 /* Howto define __GTHREAD_MUTEX_INIT? */
47 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
49 #pragma weak pthread_once
50 #pragma weak pthread_once_init
51 #pragma weak pthread_keycreate
52 #pragma weak pthread_key_delete
53 #pragma weak pthread_getspecific
54 #pragma weak pthread_setspecific
55 #pragma weak pthread_create
57 #pragma weak pthread_mutex_lock
58 #pragma weak pthread_mutex_trylock
59 #pragma weak pthread_mutex_unlock
63 #pragma weak pthread_cond_broadcast
64 #pragma weak pthread_cond_destroy
65 #pragma weak pthread_cond_init
66 #pragma weak pthread_cond_signal
67 #pragma weak pthread_cond_wait
68 #pragma weak pthread_exit
69 #pragma weak pthread_getunique_np
70 #pragma weak pthread_mutex_init
71 #pragma weak pthread_mutex_destroy
72 #pragma weak pthread_self
73 #pragma weak pthread_yield
76 static void *__gthread_active_ptr
= &pthread_create
;
79 __gthread_active_p (void)
81 return __gthread_active_ptr
!= 0;
84 #else /* not SUPPORTS_WEAK */
87 __gthread_active_p (void)
92 #endif /* SUPPORTS_WEAK */
96 /* Key structure for maintaining thread specific storage */
97 static pthread_key_t _objc_thread_storage
;
99 /* Thread local storage for a single thread */
100 static void *thread_local_storage
= NULL
;
102 /* Backend initialization functions */
104 /* Initialize the threads subsystem. */
106 __gthread_objc_init_thread_system(void)
108 if (__gthread_active_p ())
109 /* Initialize the thread storage key */
110 return pthread_keycreate (&_objc_thread_storage
, NULL
);
115 /* Close the threads subsystem. */
117 __gthread_objc_close_thread_system(void)
119 if (__gthread_active_p ())
125 /* Backend thread functions */
127 /* Create a new thread of execution. */
128 static inline objc_thread_t
129 __gthread_objc_thread_detach(void (*func
)(void *), void *arg
)
131 objc_thread_t thread_id
;
132 pthread_t new_thread_handle
;
134 if (!__gthread_active_p ())
137 if ( !(pthread_create(&new_thread_handle
, pthread_attr_default
,
138 (void *)func
, arg
)) )
140 /* ??? May not work! (64bit) */
141 thread_id
= *(objc_thread_t
*)&new_thread_handle
;
142 pthread_detach(&new_thread_handle
); /* Fully detach thread. */
150 /* Set the current thread's priority. */
152 __gthread_objc_thread_set_priority(int priority
)
154 int sys_priority
= 0;
156 if (!__gthread_active_p ())
161 case OBJC_THREAD_INTERACTIVE_PRIORITY
:
162 sys_priority
= (PRI_FG_MIN_NP
+ PRI_FG_MAX_NP
) / 2;
165 case OBJC_THREAD_BACKGROUND_PRIORITY
:
166 sys_priority
= (PRI_BG_MIN_NP
+ PRI_BG_MAX_NP
) / 2;
168 case OBJC_THREAD_LOW_PRIORITY
:
169 sys_priority
= (PRI_BG_MIN_NP
+ PRI_BG_MAX_NP
) / 2;
173 /* Change the priority. */
174 if (pthread_setprio(pthread_self(), sys_priority
) >= 0)
181 /* Return the current thread's priority. */
183 __gthread_objc_thread_get_priority(void)
187 if (__gthread_active_p ())
189 if ((sys_priority
= pthread_getprio(pthread_self())) >= 0)
191 if (sys_priority
>= PRI_FG_MIN_NP
192 && sys_priority
<= PRI_FG_MAX_NP
)
193 return OBJC_THREAD_INTERACTIVE_PRIORITY
;
194 if (sys_priority
>= PRI_BG_MIN_NP
195 && sys_priority
<= PRI_BG_MAX_NP
)
196 return OBJC_THREAD_BACKGROUND_PRIORITY
;
197 return OBJC_THREAD_LOW_PRIORITY
;
204 return OBJC_THREAD_INTERACTIVE_PRIORITY
;
207 /* Yield our process time to another thread. */
209 __gthread_objc_thread_yield(void)
211 if (__gthread_active_p ())
215 /* Terminate the current thread. */
217 __gthread_objc_thread_exit(void)
219 if (__gthread_active_p ())
220 /* exit the thread */
221 pthread_exit(&__objc_thread_exit_status
);
223 /* Failed if we reached here */
227 /* Returns an integer value which uniquely describes a thread. */
228 static inline objc_thread_t
229 __gthread_objc_thread_id(void)
231 if (__gthread_active_p ())
233 pthread_t self
= pthread_self();
235 return (objc_thread_t
) pthread_getunique_np (&self
);
238 return (objc_thread_t
)1;
241 /* Sets the thread's local storage pointer. */
243 __gthread_objc_thread_set_data(void *value
)
245 if (__gthread_active_p ())
246 return pthread_setspecific(_objc_thread_storage
, value
);
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 ( !(pthread_getspecific(_objc_thread_storage
, &value
)) )
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 && pthread_mutex_init((pthread_mutex_t
*)mutex
->backend
,
279 pthread_mutexattr_default
))
285 /* Deallocate a mutex. */
287 __gthread_objc_mutex_deallocate(objc_mutex_t mutex
)
289 if (__gthread_active_p ()
290 && pthread_mutex_destroy((pthread_mutex_t
*)mutex
->backend
))
296 /* Grab a lock on a mutex. */
298 __gthread_objc_mutex_lock(objc_mutex_t mutex
)
300 if (__gthread_active_p ())
301 return pthread_mutex_lock((pthread_mutex_t
*)mutex
->backend
);
306 /* Try to grab a lock on a mutex. */
308 __gthread_objc_mutex_trylock(objc_mutex_t mutex
)
310 if (__gthread_active_p ()
311 && pthread_mutex_trylock((pthread_mutex_t
*)mutex
->backend
) != 1)
317 /* Unlock the mutex */
319 __gthread_objc_mutex_unlock(objc_mutex_t mutex
)
321 if (__gthread_active_p ())
322 return pthread_mutex_unlock((pthread_mutex_t
*)mutex
->backend
);
327 /* Backend condition mutex functions */
329 /* Allocate a condition. */
331 __gthread_objc_condition_allocate(objc_condition_t condition
)
333 if (__gthread_active_p ())
340 /* Deallocate a condition. */
342 __gthread_objc_condition_deallocate(objc_condition_t condition
)
344 if (__gthread_active_p ())
351 /* Wait on the condition */
353 __gthread_objc_condition_wait(objc_condition_t condition
, objc_mutex_t mutex
)
355 if (__gthread_active_p ())
362 /* Wake up all threads waiting on this condition. */
364 __gthread_objc_condition_broadcast(objc_condition_t condition
)
366 if (__gthread_active_p ())
373 /* Wake up one thread waiting on this condition. */
375 __gthread_objc_condition_signal(objc_condition_t condition
)
377 if (__gthread_active_p ())
387 __gthread_once (__gthread_once_t
*once
, void (*func
) (void))
389 if (__gthread_active_p ())
390 return pthread_once (once
, func
);
396 __gthread_key_create (__gthread_key_t
*key
, void (*dtor
) (void *))
398 return pthread_keycreate (key
, dtor
);
402 __gthread_key_dtor (__gthread_key_t key
, void *ptr
)
404 /* Nothing needed. */
409 __gthread_key_delete (__gthread_key_t key
)
411 return pthread_key_delete (key
);
415 __gthread_getspecific (__gthread_key_t key
)
418 if (pthread_getspecific (key
, &ptr
) == 0)
425 __gthread_setspecific (__gthread_key_t key
, const void *ptr
)
427 return pthread_setspecific (key
, (void *) ptr
);
431 __gthread_mutex_lock (__gthread_mutex_t
*mutex
)
433 if (__gthread_active_p ())
434 return pthread_mutex_lock (mutex
);
440 __gthread_mutex_trylock (__gthread_mutex_t
*mutex
)
442 if (__gthread_active_p ())
443 return pthread_mutex_trylock (mutex
);
449 __gthread_mutex_unlock (__gthread_mutex_t
*mutex
)
451 if (__gthread_active_p ())
452 return pthread_mutex_unlock (mutex
);
457 #endif /* _LIBOBJC */
459 #endif /* not __gthr_dce_h */