gthr-posix.h

00001 /* Threads compatibility routines for libgcc2 and libobjc. */ 00002 /* Compile this one with gcc. */ 00003 /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 00004 Free Software Foundation, Inc. 00005 00006 This file is part of GCC. 00007 00008 GCC is free software; you can redistribute it and/or modify it under 00009 the terms of the GNU General Public License as published by the Free 00010 Software Foundation; either version 2, or (at your option) any later 00011 version. 00012 00013 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 00014 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00015 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00016 for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with GCC; see the file COPYING. If not, write to the Free 00020 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 00021 02111-1307, USA. */ 00022 00023 /* As a special exception, if you link this library with other files, 00024 some of which are compiled with GCC, to produce an executable, 00025 this library does not by itself cause the resulting executable 00026 to be covered by the GNU General Public License. 00027 This exception does not however invalidate any other reasons why 00028 the executable file might be covered by the GNU General Public License. */ 00029 00030 #ifndef _GLIBCXX_GCC_GTHR_POSIX_H 00031 #define _GLIBCXX_GCC_GTHR_POSIX_H 00032 00033 /* POSIX threads specific definitions. 00034 Easy, since the interface is just one-to-one mapping. */ 00035 00036 #define __GTHREADS 1 00037 00038 /* Some implementations of <pthread.h> require this to be defined. */ 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 /* Objective-C. */ 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 /* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but 00078 we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block. */ 00079 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 00080 #pragma weak sched_get_priority_max 00081 #pragma weak sched_get_priority_min 00082 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 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 /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00091 #endif /* _LIBOBJC || _LIBOBJC_WEAK */ 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 /* not __GXX_WEAK__ */ 00101 00102 static inline int 00103 __gthread_active_p (void) 00104 { 00105 return 1; 00106 } 00107 00108 #endif /* __GXX_WEAK__ */ 00109 00110 #ifdef _LIBOBJC 00111 00112 /* This is the config.h file in libobjc/ */ 00113 #include <config.h> 00114 00115 #ifdef HAVE_SCHED_H 00116 # include <sched.h> 00117 #endif 00118 00119 /* Key structure for maintaining thread specific storage */ 00120 static pthread_key_t _objc_thread_storage; 00121 static pthread_attr_t _objc_thread_attribs; 00122 00123 /* Thread local storage for a single thread */ 00124 static void *thread_local_storage = NULL; 00125 00126 /* Backend initialization functions */ 00127 00128 /* Initialize the threads subsystem. */ 00129 static inline int 00130 __gthread_objc_init_thread_system (void) 00131 { 00132 if (__gthread_active_p ()) 00133 { 00134 /* Initialize the thread storage key */ 00135 if (pthread_key_create (&_objc_thread_storage, NULL) == 0) 00136 { 00137 /* The normal default detach state for threads is 00138 * PTHREAD_CREATE_JOINABLE which causes threads to not die 00139 * when you think they should. */ 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 /* Close the threads subsystem. */ 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 /* Backend thread functions */ 00163 00164 /* Create a new thread of execution. */ 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 /* Set the current thread's priority. */ 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, &params) == 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 * The solaris 7 and several other man pages incorrectly state that 00212 * this should be a pointer to policy but pthread.h is universally 00213 * at odds with this. 00214 */ 00215 if (pthread_setschedparam (thread_id, policy, &params) == 0) 00216 return 0; 00217 } 00218 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00219 return -1; 00220 } 00221 } 00222 00223 /* Return the current thread's priority. */ 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, &params) == 0) 00234 return params.sched_priority; 00235 else 00236 return -1; 00237 } 00238 else 00239 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00240 return OBJC_THREAD_INTERACTIVE_PRIORITY; 00241 } 00242 00243 /* Yield our process time to another thread. */ 00244 static inline void 00245 __gthread_objc_thread_yield (void) 00246 { 00247 if (__gthread_active_p ()) 00248 sched_yield (); 00249 } 00250 00251 /* Terminate the current thread. */ 00252 static inline int 00253 __gthread_objc_thread_exit (void) 00254 { 00255 if (__gthread_active_p ()) 00256 /* exit the thread */ 00257 pthread_exit (&__objc_thread_exit_status); 00258 00259 /* Failed if we reached here */ 00260 return -1; 00261 } 00262 00263 /* Returns an integer value which uniquely describes a thread. */ 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 /* Sets the thread's local storage pointer. */ 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 /* Returns the thread's local storage pointer. */ 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 /* Backend mutex functions */ 00297 00298 /* Allocate a mutex. */ 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 /* Deallocate a mutex. */ 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 * Posix Threads specifically require that the thread be unlocked 00327 * for pthread_mutex_destroy to work. 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 /* Grab a lock on a mutex. */ 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 /* Try to grab a lock on a mutex. */ 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 /* Unlock the mutex */ 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 /* Backend condition mutex functions */ 00387 00388 /* Allocate a condition. */ 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 /* Deallocate a condition. */ 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 /* Wait on the condition */ 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 /* Wake up all threads waiting on this condition. */ 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 /* Wake up one thread waiting on this condition. */ 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 /* _LIBOBJC */ 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 /* _LIBOBJC */ 00516 00517 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

Generated on Wed Sep 8 10:19:31 2004 for libstdc++-v3 Source by doxygen 1.3.8