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 Wed Sep 29 13:54:48 2004 for libstdc++-v3 Source by doxygen 1.3.7