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