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