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