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