gthr-posix.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 #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 /* Objective-C. */ 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 /* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but 00072 we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block. */ 00073 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 00074 #pragma weak sched_get_priority_max 00075 #pragma weak sched_get_priority_min 00076 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 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 /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00085 #endif /* _LIBOBJC */ 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 /* not _GLIBCPP_SUPPORTS_WEAK */ 00095 00096 static inline int 00097 __gthread_active_p (void) 00098 { 00099 return 1; 00100 } 00101 00102 #endif /* _GLIBCPP_SUPPORTS_WEAK */ 00103 00104 #ifdef _LIBOBJC 00105 00106 /* This is the config.h file in libobjc/ */ 00107 #include <config.h> 00108 00109 #ifdef HAVE_SCHED_H 00110 # include <sched.h> 00111 #endif 00112 00113 /* Key structure for maintaining thread specific storage */ 00114 static pthread_key_t _objc_thread_storage; 00115 static pthread_attr_t _objc_thread_attribs; 00116 00117 /* Thread local storage for a single thread */ 00118 static void *thread_local_storage = NULL; 00119 00120 /* Backend initialization functions */ 00121 00122 /* Initialize the threads subsystem. */ 00123 static inline int 00124 __gthread_objc_init_thread_system (void) 00125 { 00126 if (__gthread_active_p ()) 00127 { 00128 /* Initialize the thread storage key */ 00129 if (pthread_key_create (&_objc_thread_storage, NULL) == 0) 00130 { 00131 /* The normal default detach state for threads is 00132 * PTHREAD_CREATE_JOINABLE which causes threads to not die 00133 * when you think they should. */ 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 /* Close the threads subsystem. */ 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 /* Backend thread functions */ 00157 00158 /* Create a new thread of execution. */ 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 /* Set the current thread's priority. */ 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, &params) == 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 * The solaris 7 and several other man pages incorrectly state that 00206 * this should be a pointer to policy but pthread.h is universally 00207 * at odds with this. 00208 */ 00209 if (pthread_setschedparam (thread_id, policy, &params) == 0) 00210 return 0; 00211 } 00212 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00213 return -1; 00214 } 00215 } 00216 00217 /* Return the current thread's priority. */ 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, &params) == 0) 00228 return params.sched_priority; 00229 else 00230 return -1; 00231 } 00232 else 00233 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00234 return OBJC_THREAD_INTERACTIVE_PRIORITY; 00235 } 00236 00237 /* Yield our process time to another thread. */ 00238 static inline void 00239 __gthread_objc_thread_yield (void) 00240 { 00241 if (__gthread_active_p ()) 00242 sched_yield (); 00243 } 00244 00245 /* Terminate the current thread. */ 00246 static inline int 00247 __gthread_objc_thread_exit (void) 00248 { 00249 if (__gthread_active_p ()) 00250 /* exit the thread */ 00251 pthread_exit (&__objc_thread_exit_status); 00252 00253 /* Failed if we reached here */ 00254 return -1; 00255 } 00256 00257 /* Returns an integer value which uniquely describes a thread. */ 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 /* Sets the thread's local storage pointer. */ 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 /* Returns the thread's local storage pointer. */ 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 /* Backend mutex functions */ 00291 00292 /* Allocate a mutex. */ 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 /* Deallocate a mutex. */ 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 * Posix Threads specifically require that the thread be unlocked 00321 * for pthread_mutex_destroy to work. 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 /* Grab a lock on a mutex. */ 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 /* Try to grab a lock on a mutex. */ 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 /* Unlock the mutex */ 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 /* Backend condition mutex functions */ 00381 00382 /* Allocate a condition. */ 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 /* Deallocate a condition. */ 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 /* Wait on the condition */ 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 /* Wake up all threads waiting on this condition. */ 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 /* Wake up one thread waiting on this condition. */ 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 /* _LIBOBJC */ 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 /* Just reset the key value to zero. */ 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 /* _LIBOBJC */ 00520 00521 #endif /* ! _GLIBCPP_GCC_GTHR_POSIX_H */

Generated on Wed Aug 4 21:43:11 2004 for libstdc++-v3 Source by doxygen 1.3.8