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