]> gcc.gnu.org Git - gcc.git/blob - gcc/gthr-dce.h
c-pragma.h: Define HANDLE_GENERIC_PRAGMAS if REGISTER_TARGET_PRAGMAS is defined.
[gcc.git] / gcc / gthr-dce.h
1
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
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)
10 any later version.
11
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.
16
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. */
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_dce_h
30 #define __gthr_dce_h
31
32 /* DCE threads interface.
33 DCE threads are based on POSIX threads draft 4, and many things
34 have changed since then. */
35
36 #define __GTHREADS 1
37
38 #include <pthread.h>
39
40 typedef pthread_key_t __gthread_key_t;
41 typedef pthread_once_t __gthread_once_t;
42 typedef pthread_mutex_t __gthread_mutex_t;
43
44 #define __GTHREAD_ONCE_INIT pthread_once_init
45 /* Howto define __GTHREAD_MUTEX_INIT? */
46
47 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
48
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
56
57 #pragma weak pthread_mutex_lock
58 #pragma weak pthread_mutex_trylock
59 #pragma weak pthread_mutex_unlock
60
61 #ifdef _LIBOBJC
62 /* Objective C. */
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
74 #endif
75
76 static void *__gthread_active_ptr = &pthread_create;
77
78 static inline int
79 __gthread_active_p (void)
80 {
81 return __gthread_active_ptr != 0;
82 }
83
84 #else /* not SUPPORTS_WEAK */
85
86 static inline int
87 __gthread_active_p (void)
88 {
89 return 1;
90 }
91
92 #endif /* SUPPORTS_WEAK */
93
94 #ifdef _LIBOBJC
95
96 /* Key structure for maintaining thread specific storage */
97 static pthread_key_t _objc_thread_storage;
98
99 /* Thread local storage for a single thread */
100 static void *thread_local_storage = NULL;
101
102 /* Backend initialization functions */
103
104 /* Initialize the threads subsystem. */
105 static inline int
106 __gthread_objc_init_thread_system(void)
107 {
108 if (__gthread_active_p ())
109 /* Initialize the thread storage key */
110 return pthread_keycreate (&_objc_thread_storage, NULL);
111 else
112 return -1;
113 }
114
115 /* Close the threads subsystem. */
116 static inline int
117 __gthread_objc_close_thread_system(void)
118 {
119 if (__gthread_active_p ())
120 return 0;
121 else
122 return -1;
123 }
124
125 /* Backend thread functions */
126
127 /* Create a new thread of execution. */
128 static inline objc_thread_t
129 __gthread_objc_thread_detach(void (*func)(void *), void *arg)
130 {
131 objc_thread_t thread_id;
132 pthread_t new_thread_handle;
133
134 if (!__gthread_active_p ())
135 return NULL;
136
137 if ( !(pthread_create(&new_thread_handle, pthread_attr_default,
138 (void *)func, arg)) )
139 {
140 /* ??? May not work! (64bit) */
141 thread_id = *(objc_thread_t *)&new_thread_handle;
142 pthread_detach(&new_thread_handle); /* Fully detach thread. */
143 }
144 else
145 thread_id = NULL;
146
147 return thread_id;
148 }
149
150 /* Set the current thread's priority. */
151 static inline int
152 __gthread_objc_thread_set_priority(int priority)
153 {
154 int sys_priority = 0;
155
156 if (!__gthread_active_p ())
157 return -1;
158
159 switch (priority)
160 {
161 case OBJC_THREAD_INTERACTIVE_PRIORITY:
162 sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
163 break;
164 default:
165 case OBJC_THREAD_BACKGROUND_PRIORITY:
166 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
167 break;
168 case OBJC_THREAD_LOW_PRIORITY:
169 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
170 break;
171 }
172
173 /* Change the priority. */
174 if (pthread_setprio(pthread_self(), sys_priority) >= 0)
175 return 0;
176 else
177 /* Failed */
178 return -1;
179 }
180
181 /* Return the current thread's priority. */
182 static inline int
183 __gthread_objc_thread_get_priority(void)
184 {
185 int sys_priority;
186
187 if (__gthread_active_p ())
188 {
189 if ((sys_priority = pthread_getprio(pthread_self())) >= 0)
190 {
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;
198 }
199
200 /* Failed */
201 return -1;
202 }
203 else
204 return OBJC_THREAD_INTERACTIVE_PRIORITY;
205 }
206
207 /* Yield our process time to another thread. */
208 static inline void
209 __gthread_objc_thread_yield(void)
210 {
211 if (__gthread_active_p ())
212 pthread_yield();
213 }
214
215 /* Terminate the current thread. */
216 static inline int
217 __gthread_objc_thread_exit(void)
218 {
219 if (__gthread_active_p ())
220 /* exit the thread */
221 pthread_exit(&__objc_thread_exit_status);
222
223 /* Failed if we reached here */
224 return -1;
225 }
226
227 /* Returns an integer value which uniquely describes a thread. */
228 static inline objc_thread_t
229 __gthread_objc_thread_id(void)
230 {
231 if (__gthread_active_p ())
232 {
233 pthread_t self = pthread_self();
234
235 return (objc_thread_t) pthread_getunique_np (&self);
236 }
237 else
238 return (objc_thread_t)1;
239 }
240
241 /* Sets the thread's local storage pointer. */
242 static inline int
243 __gthread_objc_thread_set_data(void *value)
244 {
245 if (__gthread_active_p ())
246 return pthread_setspecific(_objc_thread_storage, value);
247 else
248 {
249 thread_local_storage = value;
250 return 0;
251 }
252 }
253
254 /* Returns the thread's local storage pointer. */
255 static inline void *
256 __gthread_objc_thread_get_data(void)
257 {
258 void *value = NULL;
259
260 if (__gthread_active_p ())
261 {
262 if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
263 return value;
264
265 return NULL;
266 }
267 else
268 return thread_local_storage;
269 }
270
271 /* Backend mutex functions */
272
273 /* Allocate a mutex. */
274 static inline int
275 __gthread_objc_mutex_allocate(objc_mutex_t mutex)
276 {
277 if (__gthread_active_p ())
278 {
279 mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
280
281 if (pthread_mutex_init((pthread_mutex_t *)mutex->backend,
282 pthread_mutexattr_default))
283 {
284 objc_free(mutex->backend);
285 mutex->backend = NULL;
286 return -1;
287 }
288 }
289
290 return 0;
291 }
292
293 /* Deallocate a mutex. */
294 static inline int
295 __gthread_objc_mutex_deallocate(objc_mutex_t mutex)
296 {
297 if (__gthread_active_p ())
298 {
299 if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
300 return -1;
301
302 objc_free(mutex->backend);
303 mutex->backend = NULL;
304 }
305
306 return 0;
307 }
308
309 /* Grab a lock on a mutex. */
310 static inline int
311 __gthread_objc_mutex_lock(objc_mutex_t mutex)
312 {
313 if (__gthread_active_p ())
314 return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
315 else
316 return 0;
317 }
318
319 /* Try to grab a lock on a mutex. */
320 static inline int
321 __gthread_objc_mutex_trylock(objc_mutex_t mutex)
322 {
323 if (__gthread_active_p ()
324 && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 1)
325 return -1;
326
327 return 0;
328 }
329
330 /* Unlock the mutex */
331 static inline int
332 __gthread_objc_mutex_unlock(objc_mutex_t mutex)
333 {
334 if (__gthread_active_p ())
335 return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
336 else
337 return 0;
338 }
339
340 /* Backend condition mutex functions */
341
342 /* Allocate a condition. */
343 static inline int
344 __gthread_objc_condition_allocate(objc_condition_t condition)
345 {
346 if (__gthread_active_p ())
347 /* Unimplemented. */
348 return -1;
349 else
350 return 0;
351 }
352
353 /* Deallocate a condition. */
354 static inline int
355 __gthread_objc_condition_deallocate(objc_condition_t condition)
356 {
357 if (__gthread_active_p ())
358 /* Unimplemented. */
359 return -1;
360 else
361 return 0;
362 }
363
364 /* Wait on the condition */
365 static inline int
366 __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
367 {
368 if (__gthread_active_p ())
369 /* Unimplemented. */
370 return -1;
371 else
372 return 0;
373 }
374
375 /* Wake up all threads waiting on this condition. */
376 static inline int
377 __gthread_objc_condition_broadcast(objc_condition_t condition)
378 {
379 if (__gthread_active_p ())
380 /* Unimplemented. */
381 return -1;
382 else
383 return 0;
384 }
385
386 /* Wake up one thread waiting on this condition. */
387 static inline int
388 __gthread_objc_condition_signal(objc_condition_t condition)
389 {
390 if (__gthread_active_p ())
391 /* Unimplemented. */
392 return -1;
393 else
394 return 0;
395 }
396
397 #else /* _LIBOBJC */
398
399 static inline int
400 __gthread_once (__gthread_once_t *once, void (*func) (void))
401 {
402 if (__gthread_active_p ())
403 return pthread_once (once, func);
404 else
405 return -1;
406 }
407
408 static inline int
409 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
410 {
411 return pthread_keycreate (key, dtor);
412 }
413
414 static inline int
415 __gthread_key_dtor (__gthread_key_t key, void *ptr)
416 {
417 /* Nothing needed. */
418 return 0;
419 }
420
421 static inline int
422 __gthread_key_delete (__gthread_key_t key)
423 {
424 return pthread_key_delete (key);
425 }
426
427 static inline void *
428 __gthread_getspecific (__gthread_key_t key)
429 {
430 void *ptr;
431 if (pthread_getspecific (key, &ptr) == 0)
432 return ptr;
433 else
434 return 0;
435 }
436
437 static inline int
438 __gthread_setspecific (__gthread_key_t key, const void *ptr)
439 {
440 return pthread_setspecific (key, (void *) ptr);
441 }
442
443 static inline int
444 __gthread_mutex_lock (__gthread_mutex_t *mutex)
445 {
446 if (__gthread_active_p ())
447 return pthread_mutex_lock (mutex);
448 else
449 return 0;
450 }
451
452 static inline int
453 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
454 {
455 if (__gthread_active_p ())
456 return pthread_mutex_trylock (mutex);
457 else
458 return 0;
459 }
460
461 static inline int
462 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
463 {
464 if (__gthread_active_p ())
465 return pthread_mutex_unlock (mutex);
466 else
467 return 0;
468 }
469
470 #endif /* _LIBOBJC */
471
472 #endif /* not __gthr_dce_h */
This page took 0.056831 seconds and 5 git commands to generate.