Mercurial > hg > CbC > CbC_gcc
annotate gcc/gthr-posix.h @ 89:3356a4c26abc
modify comment out :c-parser.c
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 20 Dec 2011 19:03:56 +0900 |
parents | f6334be47118 |
children |
rev | line source |
---|---|
0 | 1 /* Threads compatibility routines for libgcc2 and libobjc. */ |
2 /* Compile this one with gcc. */ | |
3 /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
4 2008, 2009, 2010 Free Software Foundation, Inc. |
0 | 5 |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 Under Section 7 of GPL version 3, you are granted additional | |
19 permissions described in the GCC Runtime Library Exception, version | |
20 3.1, as published by the Free Software Foundation. | |
21 | |
22 You should have received a copy of the GNU General Public License and | |
23 a copy of the GCC Runtime Library Exception along with this program; | |
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
25 <http://www.gnu.org/licenses/>. */ | |
26 | |
27 #ifndef GCC_GTHR_POSIX_H | |
28 #define GCC_GTHR_POSIX_H | |
29 | |
30 /* POSIX threads specific definitions. | |
31 Easy, since the interface is just one-to-one mapping. */ | |
32 | |
33 #define __GTHREADS 1 | |
34 #define __GTHREADS_CXX0X 1 | |
35 | |
36 /* Some implementations of <pthread.h> require this to be defined. */ | |
37 #if !defined(_REENTRANT) && defined(__osf__) | |
38 #define _REENTRANT 1 | |
39 #endif | |
40 | |
41 #include <pthread.h> | |
42 #include <unistd.h> | |
43 | |
44 typedef pthread_t __gthread_t; | |
45 typedef pthread_key_t __gthread_key_t; | |
46 typedef pthread_once_t __gthread_once_t; | |
47 typedef pthread_mutex_t __gthread_mutex_t; | |
48 typedef pthread_mutex_t __gthread_recursive_mutex_t; | |
49 typedef pthread_cond_t __gthread_cond_t; | |
50 typedef struct timespec __gthread_time_t; | |
51 | |
52 /* POSIX like conditional variables are supported. Please look at comments | |
53 in gthr.h for details. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
54 #define __GTHREAD_HAS_COND 1 |
0 | 55 |
56 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER | |
57 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT | |
58 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) | |
59 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER | |
60 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) | |
61 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP | |
62 #else | |
63 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function | |
64 #endif | |
65 #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER | |
66 #define __GTHREAD_TIME_INIT {0,0} | |
67 | |
68 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK | |
69 # ifndef __gthrw_pragma | |
70 # define __gthrw_pragma(pragma) | |
71 # endif | |
72 # define __gthrw2(name,name2,type) \ | |
73 static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ | |
74 __gthrw_pragma(weak type) | |
75 # define __gthrw_(name) __gthrw_ ## name | |
76 #else | |
77 # define __gthrw2(name,name2,type) | |
78 # define __gthrw_(name) name | |
79 #endif | |
80 | |
81 /* Typically, __gthrw_foo is a weak reference to symbol foo. */ | |
82 #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) | |
83 | |
84 /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to | |
85 map a subset of the POSIX pthread API to mangled versions of their | |
86 names. */ | |
87 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) | |
88 #define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name) | |
89 __gthrw3(pthread_once) | |
90 __gthrw3(pthread_getspecific) | |
91 __gthrw3(pthread_setspecific) | |
92 | |
93 __gthrw3(pthread_create) | |
94 __gthrw3(pthread_join) | |
95 __gthrw3(pthread_detach) | |
96 __gthrw3(pthread_equal) | |
97 __gthrw3(pthread_self) | |
98 __gthrw3(pthread_cancel) | |
99 __gthrw3(sched_yield) | |
100 | |
101 __gthrw3(pthread_mutex_lock) | |
102 __gthrw3(pthread_mutex_trylock) | |
103 #ifdef _POSIX_TIMEOUTS | |
104 #if _POSIX_TIMEOUTS >= 0 | |
105 __gthrw3(pthread_mutex_timedlock) | |
106 #endif | |
107 #endif /* _POSIX_TIMEOUTS */ | |
108 __gthrw3(pthread_mutex_unlock) | |
109 __gthrw3(pthread_mutex_init) | |
110 __gthrw3(pthread_mutex_destroy) | |
111 | |
112 __gthrw3(pthread_cond_broadcast) | |
113 __gthrw3(pthread_cond_signal) | |
114 __gthrw3(pthread_cond_wait) | |
115 __gthrw3(pthread_cond_timedwait) | |
116 __gthrw3(pthread_cond_destroy) | |
117 #else | |
118 __gthrw(pthread_once) | |
119 __gthrw(pthread_getspecific) | |
120 __gthrw(pthread_setspecific) | |
121 | |
122 __gthrw(pthread_create) | |
123 __gthrw(pthread_join) | |
124 __gthrw(pthread_equal) | |
125 __gthrw(pthread_self) | |
126 __gthrw(pthread_detach) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
127 #ifndef __BIONIC__ |
0 | 128 __gthrw(pthread_cancel) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
129 #endif |
0 | 130 __gthrw(sched_yield) |
131 | |
132 __gthrw(pthread_mutex_lock) | |
133 __gthrw(pthread_mutex_trylock) | |
134 #ifdef _POSIX_TIMEOUTS | |
135 #if _POSIX_TIMEOUTS >= 0 | |
136 __gthrw(pthread_mutex_timedlock) | |
137 #endif | |
138 #endif /* _POSIX_TIMEOUTS */ | |
139 __gthrw(pthread_mutex_unlock) | |
140 __gthrw(pthread_mutex_init) | |
141 __gthrw(pthread_mutex_destroy) | |
142 | |
143 __gthrw(pthread_cond_broadcast) | |
144 __gthrw(pthread_cond_signal) | |
145 __gthrw(pthread_cond_wait) | |
146 __gthrw(pthread_cond_timedwait) | |
147 __gthrw(pthread_cond_destroy) | |
148 #endif | |
149 | |
150 __gthrw(pthread_key_create) | |
151 __gthrw(pthread_key_delete) | |
152 __gthrw(pthread_mutexattr_init) | |
153 __gthrw(pthread_mutexattr_settype) | |
154 __gthrw(pthread_mutexattr_destroy) | |
155 | |
156 | |
157 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) | |
158 /* Objective-C. */ | |
159 #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_) | |
160 __gthrw3(pthread_cond_init) | |
161 __gthrw3(pthread_exit) | |
162 #else | |
163 __gthrw(pthread_cond_init) | |
164 __gthrw(pthread_exit) | |
165 #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */ | |
166 #ifdef _POSIX_PRIORITY_SCHEDULING | |
167 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING | |
168 __gthrw(sched_get_priority_max) | |
169 __gthrw(sched_get_priority_min) | |
170 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ | |
171 #endif /* _POSIX_PRIORITY_SCHEDULING */ | |
172 __gthrw(pthread_attr_destroy) | |
173 __gthrw(pthread_attr_init) | |
174 __gthrw(pthread_attr_setdetachstate) | |
175 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING | |
176 __gthrw(pthread_getschedparam) | |
177 __gthrw(pthread_setschedparam) | |
178 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ | |
179 #endif /* _LIBOBJC || _LIBOBJC_WEAK */ | |
180 | |
181 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK | |
182 | |
183 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if | |
184 -pthreads is not specified. The functions are dummies and most return an | |
185 error value. However pthread_once returns 0 without invoking the routine | |
186 it is passed so we cannot pretend that the interface is active if -pthreads | |
187 is not specified. On Solaris 2.5.1, the interface is not exposed at all so | |
188 we need to play the usual game with weak symbols. On Solaris 10 and up, a | |
189 working interface is always exposed. On FreeBSD 6 and later, libc also | |
190 exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up | |
191 to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, | |
192 which means the alternate __gthread_active_p below cannot be used there. */ | |
193 | |
194 #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) | |
195 | |
196 static volatile int __gthread_active = -1; | |
197 | |
198 static void | |
199 __gthread_trigger (void) | |
200 { | |
201 __gthread_active = 1; | |
202 } | |
203 | |
204 static inline int | |
205 __gthread_active_p (void) | |
206 { | |
207 static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; | |
208 static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; | |
209 | |
210 /* Avoid reading __gthread_active twice on the main code path. */ | |
211 int __gthread_active_latest_value = __gthread_active; | |
212 | |
213 /* This test is not protected to avoid taking a lock on the main code | |
214 path so every update of __gthread_active in a threaded program must | |
215 be atomic with regard to the result of the test. */ | |
216 if (__builtin_expect (__gthread_active_latest_value < 0, 0)) | |
217 { | |
218 if (__gthrw_(pthread_once)) | |
219 { | |
220 /* If this really is a threaded program, then we must ensure that | |
221 __gthread_active has been set to 1 before exiting this block. */ | |
222 __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); | |
223 __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); | |
224 __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); | |
225 } | |
226 | |
227 /* Make sure we'll never enter this block again. */ | |
228 if (__gthread_active < 0) | |
229 __gthread_active = 0; | |
230 | |
231 __gthread_active_latest_value = __gthread_active; | |
232 } | |
233 | |
234 return __gthread_active_latest_value != 0; | |
235 } | |
236 | |
237 #else /* neither FreeBSD nor Solaris */ | |
238 | |
239 static inline int | |
240 __gthread_active_p (void) | |
241 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
242 static void *const __gthread_active_ptr |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
243 = __extension__ (void *) &__gthrw_( |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
244 /* Android's C library does not provide pthread_cancel, check for |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
245 `pthread_create' instead. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
246 #ifndef __BIONIC__ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
247 pthread_cancel |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
248 #else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
249 pthread_create |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
250 #endif |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
251 ); |
0 | 252 return __gthread_active_ptr != 0; |
253 } | |
254 | |
255 #endif /* FreeBSD or Solaris */ | |
256 | |
257 #else /* not SUPPORTS_WEAK */ | |
258 | |
259 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread | |
260 calls in shared flavors of the HP-UX C library. Most of the stubs | |
261 have no functionality. The details are described in the "libc cumulative | |
262 patch" for each subversion of HP-UX 11. There are two special interfaces | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
263 provided for checking whether an application is linked to a shared pthread |
0 | 264 library or not. However, these interfaces aren't available in early |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
265 libpthread libraries. We also need a test that works for archive |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
266 libraries. We can't use pthread_once as some libc versions call the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
267 init function. We also can't use pthread_create or pthread_attr_init |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
268 as these create a thread and thereby prevent changing the default stack |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
269 size. The function pthread_default_stacksize_np is available in both |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
270 the archive and shared versions of libpthread. It can be used to |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
271 determine the default pthread stack size. There is a stub in some |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
272 shared libc versions which returns a zero size if pthreads are not |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
273 active. We provide an equivalent stub to handle cases where libc |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
274 doesn't provide one. */ |
0 | 275 |
276 #if defined(__hppa__) && defined(__hpux__) | |
277 | |
278 static volatile int __gthread_active = -1; | |
279 | |
280 static inline int | |
281 __gthread_active_p (void) | |
282 { | |
283 /* Avoid reading __gthread_active twice on the main code path. */ | |
284 int __gthread_active_latest_value = __gthread_active; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
285 size_t __s; |
0 | 286 |
287 if (__builtin_expect (__gthread_active_latest_value < 0, 0)) | |
288 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
289 pthread_default_stacksize_np (0, &__s); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
290 __gthread_active = __s ? 1 : 0; |
0 | 291 __gthread_active_latest_value = __gthread_active; |
292 } | |
293 | |
294 return __gthread_active_latest_value != 0; | |
295 } | |
296 | |
297 #else /* not hppa-hpux */ | |
298 | |
299 static inline int | |
300 __gthread_active_p (void) | |
301 { | |
302 return 1; | |
303 } | |
304 | |
305 #endif /* hppa-hpux */ | |
306 | |
307 #endif /* SUPPORTS_WEAK */ | |
308 | |
309 #ifdef _LIBOBJC | |
310 | |
311 /* This is the config.h file in libobjc/ */ | |
312 #include <config.h> | |
313 | |
314 #ifdef HAVE_SCHED_H | |
315 # include <sched.h> | |
316 #endif | |
317 | |
318 /* Key structure for maintaining thread specific storage */ | |
319 static pthread_key_t _objc_thread_storage; | |
320 static pthread_attr_t _objc_thread_attribs; | |
321 | |
322 /* Thread local storage for a single thread */ | |
323 static void *thread_local_storage = NULL; | |
324 | |
325 /* Backend initialization functions */ | |
326 | |
327 /* Initialize the threads subsystem. */ | |
328 static inline int | |
329 __gthread_objc_init_thread_system (void) | |
330 { | |
331 if (__gthread_active_p ()) | |
332 { | |
333 /* Initialize the thread storage key. */ | |
334 if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) | |
335 { | |
336 /* The normal default detach state for threads is | |
337 * PTHREAD_CREATE_JOINABLE which causes threads to not die | |
338 * when you think they should. */ | |
339 if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 | |
340 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, | |
341 PTHREAD_CREATE_DETACHED) == 0) | |
342 return 0; | |
343 } | |
344 } | |
345 | |
346 return -1; | |
347 } | |
348 | |
349 /* Close the threads subsystem. */ | |
350 static inline int | |
351 __gthread_objc_close_thread_system (void) | |
352 { | |
353 if (__gthread_active_p () | |
354 && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 | |
355 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) | |
356 return 0; | |
357 | |
358 return -1; | |
359 } | |
360 | |
361 /* Backend thread functions */ | |
362 | |
363 /* Create a new thread of execution. */ | |
364 static inline objc_thread_t | |
365 __gthread_objc_thread_detach (void (*func)(void *), void *arg) | |
366 { | |
367 objc_thread_t thread_id; | |
368 pthread_t new_thread_handle; | |
369 | |
370 if (!__gthread_active_p ()) | |
371 return NULL; | |
372 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
373 if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
374 (void *) func, arg))) |
0 | 375 thread_id = (objc_thread_t) new_thread_handle; |
376 else | |
377 thread_id = NULL; | |
378 | |
379 return thread_id; | |
380 } | |
381 | |
382 /* Set the current thread's priority. */ | |
383 static inline int | |
384 __gthread_objc_thread_set_priority (int priority) | |
385 { | |
386 if (!__gthread_active_p ()) | |
387 return -1; | |
388 else | |
389 { | |
390 #ifdef _POSIX_PRIORITY_SCHEDULING | |
391 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING | |
392 pthread_t thread_id = __gthrw_(pthread_self) (); | |
393 int policy; | |
394 struct sched_param params; | |
395 int priority_min, priority_max; | |
396 | |
397 if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) | |
398 { | |
399 if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) | |
400 return -1; | |
401 | |
402 if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) | |
403 return -1; | |
404 | |
405 if (priority > priority_max) | |
406 priority = priority_max; | |
407 else if (priority < priority_min) | |
408 priority = priority_min; | |
409 params.sched_priority = priority; | |
410 | |
411 /* | |
412 * The solaris 7 and several other man pages incorrectly state that | |
413 * this should be a pointer to policy but pthread.h is universally | |
414 * at odds with this. | |
415 */ | |
416 if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) | |
417 return 0; | |
418 } | |
419 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ | |
420 #endif /* _POSIX_PRIORITY_SCHEDULING */ | |
421 return -1; | |
422 } | |
423 } | |
424 | |
425 /* Return the current thread's priority. */ | |
426 static inline int | |
427 __gthread_objc_thread_get_priority (void) | |
428 { | |
429 #ifdef _POSIX_PRIORITY_SCHEDULING | |
430 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING | |
431 if (__gthread_active_p ()) | |
432 { | |
433 int policy; | |
434 struct sched_param params; | |
435 | |
436 if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) | |
437 return params.sched_priority; | |
438 else | |
439 return -1; | |
440 } | |
441 else | |
442 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ | |
443 #endif /* _POSIX_PRIORITY_SCHEDULING */ | |
444 return OBJC_THREAD_INTERACTIVE_PRIORITY; | |
445 } | |
446 | |
447 /* Yield our process time to another thread. */ | |
448 static inline void | |
449 __gthread_objc_thread_yield (void) | |
450 { | |
451 if (__gthread_active_p ()) | |
452 __gthrw_(sched_yield) (); | |
453 } | |
454 | |
455 /* Terminate the current thread. */ | |
456 static inline int | |
457 __gthread_objc_thread_exit (void) | |
458 { | |
459 if (__gthread_active_p ()) | |
460 /* exit the thread */ | |
461 __gthrw_(pthread_exit) (&__objc_thread_exit_status); | |
462 | |
463 /* Failed if we reached here */ | |
464 return -1; | |
465 } | |
466 | |
467 /* Returns an integer value which uniquely describes a thread. */ | |
468 static inline objc_thread_t | |
469 __gthread_objc_thread_id (void) | |
470 { | |
471 if (__gthread_active_p ()) | |
472 return (objc_thread_t) __gthrw_(pthread_self) (); | |
473 else | |
474 return (objc_thread_t) 1; | |
475 } | |
476 | |
477 /* Sets the thread's local storage pointer. */ | |
478 static inline int | |
479 __gthread_objc_thread_set_data (void *value) | |
480 { | |
481 if (__gthread_active_p ()) | |
482 return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); | |
483 else | |
484 { | |
485 thread_local_storage = value; | |
486 return 0; | |
487 } | |
488 } | |
489 | |
490 /* Returns the thread's local storage pointer. */ | |
491 static inline void * | |
492 __gthread_objc_thread_get_data (void) | |
493 { | |
494 if (__gthread_active_p ()) | |
495 return __gthrw_(pthread_getspecific) (_objc_thread_storage); | |
496 else | |
497 return thread_local_storage; | |
498 } | |
499 | |
500 /* Backend mutex functions */ | |
501 | |
502 /* Allocate a mutex. */ | |
503 static inline int | |
504 __gthread_objc_mutex_allocate (objc_mutex_t mutex) | |
505 { | |
506 if (__gthread_active_p ()) | |
507 { | |
508 mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); | |
509 | |
510 if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) | |
511 { | |
512 objc_free (mutex->backend); | |
513 mutex->backend = NULL; | |
514 return -1; | |
515 } | |
516 } | |
517 | |
518 return 0; | |
519 } | |
520 | |
521 /* Deallocate a mutex. */ | |
522 static inline int | |
523 __gthread_objc_mutex_deallocate (objc_mutex_t mutex) | |
524 { | |
525 if (__gthread_active_p ()) | |
526 { | |
527 int count; | |
528 | |
529 /* | |
530 * Posix Threads specifically require that the thread be unlocked | |
531 * for __gthrw_(pthread_mutex_destroy) to work. | |
532 */ | |
533 | |
534 do | |
535 { | |
536 count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); | |
537 if (count < 0) | |
538 return -1; | |
539 } | |
540 while (count); | |
541 | |
542 if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) | |
543 return -1; | |
544 | |
545 objc_free (mutex->backend); | |
546 mutex->backend = NULL; | |
547 } | |
548 return 0; | |
549 } | |
550 | |
551 /* Grab a lock on a mutex. */ | |
552 static inline int | |
553 __gthread_objc_mutex_lock (objc_mutex_t mutex) | |
554 { | |
555 if (__gthread_active_p () | |
556 && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) | |
557 { | |
558 return -1; | |
559 } | |
560 | |
561 return 0; | |
562 } | |
563 | |
564 /* Try to grab a lock on a mutex. */ | |
565 static inline int | |
566 __gthread_objc_mutex_trylock (objc_mutex_t mutex) | |
567 { | |
568 if (__gthread_active_p () | |
569 && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) | |
570 { | |
571 return -1; | |
572 } | |
573 | |
574 return 0; | |
575 } | |
576 | |
577 /* Unlock the mutex */ | |
578 static inline int | |
579 __gthread_objc_mutex_unlock (objc_mutex_t mutex) | |
580 { | |
581 if (__gthread_active_p () | |
582 && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) | |
583 { | |
584 return -1; | |
585 } | |
586 | |
587 return 0; | |
588 } | |
589 | |
590 /* Backend condition mutex functions */ | |
591 | |
592 /* Allocate a condition. */ | |
593 static inline int | |
594 __gthread_objc_condition_allocate (objc_condition_t condition) | |
595 { | |
596 if (__gthread_active_p ()) | |
597 { | |
598 condition->backend = objc_malloc (sizeof (pthread_cond_t)); | |
599 | |
600 if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) | |
601 { | |
602 objc_free (condition->backend); | |
603 condition->backend = NULL; | |
604 return -1; | |
605 } | |
606 } | |
607 | |
608 return 0; | |
609 } | |
610 | |
611 /* Deallocate a condition. */ | |
612 static inline int | |
613 __gthread_objc_condition_deallocate (objc_condition_t condition) | |
614 { | |
615 if (__gthread_active_p ()) | |
616 { | |
617 if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) | |
618 return -1; | |
619 | |
620 objc_free (condition->backend); | |
621 condition->backend = NULL; | |
622 } | |
623 return 0; | |
624 } | |
625 | |
626 /* Wait on the condition */ | |
627 static inline int | |
628 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) | |
629 { | |
630 if (__gthread_active_p ()) | |
631 return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, | |
632 (pthread_mutex_t *) mutex->backend); | |
633 else | |
634 return 0; | |
635 } | |
636 | |
637 /* Wake up all threads waiting on this condition. */ | |
638 static inline int | |
639 __gthread_objc_condition_broadcast (objc_condition_t condition) | |
640 { | |
641 if (__gthread_active_p ()) | |
642 return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); | |
643 else | |
644 return 0; | |
645 } | |
646 | |
647 /* Wake up one thread waiting on this condition. */ | |
648 static inline int | |
649 __gthread_objc_condition_signal (objc_condition_t condition) | |
650 { | |
651 if (__gthread_active_p ()) | |
652 return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); | |
653 else | |
654 return 0; | |
655 } | |
656 | |
657 #else /* _LIBOBJC */ | |
658 | |
659 static inline int | |
660 __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), | |
661 void *__args) | |
662 { | |
663 return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); | |
664 } | |
665 | |
666 static inline int | |
667 __gthread_join (__gthread_t __threadid, void **__value_ptr) | |
668 { | |
669 return __gthrw_(pthread_join) (__threadid, __value_ptr); | |
670 } | |
671 | |
672 static inline int | |
673 __gthread_detach (__gthread_t __threadid) | |
674 { | |
675 return __gthrw_(pthread_detach) (__threadid); | |
676 } | |
677 | |
678 static inline int | |
679 __gthread_equal (__gthread_t __t1, __gthread_t __t2) | |
680 { | |
681 return __gthrw_(pthread_equal) (__t1, __t2); | |
682 } | |
683 | |
684 static inline __gthread_t | |
685 __gthread_self (void) | |
686 { | |
687 return __gthrw_(pthread_self) (); | |
688 } | |
689 | |
690 static inline int | |
691 __gthread_yield (void) | |
692 { | |
693 return __gthrw_(sched_yield) (); | |
694 } | |
695 | |
696 static inline int | |
697 __gthread_once (__gthread_once_t *__once, void (*__func) (void)) | |
698 { | |
699 if (__gthread_active_p ()) | |
700 return __gthrw_(pthread_once) (__once, __func); | |
701 else | |
702 return -1; | |
703 } | |
704 | |
705 static inline int | |
706 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) | |
707 { | |
708 return __gthrw_(pthread_key_create) (__key, __dtor); | |
709 } | |
710 | |
711 static inline int | |
712 __gthread_key_delete (__gthread_key_t __key) | |
713 { | |
714 return __gthrw_(pthread_key_delete) (__key); | |
715 } | |
716 | |
717 static inline void * | |
718 __gthread_getspecific (__gthread_key_t __key) | |
719 { | |
720 return __gthrw_(pthread_getspecific) (__key); | |
721 } | |
722 | |
723 static inline int | |
724 __gthread_setspecific (__gthread_key_t __key, const void *__ptr) | |
725 { | |
726 return __gthrw_(pthread_setspecific) (__key, __ptr); | |
727 } | |
728 | |
729 static inline int | |
730 __gthread_mutex_destroy (__gthread_mutex_t *__mutex) | |
731 { | |
732 if (__gthread_active_p ()) | |
733 return __gthrw_(pthread_mutex_destroy) (__mutex); | |
734 else | |
735 return 0; | |
736 } | |
737 | |
738 static inline int | |
739 __gthread_mutex_lock (__gthread_mutex_t *__mutex) | |
740 { | |
741 if (__gthread_active_p ()) | |
742 return __gthrw_(pthread_mutex_lock) (__mutex); | |
743 else | |
744 return 0; | |
745 } | |
746 | |
747 static inline int | |
748 __gthread_mutex_trylock (__gthread_mutex_t *__mutex) | |
749 { | |
750 if (__gthread_active_p ()) | |
751 return __gthrw_(pthread_mutex_trylock) (__mutex); | |
752 else | |
753 return 0; | |
754 } | |
755 | |
756 #ifdef _POSIX_TIMEOUTS | |
757 #if _POSIX_TIMEOUTS >= 0 | |
758 static inline int | |
759 __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, | |
760 const __gthread_time_t *__abs_timeout) | |
761 { | |
762 if (__gthread_active_p ()) | |
763 return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout); | |
764 else | |
765 return 0; | |
766 } | |
767 #endif | |
768 #endif | |
769 | |
770 static inline int | |
771 __gthread_mutex_unlock (__gthread_mutex_t *__mutex) | |
772 { | |
773 if (__gthread_active_p ()) | |
774 return __gthrw_(pthread_mutex_unlock) (__mutex); | |
775 else | |
776 return 0; | |
777 } | |
778 | |
779 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP | |
780 static inline int | |
781 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) | |
782 { | |
783 if (__gthread_active_p ()) | |
784 { | |
785 pthread_mutexattr_t __attr; | |
786 int __r; | |
787 | |
788 __r = __gthrw_(pthread_mutexattr_init) (&__attr); | |
789 if (!__r) | |
790 __r = __gthrw_(pthread_mutexattr_settype) (&__attr, | |
791 PTHREAD_MUTEX_RECURSIVE); | |
792 if (!__r) | |
793 __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr); | |
794 if (!__r) | |
795 __r = __gthrw_(pthread_mutexattr_destroy) (&__attr); | |
796 return __r; | |
797 } | |
798 return 0; | |
799 } | |
800 #endif | |
801 | |
802 static inline int | |
803 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) | |
804 { | |
805 return __gthread_mutex_lock (__mutex); | |
806 } | |
807 | |
808 static inline int | |
809 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) | |
810 { | |
811 return __gthread_mutex_trylock (__mutex); | |
812 } | |
813 | |
814 #ifdef _POSIX_TIMEOUTS | |
815 #if _POSIX_TIMEOUTS >= 0 | |
816 static inline int | |
817 __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, | |
818 const __gthread_time_t *__abs_timeout) | |
819 { | |
820 return __gthread_mutex_timedlock (__mutex, __abs_timeout); | |
821 } | |
822 #endif | |
823 #endif | |
824 | |
825 static inline int | |
826 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) | |
827 { | |
828 return __gthread_mutex_unlock (__mutex); | |
829 } | |
830 | |
831 static inline int | |
832 __gthread_cond_broadcast (__gthread_cond_t *__cond) | |
833 { | |
834 return __gthrw_(pthread_cond_broadcast) (__cond); | |
835 } | |
836 | |
837 static inline int | |
838 __gthread_cond_signal (__gthread_cond_t *__cond) | |
839 { | |
840 return __gthrw_(pthread_cond_signal) (__cond); | |
841 } | |
842 | |
843 static inline int | |
844 __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) | |
845 { | |
846 return __gthrw_(pthread_cond_wait) (__cond, __mutex); | |
847 } | |
848 | |
849 static inline int | |
850 __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, | |
851 const __gthread_time_t *__abs_timeout) | |
852 { | |
853 return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); | |
854 } | |
855 | |
856 static inline int | |
857 __gthread_cond_wait_recursive (__gthread_cond_t *__cond, | |
858 __gthread_recursive_mutex_t *__mutex) | |
859 { | |
860 return __gthread_cond_wait (__cond, __mutex); | |
861 } | |
862 | |
863 static inline int | |
864 __gthread_cond_timedwait_recursive (__gthread_cond_t *__cond, | |
865 __gthread_recursive_mutex_t *__mutex, | |
866 const __gthread_time_t *__abs_timeout) | |
867 { | |
868 return __gthread_cond_timedwait (__cond, __mutex, __abs_timeout); | |
869 } | |
870 | |
871 static inline int | |
872 __gthread_cond_destroy (__gthread_cond_t* __cond) | |
873 { | |
874 return __gthrw_(pthread_cond_destroy) (__cond); | |
875 } | |
876 | |
877 #endif /* _LIBOBJC */ | |
878 | |
879 #endif /* ! GCC_GTHR_POSIX_H */ |