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