1 /* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. 2 Contributed by Richard Henderson <rth@redhat.com>. 3 4 This file is part of the GNU OpenMP Library (libgomp). 5 6 Libgomp is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 more details. 15 16 Under Section 7 of GPL version 3, you are granted additional 17 permissions described in the GCC Runtime Library Exception, version 18 3.1, as published by the Free Software Foundation. 19 20 You should have received a copy of the GNU General Public License and 21 a copy of the GCC Runtime Library Exception along with this program; 22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 <http://www.gnu.org/licenses/>. */ 24 25 /* This is the default PTHREADS implementation of the public OpenMP 26 locking primitives. 27 28 Because OpenMP uses different entry points for normal and recursive 29 locks, and pthreads uses only one entry point, a system may be able 30 to do better and streamline the locking as well as reduce the size 31 of the types exported. */ 32 33 /* We need Unix98 extensions to get recursive locks. On Tru64 UNIX V4.0F, 34 the declarations are available without _XOPEN_SOURCE, which actually 35 breaks compilation. */ 36 #ifndef __osf__ 37 #define _XOPEN_SOURCE 500 38 #endif 39 40 #include "libgomp.h" 41 42 #ifdef HAVE_BROKEN_POSIX_SEMAPHORES 43 void 44 gomp_init_lock_30 (omp_lock_t *lock) 45 { 46 pthread_mutex_init (lock, NULL); 47 } 48 49 void 50 gomp_destroy_lock_30 (omp_lock_t *lock) 51 { 52 pthread_mutex_destroy (lock); 53 } 54 55 void 56 gomp_set_lock_30 (omp_lock_t *lock) 57 { 58 pthread_mutex_lock (lock); 59 } 60 61 void 62 gomp_unset_lock_30 (omp_lock_t *lock) 63 { 64 pthread_mutex_unlock (lock); 65 } 66 67 int 68 gomp_test_lock_30 (omp_lock_t *lock) 69 { 70 return pthread_mutex_trylock (lock) == 0; 71 } 72 73 void 74 gomp_init_nest_lock_30 (omp_nest_lock_t *lock) 75 { 76 pthread_mutex_init (&lock->lock, NULL); 77 lock->count = 0; 78 lock->owner = NULL; 79 } 80 81 void 82 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) 83 { 84 pthread_mutex_destroy (&lock->lock); 85 } 86 87 void 88 gomp_set_nest_lock_30 (omp_nest_lock_t *lock) 89 { 90 void *me = gomp_icv (true); 91 92 if (lock->owner != me) 93 { 94 pthread_mutex_lock (&lock->lock); 95 lock->owner = me; 96 } 97 lock->count++; 98 } 99 100 void 101 gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) 102 { 103 if (--lock->count == 0) 104 { 105 lock->owner = NULL; 106 pthread_mutex_unlock (&lock->lock); 107 } 108 } 109 110 int 111 gomp_test_nest_lock_30 (omp_nest_lock_t *lock) 112 { 113 void *me = gomp_icv (true); 114 115 if (lock->owner != me) 116 { 117 if (pthread_mutex_trylock (&lock->lock) != 0) 118 return 0; 119 lock->owner = me; 120 } 121 122 return ++lock->count; 123 } 124 125 #else 126 127 void 128 gomp_init_lock_30 (omp_lock_t *lock) 129 { 130 sem_init (lock, 0, 1); 131 } 132 133 void 134 gomp_destroy_lock_30 (omp_lock_t *lock) 135 { 136 sem_destroy (lock); 137 } 138 139 void 140 gomp_set_lock_30 (omp_lock_t *lock) 141 { 142 while (sem_wait (lock) != 0) 143 ; 144 } 145 146 void 147 gomp_unset_lock_30 (omp_lock_t *lock) 148 { 149 sem_post (lock); 150 } 151 152 int 153 gomp_test_lock_30 (omp_lock_t *lock) 154 { 155 return sem_trywait (lock) == 0; 156 } 157 158 void 159 gomp_init_nest_lock_30 (omp_nest_lock_t *lock) 160 { 161 sem_init (&lock->lock, 0, 1); 162 lock->count = 0; 163 lock->owner = NULL; 164 } 165 166 void 167 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) 168 { 169 sem_destroy (&lock->lock); 170 } 171 172 void 173 gomp_set_nest_lock_30 (omp_nest_lock_t *lock) 174 { 175 void *me = gomp_icv (true); 176 177 if (lock->owner != me) 178 { 179 while (sem_wait (&lock->lock) != 0) 180 ; 181 lock->owner = me; 182 } 183 lock->count++; 184 } 185 186 void 187 gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) 188 { 189 if (--lock->count == 0) 190 { 191 lock->owner = NULL; 192 sem_post (&lock->lock); 193 } 194 } 195 196 int 197 gomp_test_nest_lock_30 (omp_nest_lock_t *lock) 198 { 199 void *me = gomp_icv (true); 200 201 if (lock->owner != me) 202 { 203 if (sem_trywait (&lock->lock) != 0) 204 return 0; 205 lock->owner = me; 206 } 207 208 return ++lock->count; 209 } 210 #endif 211 212 #ifdef LIBGOMP_GNU_SYMBOL_VERSIONING 213 void 214 gomp_init_lock_25 (omp_lock_25_t *lock) 215 { 216 pthread_mutex_init (lock, NULL); 217 } 218 219 void 220 gomp_destroy_lock_25 (omp_lock_25_t *lock) 221 { 222 pthread_mutex_destroy (lock); 223 } 224 225 void 226 gomp_set_lock_25 (omp_lock_25_t *lock) 227 { 228 pthread_mutex_lock (lock); 229 } 230 231 void 232 gomp_unset_lock_25 (omp_lock_25_t *lock) 233 { 234 pthread_mutex_unlock (lock); 235 } 236 237 int 238 gomp_test_lock_25 (omp_lock_25_t *lock) 239 { 240 return pthread_mutex_trylock (lock) == 0; 241 } 242 243 void 244 gomp_init_nest_lock_25 (omp_nest_lock_25_t *lock) 245 { 246 pthread_mutexattr_t attr; 247 248 pthread_mutexattr_init (&attr); 249 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 250 pthread_mutex_init (&lock->lock, &attr); 251 lock->count = 0; 252 pthread_mutexattr_destroy (&attr); 253 } 254 255 void 256 gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *lock) 257 { 258 pthread_mutex_destroy (&lock->lock); 259 } 260 261 void 262 gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock) 263 { 264 pthread_mutex_lock (&lock->lock); 265 lock->count++; 266 } 267 268 void 269 gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock) 270 { 271 lock->count--; 272 pthread_mutex_unlock (&lock->lock); 273 } 274 275 int 276 gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock) 277 { 278 if (pthread_mutex_trylock (&lock->lock) == 0) 279 return ++lock->count; 280 return 0; 281 } 282 283 omp_lock_symver (omp_init_lock) 284 omp_lock_symver (omp_destroy_lock) 285 omp_lock_symver (omp_set_lock) 286 omp_lock_symver (omp_unset_lock) 287 omp_lock_symver (omp_test_lock) 288 omp_lock_symver (omp_init_nest_lock) 289 omp_lock_symver (omp_destroy_nest_lock) 290 omp_lock_symver (omp_set_nest_lock) 291 omp_lock_symver (omp_unset_nest_lock) 292 omp_lock_symver (omp_test_nest_lock) 293 294 #else 295 296 ialias (omp_init_lock) 297 ialias (omp_init_nest_lock) 298 ialias (omp_destroy_lock) 299 ialias (omp_destroy_nest_lock) 300 ialias (omp_set_lock) 301 ialias (omp_set_nest_lock) 302 ialias (omp_unset_lock) 303 ialias (omp_unset_nest_lock) 304 ialias (omp_test_lock) 305 ialias (omp_test_nest_lock) 306 307 #endif 308