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