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