gthr-default.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 #ifdef _POSIX_PRIORITY_SCHEDULING 00078 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 00079 #pragma weak sched_get_priority_max 00080 #pragma weak sched_get_priority_min 00081 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00082 #endif /* _POSIX_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_PRIORITY_SCHEDULING 00191 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 00192 pthread_t thread_id = pthread_self (); 00193 int policy; 00194 struct sched_param params; 00195 int priority_min, priority_max; 00196 00197 if (pthread_getschedparam (thread_id, &policy, &params) == 0) 00198 { 00199 if ((priority_max = sched_get_priority_max (policy)) == -1) 00200 return -1; 00201 00202 if ((priority_min = sched_get_priority_min (policy)) == -1) 00203 return -1; 00204 00205 if (priority > priority_max) 00206 priority = priority_max; 00207 else if (priority < priority_min) 00208 priority = priority_min; 00209 params.sched_priority = priority; 00210 00211 /* 00212 * The solaris 7 and several other man pages incorrectly state that 00213 * this should be a pointer to policy but pthread.h is universally 00214 * at odds with this. 00215 */ 00216 if (pthread_setschedparam (thread_id, policy, &params) == 0) 00217 return 0; 00218 } 00219 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00220 #endif /* _POSIX_PRIORITY_SCHEDULING */ 00221 return -1; 00222 } 00223 } 00224 00225 /* Return the current thread's priority. */ 00226 static inline int 00227 __gthread_objc_thread_get_priority (void) 00228 { 00229 #ifdef _POSIX_PRIORITY_SCHEDULING 00230 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING 00231 if (__gthread_active_p ()) 00232 { 00233 int policy; 00234 struct sched_param params; 00235 00236 if (pthread_getschedparam (pthread_self (), &policy, &params) == 0) 00237 return params.sched_priority; 00238 else 00239 return -1; 00240 } 00241 else 00242 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ 00243 #endif /* _POSIX_PRIORITY_SCHEDULING */ 00244 return OBJC_THREAD_INTERACTIVE_PRIORITY; 00245 } 00246 00247 /* Yield our process time to another thread. */ 00248 static inline void 00249 __gthread_objc_thread_yield (void) 00250 { 00251 if (__gthread_active_p ()) 00252 sched_yield (); 00253 } 00254 00255 /* Terminate the current thread. */ 00256 static inline int 00257 __gthread_objc_thread_exit (void) 00258 { 00259 if (__gthread_active_p ()) 00260 /* exit the thread */ 00261 pthread_exit (&__objc_thread_exit_status); 00262 00263 /* Failed if we reached here */ 00264 return -1; 00265 } 00266 00267 /* Returns an integer value which uniquely describes a thread. */ 00268 static inline objc_thread_t 00269 __gthread_objc_thread_id (void) 00270 { 00271 if (__gthread_active_p ()) 00272 return (objc_thread_t) pthread_self (); 00273 else 00274 return (objc_thread_t) 1; 00275 } 00276 00277 /* Sets the thread's local storage pointer. */ 00278 static inline int 00279 __gthread_objc_thread_set_data (void *value) 00280 { 00281 if (__gthread_active_p ()) 00282 return pthread_setspecific (_objc_thread_storage, value); 00283 else 00284 { 00285 thread_local_storage = value; 00286 return 0; 00287 } 00288 } 00289 00290 /* Returns the thread's local storage pointer. */ 00291 static inline void * 00292 __gthread_objc_thread_get_data (void) 00293 { 00294 if (__gthread_active_p ()) 00295 return pthread_getspecific (_objc_thread_storage); 00296 else 00297 return thread_local_storage; 00298 } 00299 00300 /* Backend mutex functions */ 00301 00302 /* Allocate a mutex. */ 00303 static inline int 00304 __gthread_objc_mutex_allocate (objc_mutex_t mutex) 00305 { 00306 if (__gthread_active_p ()) 00307 { 00308 mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); 00309 00310 if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL)) 00311 { 00312 objc_free (mutex->backend); 00313 mutex->backend = NULL; 00314 return -1; 00315 } 00316 } 00317 00318 return 0; 00319 } 00320 00321 /* Deallocate a mutex. */ 00322 static inline int 00323 __gthread_objc_mutex_deallocate (objc_mutex_t mutex) 00324 { 00325 if (__gthread_active_p ()) 00326 { 00327 int count; 00328 00329 /* 00330 * Posix Threads specifically require that the thread be unlocked 00331 * for pthread_mutex_destroy to work. 00332 */ 00333 00334 do 00335 { 00336 count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend); 00337 if (count < 0) 00338 return -1; 00339 } 00340 while (count); 00341 00342 if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend)) 00343 return -1; 00344 00345 objc_free (mutex->backend); 00346 mutex->backend = NULL; 00347 } 00348 return 0; 00349 } 00350 00351 /* Grab a lock on a mutex. */ 00352 static inline int 00353 __gthread_objc_mutex_lock (objc_mutex_t mutex) 00354 { 00355 if (__gthread_active_p () 00356 && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0) 00357 { 00358 return -1; 00359 } 00360 00361 return 0; 00362 } 00363 00364 /* Try to grab a lock on a mutex. */ 00365 static inline int 00366 __gthread_objc_mutex_trylock (objc_mutex_t mutex) 00367 { 00368 if (__gthread_active_p () 00369 && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0) 00370 { 00371 return -1; 00372 } 00373 00374 return 0; 00375 } 00376 00377 /* Unlock the mutex */ 00378 static inline int 00379 __gthread_objc_mutex_unlock (objc_mutex_t mutex) 00380 { 00381 if (__gthread_active_p () 00382 && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0) 00383 { 00384 return -1; 00385 } 00386 00387 return 0; 00388 } 00389 00390 /* Backend condition mutex functions */ 00391 00392 /* Allocate a condition. */ 00393 static inline int 00394 __gthread_objc_condition_allocate (objc_condition_t condition) 00395 { 00396 if (__gthread_active_p ()) 00397 { 00398 condition->backend = objc_malloc (sizeof (pthread_cond_t)); 00399 00400 if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL)) 00401 { 00402 objc_free (condition->backend); 00403 condition->backend = NULL; 00404 return -1; 00405 } 00406 } 00407 00408 return 0; 00409 } 00410 00411 /* Deallocate a condition. */ 00412 static inline int 00413 __gthread_objc_condition_deallocate (objc_condition_t condition) 00414 { 00415 if (__gthread_active_p ()) 00416 { 00417 if (pthread_cond_destroy ((pthread_cond_t *) condition->backend)) 00418 return -1; 00419 00420 objc_free (condition->backend); 00421 condition->backend = NULL; 00422 } 00423 return 0; 00424 } 00425 00426 /* Wait on the condition */ 00427 static inline int 00428 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) 00429 { 00430 if (__gthread_active_p ()) 00431 return pthread_cond_wait ((pthread_cond_t *) condition->backend, 00432 (pthread_mutex_t *) mutex->backend); 00433 else 00434 return 0; 00435 } 00436 00437 /* Wake up all threads waiting on this condition. */ 00438 static inline int 00439 __gthread_objc_condition_broadcast (objc_condition_t condition) 00440 { 00441 if (__gthread_active_p ()) 00442 return pthread_cond_broadcast ((pthread_cond_t *) condition->backend); 00443 else 00444 return 0; 00445 } 00446 00447 /* Wake up one thread waiting on this condition. */ 00448 static inline int 00449 __gthread_objc_condition_signal (objc_condition_t condition) 00450 { 00451 if (__gthread_active_p ()) 00452 return pthread_cond_signal ((pthread_cond_t *) condition->backend); 00453 else 00454 return 0; 00455 } 00456 00457 #else /* _LIBOBJC */ 00458 00459 static inline int 00460 __gthread_once (__gthread_once_t *once, void (*func) (void)) 00461 { 00462 if (__gthread_active_p ()) 00463 return pthread_once (once, func); 00464 else 00465 return -1; 00466 } 00467 00468 static inline int 00469 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) 00470 { 00471 return pthread_key_create (key, dtor); 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 /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

Generated on Wed Jun 9 11:18:27 2004 for libstdc++-v3 Source by doxygen 1.3.7