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