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