gthr-default.h

00001 /* Threads compatibility routines for libgcc2 and libobjc.  */
00002 /* Compile this one with gcc.  */
00003 /* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
00004 
00005 This file is part of GCC.
00006 
00007 GCC is free software; you can redistribute it and/or modify it under
00008 the terms of the GNU General Public License as published by the Free
00009 Software Foundation; either version 2, or (at your option) any later
00010 version.
00011 
00012 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
00013 WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GCC; see the file COPYING.  If not, write to the Free
00019 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
00020 02111-1307, USA.  */
00021 
00022 /* As a special exception, if you link this library with other files,
00023    some of which are compiled with GCC, to produce an executable,
00024    this library does not by itself cause the resulting executable
00025    to be covered by the GNU General Public License.
00026    This exception does not however invalidate any other reasons why
00027    the executable file might be covered by the GNU General Public License.  */
00028 
00029 #ifndef _GLIBCPP_GCC_GTHR_POSIX_H
00030 #define _GLIBCPP_GCC_GTHR_POSIX_H
00031 
00032 /* POSIX threads specific definitions.
00033    Easy, since the interface is just one-to-one mapping.  */
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 /* Objective C.  */
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 /* not _GLIBCPP_SUPPORTS_WEAK */
00088 
00089 static inline int
00090 __gthread_active_p (void)
00091 {
00092   return 1;
00093 }
00094 
00095 #endif /* _GLIBCPP_SUPPORTS_WEAK */
00096 
00097 #ifdef _LIBOBJC
00098 
00099 /* This is the config.h file in libobjc/ */
00100 #include <config.h>
00101 
00102 #ifdef HAVE_SCHED_H
00103 # include <sched.h>
00104 #endif
00105 
00106 /* Key structure for maintaining thread specific storage */
00107 static pthread_key_t _objc_thread_storage;
00108 static pthread_attr_t _objc_thread_attribs;
00109 
00110 /* Thread local storage for a single thread */
00111 static void *thread_local_storage = NULL;
00112 
00113 /* Backend initialization functions */
00114 
00115 /* Initialize the threads subsystem.  */
00116 static inline int
00117 __gthread_objc_init_thread_system(void)
00118 {
00119   if (__gthread_active_p ())
00120     {
00121       /* Initialize the thread storage key */
00122       if (pthread_key_create(&_objc_thread_storage, NULL) == 0)
00123         {
00124           /* The normal default detach state for threads is
00125            * PTHREAD_CREATE_JOINABLE which causes threads to not die
00126            * when you think they should.  */
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 /* Close the threads subsystem.  */
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 /* Backend thread functions */
00150 
00151 /* Create a new thread of execution.  */
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 /* Set the current thread's priority.  */
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, &params) == 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          * The solaris 7 and several other man pages incorrectly state that
00197          * this should be a pointer to policy but pthread.h is universally
00198          * at odds with this.
00199          */
00200         if (pthread_setschedparam(thread_id, policy, &params) == 0)
00201           return 0;
00202       }
00203     return -1;
00204   }
00205 }
00206 
00207 /* Return the current thread's priority.  */
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, &params) == 0)
00217         return params.sched_priority;
00218       else
00219         return -1;
00220     }
00221   else
00222     return OBJC_THREAD_INTERACTIVE_PRIORITY;
00223 }
00224 
00225 /* Yield our process time to another thread.  */
00226 static inline void
00227 __gthread_objc_thread_yield(void)
00228 {
00229   if (__gthread_active_p ())
00230     sched_yield();
00231 }
00232 
00233 /* Terminate the current thread.  */
00234 static inline int
00235 __gthread_objc_thread_exit(void)
00236 {
00237   if (__gthread_active_p ())
00238     /* exit the thread */
00239     pthread_exit(&__objc_thread_exit_status);
00240 
00241   /* Failed if we reached here */
00242   return -1;
00243 }
00244 
00245 /* Returns an integer value which uniquely describes a thread.  */
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 /* Sets the thread's local storage pointer.  */
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 /* Returns the thread's local storage pointer.  */
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 /* Backend mutex functions */
00279 
00280 /* Allocate a mutex.  */
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 /* Deallocate a mutex.  */
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        * Posix Threads specifically require that the thread be unlocked
00309        * for pthread_mutex_destroy to work.
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 /* Grab a lock on a mutex.  */
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 /* Try to grab a lock on a mutex.  */
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 /* Unlock the mutex */
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 /* Backend condition mutex functions */
00369 
00370 /* Allocate a condition.  */
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 /* Deallocate a condition.  */
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 /* Wait on the condition */
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 /* Wake up all threads waiting on this condition.  */
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 /* Wake up one thread waiting on this condition.  */
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 /* _LIBOBJC */
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   /* Just reset the key value to zero.  */
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 /* _LIBOBJC */
00508 
00509 #endif /* ! _GLIBCPP_GCC_GTHR_POSIX_H */

Generated on Tue Dec 23 12:33:40 2003 for libstdc++-v3 Source by doxygen 1.3.4