00001 /* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. 00002 Contributed by Richard Henderson <rth@redhat.com>. 00003 00004 This file is part of the GNU OpenMP Library (libgomp). 00005 00006 Libgomp is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3, or (at your option) 00009 any later version. 00010 00011 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 00012 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00013 FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00014 more details. 00015 00016 Under Section 7 of GPL version 3, you are granted additional 00017 permissions described in the GCC Runtime Library Exception, version 00018 3.1, as published by the Free Software Foundation. 00019 00020 You should have received a copy of the GNU General Public License and 00021 a copy of the GCC Runtime Library Exception along with this program; 00022 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 <http://www.gnu.org/licenses/>. */ 00024 00025 /* This is the default PTHREADS implementation of the public OpenMP 00026 locking primitives. 00027 00028 Because OpenMP uses different entry points for normal and recursive 00029 locks, and pthreads uses only one entry point, a system may be able 00030 to do better and streamline the locking as well as reduce the size 00031 of the types exported. */ 00032 00033 /* We need Unix98 extensions to get recursive locks. On Tru64 UNIX V4.0F, 00034 the declarations are available without _XOPEN_SOURCE, which actually 00035 breaks compilation. */ 00036 #ifndef __osf__ 00037 #define _XOPEN_SOURCE 500 00038 #endif 00039 00040 #include "libgomp.h" 00041 00042 #ifdef HAVE_BROKEN_POSIX_SEMAPHORES 00043 void 00044 gomp_init_lock_30 (omp_lock_t *lock) 00045 { 00046 pthread_mutex_init (lock, NULL); 00047 } 00048 00049 void 00050 gomp_destroy_lock_30 (omp_lock_t *lock) 00051 { 00052 pthread_mutex_destroy (lock); 00053 } 00054 00055 void 00056 gomp_set_lock_30 (omp_lock_t *lock) 00057 { 00058 pthread_mutex_lock (lock); 00059 } 00060 00061 void 00062 gomp_unset_lock_30 (omp_lock_t *lock) 00063 { 00064 pthread_mutex_unlock (lock); 00065 } 00066 00067 int 00068 gomp_test_lock_30 (omp_lock_t *lock) 00069 { 00070 return pthread_mutex_trylock (lock) == 0; 00071 } 00072 00073 void 00074 gomp_init_nest_lock_30 (omp_nest_lock_t *lock) 00075 { 00076 pthread_mutex_init (&lock->lock, NULL); 00077 lock->count = 0; 00078 lock->owner = NULL; 00079 } 00080 00081 void 00082 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) 00083 { 00084 pthread_mutex_destroy (&lock->lock); 00085 } 00086 00087 void 00088 gomp_set_nest_lock_30 (omp_nest_lock_t *lock) 00089 { 00090 void *me = gomp_icv (true); 00091 00092 if (lock->owner != me) 00093 { 00094 pthread_mutex_lock (&lock->lock); 00095 lock->owner = me; 00096 } 00097 lock->count++; 00098 } 00099 00100 void 00101 gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) 00102 { 00103 if (--lock->count == 0) 00104 { 00105 lock->owner = NULL; 00106 pthread_mutex_unlock (&lock->lock); 00107 } 00108 } 00109 00110 int 00111 gomp_test_nest_lock_30 (omp_nest_lock_t *lock) 00112 { 00113 void *me = gomp_icv (true); 00114 00115 if (lock->owner != me) 00116 { 00117 if (pthread_mutex_trylock (&lock->lock) != 0) 00118 return 0; 00119 lock->owner = me; 00120 } 00121 00122 return ++lock->count; 00123 } 00124 00125 #else 00126 00127 void 00128 gomp_init_lock_30 (omp_lock_t *lock) 00129 { 00130 sem_init (lock, 0, 1); 00131 } 00132 00133 void 00134 gomp_destroy_lock_30 (omp_lock_t *lock) 00135 { 00136 sem_destroy (lock); 00137 } 00138 00139 void 00140 gomp_set_lock_30 (omp_lock_t *lock) 00141 { 00142 while (sem_wait (lock) != 0) 00143 ; 00144 } 00145 00146 void 00147 gomp_unset_lock_30 (omp_lock_t *lock) 00148 { 00149 sem_post (lock); 00150 } 00151 00152 int 00153 gomp_test_lock_30 (omp_lock_t *lock) 00154 { 00155 return sem_trywait (lock) == 0; 00156 } 00157 00158 void 00159 gomp_init_nest_lock_30 (omp_nest_lock_t *lock) 00160 { 00161 sem_init (&lock->lock, 0, 1); 00162 lock->count = 0; 00163 lock->owner = NULL; 00164 } 00165 00166 void 00167 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) 00168 { 00169 sem_destroy (&lock->lock); 00170 } 00171 00172 void 00173 gomp_set_nest_lock_30 (omp_nest_lock_t *lock) 00174 { 00175 void *me = gomp_icv (true); 00176 00177 if (lock->owner != me) 00178 { 00179 while (sem_wait (&lock->lock) != 0) 00180 ; 00181 lock->owner = me; 00182 } 00183 lock->count++; 00184 } 00185 00186 void 00187 gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) 00188 { 00189 if (--lock->count == 0) 00190 { 00191 lock->owner = NULL; 00192 sem_post (&lock->lock); 00193 } 00194 } 00195 00196 int 00197 gomp_test_nest_lock_30 (omp_nest_lock_t *lock) 00198 { 00199 void *me = gomp_icv (true); 00200 00201 if (lock->owner != me) 00202 { 00203 if (sem_trywait (&lock->lock) != 0) 00204 return 0; 00205 lock->owner = me; 00206 } 00207 00208 return ++lock->count; 00209 } 00210 #endif 00211 00212 #ifdef LIBGOMP_GNU_SYMBOL_VERSIONING 00213 void 00214 gomp_init_lock_25 (omp_lock_25_t *lock) 00215 { 00216 pthread_mutex_init (lock, NULL); 00217 } 00218 00219 void 00220 gomp_destroy_lock_25 (omp_lock_25_t *lock) 00221 { 00222 pthread_mutex_destroy (lock); 00223 } 00224 00225 void 00226 gomp_set_lock_25 (omp_lock_25_t *lock) 00227 { 00228 pthread_mutex_lock (lock); 00229 } 00230 00231 void 00232 gomp_unset_lock_25 (omp_lock_25_t *lock) 00233 { 00234 pthread_mutex_unlock (lock); 00235 } 00236 00237 int 00238 gomp_test_lock_25 (omp_lock_25_t *lock) 00239 { 00240 return pthread_mutex_trylock (lock) == 0; 00241 } 00242 00243 void 00244 gomp_init_nest_lock_25 (omp_nest_lock_25_t *lock) 00245 { 00246 pthread_mutexattr_t attr; 00247 00248 pthread_mutexattr_init (&attr); 00249 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 00250 pthread_mutex_init (&lock->lock, &attr); 00251 lock->count = 0; 00252 pthread_mutexattr_destroy (&attr); 00253 } 00254 00255 void 00256 gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *lock) 00257 { 00258 pthread_mutex_destroy (&lock->lock); 00259 } 00260 00261 void 00262 gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock) 00263 { 00264 pthread_mutex_lock (&lock->lock); 00265 lock->count++; 00266 } 00267 00268 void 00269 gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock) 00270 { 00271 lock->count--; 00272 pthread_mutex_unlock (&lock->lock); 00273 } 00274 00275 int 00276 gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock) 00277 { 00278 if (pthread_mutex_trylock (&lock->lock) == 0) 00279 return ++lock->count; 00280 return 0; 00281 } 00282 00283 omp_lock_symver (omp_init_lock) 00284 omp_lock_symver (omp_destroy_lock) 00285 omp_lock_symver (omp_set_lock) 00286 omp_lock_symver (omp_unset_lock) 00287 omp_lock_symver (omp_test_lock) 00288 omp_lock_symver (omp_init_nest_lock) 00289 omp_lock_symver (omp_destroy_nest_lock) 00290 omp_lock_symver (omp_set_nest_lock) 00291 omp_lock_symver (omp_unset_nest_lock) 00292 omp_lock_symver (omp_test_nest_lock) 00293 00294 #else 00295 00296 ialias (omp_init_lock) 00297 ialias (omp_init_nest_lock) 00298 ialias (omp_destroy_lock) 00299 ialias (omp_destroy_nest_lock) 00300 ialias (omp_set_lock) 00301 ialias (omp_set_nest_lock) 00302 ialias (omp_unset_lock) 00303 ialias (omp_unset_nest_lock) 00304 ialias (omp_test_lock) 00305 ialias (omp_test_nest_lock) 00306 00307 #endif