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