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