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
00078
00079
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00080
#pragma weak sched_get_priority_max
00081
#pragma weak sched_get_priority_min
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_THREAD_PRIORITY_SCHEDULING
00191
pthread_t thread_id = pthread_self ();
00192
int policy;
00193
struct sched_param params;
00194
int priority_min, priority_max;
00195
00196
if (pthread_getschedparam (thread_id, &policy, ¶ms) == 0)
00197 {
00198
if ((priority_max = sched_get_priority_max (policy)) == -1)
00199
return -1;
00200
00201
if ((priority_min = sched_get_priority_min (policy)) == -1)
00202
return -1;
00203
00204
if (priority > priority_max)
00205 priority = priority_max;
00206
else if (priority < priority_min)
00207 priority = priority_min;
00208 params.sched_priority = priority;
00209
00210
00211
00212
00213
00214
00215
if (pthread_setschedparam (thread_id, policy, ¶ms) == 0)
00216
return 0;
00217 }
00218
#endif
00219
return -1;
00220 }
00221 }
00222
00223
00224
static inline int
00225 __gthread_objc_thread_get_priority (
void)
00226 {
00227
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
00228
if (__gthread_active_p ())
00229 {
00230
int policy;
00231
struct sched_param params;
00232
00233
if (pthread_getschedparam (pthread_self (), &policy, ¶ms) == 0)
00234
return params.sched_priority;
00235
else
00236
return -1;
00237 }
00238
else
00239
#endif
00240
return OBJC_THREAD_INTERACTIVE_PRIORITY;
00241 }
00242
00243
00244
static inline void
00245 __gthread_objc_thread_yield (
void)
00246 {
00247
if (__gthread_active_p ())
00248 sched_yield ();
00249 }
00250
00251
00252
static inline int
00253 __gthread_objc_thread_exit (
void)
00254 {
00255
if (__gthread_active_p ())
00256
00257 pthread_exit (&__objc_thread_exit_status);
00258
00259
00260
return -1;
00261 }
00262
00263
00264
static inline objc_thread_t
00265 __gthread_objc_thread_id (
void)
00266 {
00267
if (__gthread_active_p ())
00268
return (objc_thread_t) pthread_self ();
00269
else
00270
return (objc_thread_t) 1;
00271 }
00272
00273
00274
static inline int
00275 __gthread_objc_thread_set_data (
void *value)
00276 {
00277
if (__gthread_active_p ())
00278
return pthread_setspecific (_objc_thread_storage, value);
00279
else
00280 {
00281 thread_local_storage = value;
00282
return 0;
00283 }
00284 }
00285
00286
00287
static inline void *
00288 __gthread_objc_thread_get_data (
void)
00289 {
00290
if (__gthread_active_p ())
00291
return pthread_getspecific (_objc_thread_storage);
00292
else
00293
return thread_local_storage;
00294 }
00295
00296
00297
00298
00299
static inline int
00300 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
00301 {
00302
if (__gthread_active_p ())
00303 {
00304 mutex->backend = objc_malloc (
sizeof (pthread_mutex_t));
00305
00306
if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL))
00307 {
00308 objc_free (mutex->backend);
00309 mutex->backend = NULL;
00310
return -1;
00311 }
00312 }
00313
00314
return 0;
00315 }
00316
00317
00318
static inline int
00319 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
00320 {
00321
if (__gthread_active_p ())
00322 {
00323
int count;
00324
00325
00326
00327
00328
00329
00330
do
00331 {
00332
count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend);
00333
if (
count < 0)
00334
return -1;
00335 }
00336
while (
count);
00337
00338
if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend))
00339
return -1;
00340
00341 objc_free (mutex->backend);
00342 mutex->backend = NULL;
00343 }
00344
return 0;
00345 }
00346
00347
00348
static inline int
00349 __gthread_objc_mutex_lock (objc_mutex_t mutex)
00350 {
00351
if (__gthread_active_p ()
00352 && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0)
00353 {
00354
return -1;
00355 }
00356
00357
return 0;
00358 }
00359
00360
00361
static inline int
00362 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
00363 {
00364
if (__gthread_active_p ()
00365 && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0)
00366 {
00367
return -1;
00368 }
00369
00370
return 0;
00371 }
00372
00373
00374
static inline int
00375 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
00376 {
00377
if (__gthread_active_p ()
00378 && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0)
00379 {
00380
return -1;
00381 }
00382
00383
return 0;
00384 }
00385
00386
00387
00388
00389
static inline int
00390 __gthread_objc_condition_allocate (objc_condition_t condition)
00391 {
00392
if (__gthread_active_p ())
00393 {
00394 condition->backend = objc_malloc (
sizeof (pthread_cond_t));
00395
00396
if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL))
00397 {
00398 objc_free (condition->backend);
00399 condition->backend = NULL;
00400
return -1;
00401 }
00402 }
00403
00404
return 0;
00405 }
00406
00407
00408
static inline int
00409 __gthread_objc_condition_deallocate (objc_condition_t condition)
00410 {
00411
if (__gthread_active_p ())
00412 {
00413
if (pthread_cond_destroy ((pthread_cond_t *) condition->backend))
00414
return -1;
00415
00416 objc_free (condition->backend);
00417 condition->backend = NULL;
00418 }
00419
return 0;
00420 }
00421
00422
00423
static inline int
00424 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
00425 {
00426
if (__gthread_active_p ())
00427
return pthread_cond_wait ((pthread_cond_t *) condition->backend,
00428 (pthread_mutex_t *) mutex->backend);
00429
else
00430
return 0;
00431 }
00432
00433
00434
static inline int
00435 __gthread_objc_condition_broadcast (objc_condition_t condition)
00436 {
00437
if (__gthread_active_p ())
00438
return pthread_cond_broadcast ((pthread_cond_t *) condition->backend);
00439
else
00440
return 0;
00441 }
00442
00443
00444
static inline int
00445 __gthread_objc_condition_signal (objc_condition_t condition)
00446 {
00447
if (__gthread_active_p ())
00448
return pthread_cond_signal ((pthread_cond_t *) condition->backend);
00449
else
00450
return 0;
00451 }
00452
00453
#else
00454
00455
static inline int
00456 __gthread_once (__gthread_once_t *once,
void (*func) (
void))
00457 {
00458
if (__gthread_active_p ())
00459
return pthread_once (once, func);
00460
else
00461
return -1;
00462 }
00463
00464
static inline int
00465 __gthread_key_create (__gthread_key_t *key,
void (*dtor) (
void *))
00466 {
00467
return pthread_key_create (key, dtor);
00468 }
00469
00470
static inline int
00471 __gthread_key_delete (__gthread_key_t key)
00472 {
00473
return pthread_key_delete (key);
00474 }
00475
00476
static inline void *
00477 __gthread_getspecific (__gthread_key_t key)
00478 {
00479
return pthread_getspecific (key);
00480 }
00481
00482
static inline int
00483 __gthread_setspecific (__gthread_key_t key,
const void *ptr)
00484 {
00485
return pthread_setspecific (key, ptr);
00486 }
00487
00488
static inline int
00489 __gthread_mutex_lock (__gthread_mutex_t *mutex)
00490 {
00491
if (__gthread_active_p ())
00492
return pthread_mutex_lock (mutex);
00493
else
00494
return 0;
00495 }
00496
00497
static inline int
00498 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
00499 {
00500
if (__gthread_active_p ())
00501
return pthread_mutex_trylock (mutex);
00502
else
00503
return 0;
00504 }
00505
00506
static inline int
00507 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
00508 {
00509
if (__gthread_active_p ())
00510
return pthread_mutex_unlock (mutex);
00511
else
00512
return 0;
00513 }
00514
00515
#endif
00516
00517
#endif