]> gcc.gnu.org Git - gcc.git/blame - gcc/gthr-posix.h
objc.exp (objc_target_compile): Set the ld_library_path so that running programs...
[gcc.git] / gcc / gthr-posix.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
TT
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
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
29#ifndef __gthr_posix_h
30#define __gthr_posix_h
31
32/* POSIX threads specific definitions.
33 Easy, since the interface is just one-to-one mapping. */
34
35#define __GTHREADS 1
36
37#include <pthread.h>
38
39typedef pthread_key_t __gthread_key_t;
40typedef pthread_once_t __gthread_once_t;
41typedef pthread_mutex_t __gthread_mutex_t;
42
43#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
44#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
45
46#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
47
15794a95
L
48#pragma weak pthread_once
49#pragma weak pthread_key_create
50#pragma weak pthread_key_delete
51#pragma weak pthread_getspecific
52#pragma weak pthread_setspecific
53#pragma weak pthread_create
36244024 54
15794a95
L
55#pragma weak pthread_mutex_lock
56#pragma weak pthread_mutex_trylock
57#pragma weak pthread_mutex_unlock
58
59#ifdef _LIBOBJC
60/* Objective C. */
61#pragma weak pthread_cond_broadcast
62#pragma weak pthread_cond_destroy
63#pragma weak pthread_cond_init
64#pragma weak pthread_cond_signal
65#pragma weak pthread_cond_wait
66#pragma weak pthread_exit
67#pragma weak pthread_mutex_init
68#pragma weak pthread_mutex_destroy
69#pragma weak pthread_self
70#pragma weak sched_yield
71#endif
f24af81b
TT
72
73static void *__gthread_active_ptr = &pthread_create;
74
75static inline int
d1e51320 76__gthread_active_p (void)
f24af81b
TT
77{
78 return __gthread_active_ptr != 0;
79}
80
81#else /* not SUPPORTS_WEAK */
82
83static inline int
d1e51320 84__gthread_active_p (void)
f24af81b
TT
85{
86 return 1;
87}
88
89#endif /* SUPPORTS_WEAK */
90
15794a95
L
91#ifdef _LIBOBJC
92
93/* Key structure for maintaining thread specific storage */
94static pthread_key_t _objc_thread_storage;
95
96/* Thread local storage for a single thread */
97static void *thread_local_storage = NULL;
98
99/* Backend initialization functions */
100
101/* Initialize the threads subsystem. */
102static inline int
103__gthread_objc_init_thread_system(void)
104{
105 if (__gthread_active_p ())
106 /* Initialize the thread storage key */
107 return pthread_key_create(&_objc_thread_storage, NULL);
108 else
109 return -1;
110}
111
112/* Close the threads subsystem. */
113static inline int
114__gthread_objc_close_thread_system(void)
115{
116 if (__gthread_active_p ())
117 return 0;
118 else
119 return -1;
120}
121
122/* Backend thread functions */
123
124/* Create a new thread of execution. */
125static inline objc_thread_t
126__gthread_objc_thread_detach(void (*func)(void *), void *arg)
127{
128 objc_thread_t thread_id;
129 pthread_t new_thread_handle;
130
131 if (!__gthread_active_p ())
132 return NULL;
133
134 if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
135 thread_id = *(objc_thread_t *)&new_thread_handle;
136 else
137 thread_id = NULL;
138
139 return thread_id;
140}
141
142/* Set the current thread's priority. */
143static inline int
144__gthread_objc_thread_set_priority(int priority)
145{
146 /* Not implemented yet */
147 return -1;
148}
149
150/* Return the current thread's priority. */
151static inline int
152__gthread_objc_thread_get_priority(void)
153{
154 if (__gthread_active_p ())
155 /* Not implemented yet */
156 return -1;
157 else
158 return OBJC_THREAD_INTERACTIVE_PRIORITY;
159}
160
161/* Yield our process time to another thread. */
162static inline void
163__gthread_objc_thread_yield(void)
164{
165 if (__gthread_active_p ())
166 sched_yield();
167}
168
169/* Terminate the current thread. */
170static inline int
171__gthread_objc_thread_exit(void)
172{
173 if (__gthread_active_p ())
174 /* exit the thread */
175 pthread_exit(&__objc_thread_exit_status);
176
177 /* Failed if we reached here */
178 return -1;
179}
180
181/* Returns an integer value which uniquely describes a thread. */
182static inline objc_thread_t
183__gthread_objc_thread_id(void)
184{
185 if (__gthread_active_p ())
186 {
187 pthread_t self = pthread_self();
188
189 return *(objc_thread_t *)&self;
190 }
191 else
192 return (objc_thread_t)1;
193}
194
195/* Sets the thread's local storage pointer. */
196static inline int
197__gthread_objc_thread_set_data(void *value)
198{
199 if (__gthread_active_p ())
200 return pthread_setspecific(_objc_thread_storage, value);
201 else
202 {
203 thread_local_storage = value;
204 return 0;
205 }
206}
207
208/* Returns the thread's local storage pointer. */
209static inline void *
210__gthread_objc_thread_get_data(void)
211{
212 if (__gthread_active_p ())
213 return pthread_getspecific(_objc_thread_storage);
214 else
215 return thread_local_storage;
216}
217
218/* Backend mutex functions */
219
220/* Allocate a mutex. */
221static inline int
222__gthread_objc_mutex_allocate(objc_mutex_t mutex)
223{
224 if (__gthread_active_p ())
225 {
226 mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
227
228 if (pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL))
229 {
230 objc_free(mutex->backend);
231 mutex->backend = NULL;
232 return -1;
233 }
234 }
235
236 return 0;
237}
238
239/* Deallocate a mutex. */
240static inline int
241__gthread_objc_mutex_deallocate(objc_mutex_t mutex)
242{
243 if (__gthread_active_p ())
244 {
245 int count;
246
247 /*
248 * Posix Threads specifically require that the thread be unlocked
249 * for pthread_mutex_destroy to work.
250 */
251
252 do
253 {
254 count = pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
255 if (count < 0)
256 return -1;
257 }
258 while (count);
259
260 if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
261 return -1;
262
263 objc_free(mutex->backend);
264 mutex->backend = NULL;
265 }
266 return 0;
267}
268
269/* Grab a lock on a mutex. */
270static inline int
271__gthread_objc_mutex_lock(objc_mutex_t mutex)
272{
273 if (__gthread_active_p ())
274 return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
275 else
276 return 0;
277}
278
279/* Try to grab a lock on a mutex. */
280static inline int
281__gthread_objc_mutex_trylock(objc_mutex_t mutex)
282{
283 if (__gthread_active_p ())
284 return pthread_mutex_trylock((pthread_mutex_t *)mutex->backend);
285 else
286 return 0;
287}
288
289/* Unlock the mutex */
290static inline int
291__gthread_objc_mutex_unlock(objc_mutex_t mutex)
292{
293 if (__gthread_active_p ())
294 return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
295 else
296 return 0;
297}
298
299/* Backend condition mutex functions */
300
301/* Allocate a condition. */
302static inline int
303__gthread_objc_condition_allocate(objc_condition_t condition)
304{
305 if (__gthread_active_p ())
306 {
307 condition->backend = objc_malloc(sizeof(pthread_cond_t));
308
309 if (pthread_cond_init((pthread_cond_t *)condition->backend, NULL))
310 {
311 objc_free(condition->backend);
312 condition->backend = NULL;
313 return -1;
314 }
315 }
316
317 return 0;
318}
319
320/* Deallocate a condition. */
321static inline int
322__gthread_objc_condition_deallocate(objc_condition_t condition)
323{
324 if (__gthread_active_p ())
325 {
326 if (pthread_cond_destroy((pthread_cond_t *)condition->backend))
327 return -1;
328
329 objc_free(condition->backend);
330 condition->backend = NULL;
331 }
332 return 0;
333}
334
335/* Wait on the condition */
336static inline int
337__gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
338{
339 if (__gthread_active_p ())
340 return pthread_cond_wait((pthread_cond_t *)condition->backend,
341 (pthread_mutex_t *)mutex->backend);
342 else
343 return 0;
344}
345
346/* Wake up all threads waiting on this condition. */
347static inline int
348__gthread_objc_condition_broadcast(objc_condition_t condition)
349{
350 if (__gthread_active_p ())
351 return pthread_cond_broadcast((pthread_cond_t *)condition->backend);
352 else
353 return 0;
354}
355
356/* Wake up one thread waiting on this condition. */
357static inline int
358__gthread_objc_condition_signal(objc_condition_t condition)
359{
360 if (__gthread_active_p ())
361 return pthread_cond_signal((pthread_cond_t *)condition->backend);
362 else
363 return 0;
364}
365
366#else /* _LIBOBJC */
367
f24af81b 368static inline int
d1e51320 369__gthread_once (__gthread_once_t *once, void (*func) (void))
f24af81b
TT
370{
371 if (__gthread_active_p ())
372 return pthread_once (once, func);
373 else
374 return -1;
375}
376
377static inline int
378__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
379{
380 return pthread_key_create (key, dtor);
381}
382
383static inline int
384__gthread_key_dtor (__gthread_key_t key, void *ptr)
385{
386 /* Just reset the key value to zero. */
387 if (ptr)
388 return pthread_setspecific (key, 0);
389 else
390 return 0;
391}
392
393static inline int
394__gthread_key_delete (__gthread_key_t key)
395{
396 return pthread_key_delete (key);
397}
398
399static inline void *
400__gthread_getspecific (__gthread_key_t key)
401{
402 return pthread_getspecific (key);
403}
404
405static inline int
406__gthread_setspecific (__gthread_key_t key, const void *ptr)
407{
408 return pthread_setspecific (key, ptr);
409}
410
411static inline int
412__gthread_mutex_lock (__gthread_mutex_t *mutex)
413{
414 if (__gthread_active_p ())
415 return pthread_mutex_lock (mutex);
416 else
417 return 0;
418}
419
420static inline int
421__gthread_mutex_trylock (__gthread_mutex_t *mutex)
422{
423 if (__gthread_active_p ())
424 return pthread_mutex_trylock (mutex);
425 else
426 return 0;
427}
428
429static inline int
430__gthread_mutex_unlock (__gthread_mutex_t *mutex)
431{
432 if (__gthread_active_p ())
433 return pthread_mutex_unlock (mutex);
434 else
435 return 0;
436}
437
15794a95
L
438#endif /* _LIBOBJC */
439
f24af81b 440#endif /* not __gthr_posix_h */
This page took 0.85423 seconds and 5 git commands to generate.