00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef GCC_GTHR_POSIX_H
00030 #define GCC_GTHR_POSIX_H
00031
00032
00033
00034
00035 #define __GTHREADS 1
00036
00037
00038 #ifndef _REENTRANT
00039 #define _REENTRANT 1
00040 #endif
00041
00042 #include <pthread.h>
00043 #include <unistd.h>
00044
00045 typedef pthread_key_t __gthread_key_t;
00046 typedef pthread_once_t __gthread_once_t;
00047 typedef pthread_mutex_t __gthread_mutex_t;
00048
00049 typedef struct {
00050 long depth;
00051 pthread_t owner;
00052 pthread_mutex_t actual;
00053 } __gthread_recursive_mutex_t;
00054
00055 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
00056 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
00057 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
00058
00059 #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
00060
00061 #pragma weak pthread_once
00062 #pragma weak pthread_key_create
00063 #pragma weak pthread_key_delete
00064 #pragma weak pthread_getspecific
00065 #pragma weak pthread_setspecific
00066 #pragma weak pthread_create
00067 #pragma weak pthread_cancel
00068 #pragma weak pthread_self
00069
00070 #pragma weak pthread_mutex_lock
00071 #pragma weak pthread_mutex_trylock
00072 #pragma weak pthread_mutex_unlock
00073 #pragma weak pthread_mutexattr_init
00074 #pragma weak pthread_mutexattr_settype
00075 #pragma weak pthread_mutexattr_destroy
00076
00077 #pragma weak pthread_mutex_init
00078
00079 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
00080
00081 #pragma weak pthread_cond_broadcast
00082 #pragma weak pthread_cond_destroy
00083 #pragma weak pthread_cond_init
00084 #pragma weak pthread_cond_signal
00085 #pragma weak pthread_cond_wait
00086 #pragma weak pthread_exit
00087 #pragma weak pthread_mutex_destroy
00088 #pragma weak pthread_self
00089 #ifdef _POSIX_PRIORITY_SCHEDULING
00090 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00091 #pragma weak sched_get_priority_max
00092 #pragma weak sched_get_priority_min
00093 #endif
00094 #endif
00095 #pragma weak sched_yield
00096 #pragma weak pthread_attr_destroy
00097 #pragma weak pthread_attr_init
00098 #pragma weak pthread_attr_setdetachstate
00099 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00100 #pragma weak pthread_getschedparam
00101 #pragma weak pthread_setschedparam
00102 #endif
00103 #endif
00104
00105 static inline int
00106 __gthread_active_p (void)
00107 {
00108 static void *const __gthread_active_ptr
00109 = __extension__ (void *) &pthread_cancel;
00110 return __gthread_active_ptr != 0;
00111 }
00112
00113 #else
00114
00115 static inline int
00116 __gthread_active_p (void)
00117 {
00118 return 1;
00119 }
00120
00121 #endif
00122
00123 #ifdef _LIBOBJC
00124
00125
00126 #include <config.h>
00127
00128 #ifdef HAVE_SCHED_H
00129 # include <sched.h>
00130 #endif
00131
00132
00133 static pthread_key_t _objc_thread_storage;
00134 static pthread_attr_t _objc_thread_attribs;
00135
00136
00137 static void *thread_local_storage = NULL;
00138
00139
00140
00141
00142 static inline int
00143 __gthread_objc_init_thread_system (void)
00144 {
00145 if (__gthread_active_p ())
00146 {
00147
00148 if (pthread_key_create (&_objc_thread_storage, NULL) == 0)
00149 {
00150
00151
00152
00153 if (pthread_attr_init (&_objc_thread_attribs) == 0
00154 && pthread_attr_setdetachstate (&_objc_thread_attribs,
00155 PTHREAD_CREATE_DETACHED) == 0)
00156 return 0;
00157 }
00158 }
00159
00160 return -1;
00161 }
00162
00163
00164 static inline int
00165 __gthread_objc_close_thread_system (void)
00166 {
00167 if (__gthread_active_p ()
00168 && pthread_key_delete (_objc_thread_storage) == 0
00169 && pthread_attr_destroy (&_objc_thread_attribs) == 0)
00170 return 0;
00171
00172 return -1;
00173 }
00174
00175
00176
00177
00178 static inline objc_thread_t
00179 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
00180 {
00181 objc_thread_t thread_id;
00182 pthread_t new_thread_handle;
00183
00184 if (!__gthread_active_p ())
00185 return NULL;
00186
00187 if (!(pthread_create (&new_thread_handle, NULL, (void *) func, arg)))
00188 thread_id = (objc_thread_t) new_thread_handle;
00189 else
00190 thread_id = NULL;
00191
00192 return thread_id;
00193 }
00194
00195
00196 static inline int
00197 __gthread_objc_thread_set_priority (int priority)
00198 {
00199 if (!__gthread_active_p ())
00200 return -1;
00201 else
00202 {
00203 #ifdef _POSIX_PRIORITY_SCHEDULING
00204 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00205 pthread_t thread_id = pthread_self ();
00206 int policy;
00207 struct sched_param params;
00208 int priority_min, priority_max;
00209
00210 if (pthread_getschedparam (thread_id, &policy, ¶ms) == 0)
00211 {
00212 if ((priority_max = sched_get_priority_max (policy)) == -1)
00213 return -1;
00214
00215 if ((priority_min = sched_get_priority_min (policy)) == -1)
00216 return -1;
00217
00218 if (priority > priority_max)
00219 priority = priority_max;
00220 else if (priority < priority_min)
00221 priority = priority_min;
00222 params.sched_priority = priority;
00223
00224
00225
00226
00227
00228
00229 if (pthread_setschedparam (thread_id, policy, ¶ms) == 0)
00230 return 0;
00231 }
00232 #endif
00233 #endif
00234 return -1;
00235 }
00236 }
00237
00238
00239 static inline int
00240 __gthread_objc_thread_get_priority (void)
00241 {
00242 #ifdef _POSIX_PRIORITY_SCHEDULING
00243 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00244 if (__gthread_active_p ())
00245 {
00246 int policy;
00247 struct sched_param params;
00248
00249 if (pthread_getschedparam (pthread_self (), &policy, ¶ms) == 0)
00250 return params.sched_priority;
00251 else
00252 return -1;
00253 }
00254 else
00255 #endif
00256 #endif
00257 return OBJC_THREAD_INTERACTIVE_PRIORITY;
00258 }
00259
00260
00261 static inline void
00262 __gthread_objc_thread_yield (void)
00263 {
00264 if (__gthread_active_p ())
00265 sched_yield ();
00266 }
00267
00268
00269 static inline int
00270 __gthread_objc_thread_exit (void)
00271 {
00272 if (__gthread_active_p ())
00273
00274 pthread_exit (&__objc_thread_exit_status);
00275
00276
00277 return -1;
00278 }
00279
00280
00281 static inline objc_thread_t
00282 __gthread_objc_thread_id (void)
00283 {
00284 if (__gthread_active_p ())
00285 return (objc_thread_t) pthread_self ();
00286 else
00287 return (objc_thread_t) 1;
00288 }
00289
00290
00291 static inline int
00292 __gthread_objc_thread_set_data (void *value)
00293 {
00294 if (__gthread_active_p ())
00295 return pthread_setspecific (_objc_thread_storage, value);
00296 else
00297 {
00298 thread_local_storage = value;
00299 return 0;
00300 }
00301 }
00302
00303
00304 static inline void *
00305 __gthread_objc_thread_get_data (void)
00306 {
00307 if (__gthread_active_p ())
00308 return pthread_getspecific (_objc_thread_storage);
00309 else
00310 return thread_local_storage;
00311 }
00312
00313
00314
00315
00316 static inline int
00317 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00318 {
00319 if (__gthread_active_p ())
00320 {
00321 mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
00322
00323 if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL))
00324 {
00325 objc_free (mutex->backend);
00326 mutex->backend = NULL;
00327 return -1;
00328 }
00329 }
00330
00331 return 0;
00332 }
00333
00334
00335 static inline int
00336 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00337 {
00338 if (__gthread_active_p ())
00339 {
00340 int count;
00341
00342
00343
00344
00345
00346
00347 do
00348 {
00349 count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend);
00350 if (count < 0)
00351 return -1;
00352 }
00353 while (count);
00354
00355 if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend))
00356 return -1;
00357
00358 objc_free (mutex->backend);
00359 mutex->backend = NULL;
00360 }
00361 return 0;
00362 }
00363
00364
00365 static inline int
00366 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00367 {
00368 if (__gthread_active_p ()
00369 && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0)
00370 {
00371 return -1;
00372 }
00373
00374 return 0;
00375 }
00376
00377
00378 static inline int
00379 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00380 {
00381 if (__gthread_active_p ()
00382 && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0)
00383 {
00384 return -1;
00385 }
00386
00387 return 0;
00388 }
00389
00390
00391 static inline int
00392 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00393 {
00394 if (__gthread_active_p ()
00395 && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0)
00396 {
00397 return -1;
00398 }
00399
00400 return 0;
00401 }
00402
00403
00404
00405
00406 static inline int
00407 __gthread_objc_condition_allocate (objc_condition_t condition)
00408 {
00409 if (__gthread_active_p ())
00410 {
00411 condition->backend = objc_malloc (sizeof (pthread_cond_t));
00412
00413 if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL))
00414 {
00415 objc_free (condition->backend);
00416 condition->backend = NULL;
00417 return -1;
00418 }
00419 }
00420
00421 return 0;
00422 }
00423
00424
00425 static inline int
00426 __gthread_objc_condition_deallocate (objc_condition_t condition)
00427 {
00428 if (__gthread_active_p ())
00429 {
00430 if (pthread_cond_destroy ((pthread_cond_t *) condition->backend))
00431 return -1;
00432
00433 objc_free (condition->backend);
00434 condition->backend = NULL;
00435 }
00436 return 0;
00437 }
00438
00439
00440 static inline int
00441 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00442 {
00443 if (__gthread_active_p ())
00444 return pthread_cond_wait ((pthread_cond_t *) condition->backend,
00445 (pthread_mutex_t *) mutex->backend);
00446 else
00447 return 0;
00448 }
00449
00450
00451 static inline int
00452 __gthread_objc_condition_broadcast (objc_condition_t condition)
00453 {
00454 if (__gthread_active_p ())
00455 return pthread_cond_broadcast ((pthread_cond_t *) condition->backend);
00456 else
00457 return 0;
00458 }
00459
00460
00461 static inline int
00462 __gthread_objc_condition_signal (objc_condition_t condition)
00463 {
00464 if (__gthread_active_p ())
00465 return pthread_cond_signal ((pthread_cond_t *) condition->backend);
00466 else
00467 return 0;
00468 }
00469
00470 #else
00471
00472 static inline int
00473 __gthread_once (__gthread_once_t *once, void (*func) (void))
00474 {
00475 if (__gthread_active_p ())
00476 return pthread_once (once, func);
00477 else
00478 return -1;
00479 }
00480
00481 static inline int
00482 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
00483 {
00484 return pthread_key_create (key, dtor);
00485 }
00486
00487 static inline int
00488 __gthread_key_delete (__gthread_key_t key)
00489 {
00490 return pthread_key_delete (key);
00491 }
00492
00493 static inline void *
00494 __gthread_getspecific (__gthread_key_t key)
00495 {
00496 return pthread_getspecific (key);
00497 }
00498
00499 static inline int
00500 __gthread_setspecific (__gthread_key_t key, const void *ptr)
00501 {
00502 return pthread_setspecific (key, ptr);
00503 }
00504
00505 static inline int
00506 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00507 {
00508 if (__gthread_active_p ())
00509 return pthread_mutex_lock (mutex);
00510 else
00511 return 0;
00512 }
00513
00514 static inline int
00515 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00516 {
00517 if (__gthread_active_p ())
00518 return pthread_mutex_trylock (mutex);
00519 else
00520 return 0;
00521 }
00522
00523 static inline int
00524 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00525 {
00526 if (__gthread_active_p ())
00527 return pthread_mutex_unlock (mutex);
00528 else
00529 return 0;
00530 }
00531
00532 static inline int
00533 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
00534 {
00535 mutex->depth = 0;
00536 mutex->owner = (pthread_t) 0;
00537 return pthread_mutex_init (&mutex->actual, NULL);
00538 }
00539
00540 static inline int
00541 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
00542 {
00543 if (__gthread_active_p ())
00544 {
00545 pthread_t me = pthread_self ();
00546
00547 if (mutex->owner != me)
00548 {
00549 pthread_mutex_lock (&mutex->actual);
00550 mutex->owner = me;
00551 }
00552
00553 mutex->depth++;
00554 }
00555 return 0;
00556 }
00557
00558 static inline int
00559 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
00560 {
00561 if (__gthread_active_p ())
00562 {
00563 pthread_t me = pthread_self ();
00564
00565 if (mutex->owner != me)
00566 {
00567 if (pthread_mutex_trylock (&mutex->actual))
00568 return 1;
00569 mutex->owner = me;
00570 }
00571
00572 mutex->depth++;
00573 }
00574 return 0;
00575 }
00576
00577 static inline int
00578 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
00579 {
00580 if (__gthread_active_p ())
00581 {
00582 if (--mutex->depth == 0)
00583 {
00584 mutex->owner = (pthread_t) 0;
00585 pthread_mutex_unlock (&mutex->actual);
00586 }
00587 }
00588 return 0;
00589 }
00590
00591 #endif
00592
00593 #endif