1 /* Copyright (C) 2005-2013 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. */ 34 #define _XOPEN_SOURCE 500 35 36 #include "libgomp.h" 37 38 #ifdef HAVE_BROKEN_POSIX_SEMAPHORES 39 void 40 gomp_init_lock_30 (omp_lock_t *lock) 41 { 42 pthread_mutex_init (lock, NULL); 43 } 44 45 void 46 gomp_destroy_lock_30 (omp_lock_t *lock) 47 { 48 pthread_mutex_destroy (lock); 49 } 50 51 void 52 gomp_set_lock_30 (omp_lock_t *lock) 53 { 54 pthread_mutex_lock (lock); 55 } 56 57 void 58 gomp_unset_lock_30 (omp_lock_t *lock) 59 { 60 pthread_mutex_unlock (lock); 61 } 62 63 int 64 gomp_test_lock_30 (omp_lock_t *lock) 65 { 66 return pthread_mutex_trylock (lock) == 0; 67 } 68 69 void 70 gomp_init_nest_lock_30 (omp_nest_lock_t *lock) 71 { 72 pthread_mutex_init (&lock->lock, NULL); 73 lock->count = 0; 74 lock->owner = NULL; 75 } 76 77 void 78 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) 79 { 80 pthread_mutex_destroy (&lock->lock); 81 } 82 83 void 84 gomp_set_nest_lock_30 (omp_nest_lock_t *lock) 85 { 86 void *me = gomp_icv (true); 87 88 if (lock->owner != me) 89 { 90 pthread_mutex_lock (&lock->lock); 91 lock->owner = me; 92 } 93 lock->count++; 94 } 95 96 void 97 gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) 98 { 99 if (--lock->count == 0) 100 { 101 lock->owner = NULL; 102 pthread_mutex_unlock (&lock->lock); 103 } 104 } 105 106 int 107 gomp_test_nest_lock_30 (omp_nest_lock_t *lock) 108 { 109 void *me = gomp_icv (true); 110 111 if (lock->owner != me) 112 { 113 if (pthread_mutex_trylock (&lock->lock) != 0) 114 return 0; 115 lock->owner = me; 116 } 117 118 return ++lock->count; 119 } 120 121 #else 122 123 void 124 gomp_init_lock_30 (omp_lock_t *lock) 125 { 126 sem_init (lock, 0, 1); 127 } 128 129 void 130 gomp_destroy_lock_30 (omp_lock_t *lock) 131 { 132 sem_destroy (lock); 133 } 134 135 void 136 gomp_set_lock_30 (omp_lock_t *lock) 137 { 138 while (sem_wait (lock) != 0) 139 ; 140 } 141 142 void 143 gomp_unset_lock_30 (omp_lock_t *lock) 144 { 145 sem_post (lock); 146 } 147 148 int 149 gomp_test_lock_30 (omp_lock_t *lock) 150 { 151 return sem_trywait (lock) == 0; 152 } 153 154 void 155 gomp_init_nest_lock_30 (omp_nest_lock_t *lock) 156 { 157 sem_init (&lock->lock, 0, 1); 158 lock->count = 0; 159 lock->owner = NULL; 160 } 161 162 void 163 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) 164 { 165 sem_destroy (&lock->lock); 166 } 167 168 void 169 gomp_set_nest_lock_30 (omp_nest_lock_t *lock) 170 { 171 void *me = gomp_icv (true); 172 173 if (lock->owner != me) 174 { 175 while (sem_wait (&lock->lock) != 0) 176 ; 177 lock->owner = me; 178 } 179 lock->count++; 180 } 181 182 void 183 gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) 184 { 185 if (--lock->count == 0) 186 { 187 lock->owner = NULL; 188 sem_post (&lock->lock); 189 } 190 } 191 192 int 193 gomp_test_nest_lock_30 (omp_nest_lock_t *lock) 194 { 195 void *me = gomp_icv (true); 196 197 if (lock->owner != me) 198 { 199 if (sem_trywait (&lock->lock) != 0) 200 return 0; 201 lock->owner = me; 202 } 203 204 return ++lock->count; 205 } 206 #endif 207 208 #ifdef LIBGOMP_GNU_SYMBOL_VERSIONING 209 void 210 gomp_init_lock_25 (omp_lock_25_t *lock) 211 { 212 pthread_mutex_init (lock, NULL); 213 } 214 215 void 216 gomp_destroy_lock_25 (omp_lock_25_t *lock) 217 { 218 pthread_mutex_destroy (lock); 219 } 220 221 void 222 gomp_set_lock_25 (omp_lock_25_t *lock) 223 { 224 pthread_mutex_lock (lock); 225 } 226 227 void 228 gomp_unset_lock_25 (omp_lock_25_t *lock) 229 { 230 pthread_mutex_unlock (lock); 231 } 232 233 int 234 gomp_test_lock_25 (omp_lock_25_t *lock) 235 { 236 return pthread_mutex_trylock (lock) == 0; 237 } 238 239 void 240 gomp_init_nest_lock_25 (omp_nest_lock_25_t *lock) 241 { 242 pthread_mutexattr_t attr; 243 244 pthread_mutexattr_init (&attr); 245 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 246 pthread_mutex_init (&lock->lock, &attr); 247 lock->count = 0; 248 pthread_mutexattr_destroy (&attr); 249 } 250 251 void 252 gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *lock) 253 { 254 pthread_mutex_destroy (&lock->lock); 255 } 256 257 void 258 gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock) 259 { 260 pthread_mutex_lock (&lock->lock); 261 lock->count++; 262 } 263 264 void 265 gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock) 266 { 267 lock->count--; 268 pthread_mutex_unlock (&lock->lock); 269 } 270 271 int 272 gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock) 273 { 274 if (pthread_mutex_trylock (&lock->lock) == 0) 275 return ++lock->count; 276 return 0; 277 } 278 279 omp_lock_symver (omp_init_lock) 280 omp_lock_symver (omp_destroy_lock) 281 omp_lock_symver (omp_set_lock) 282 omp_lock_symver (omp_unset_lock) 283 omp_lock_symver (omp_test_lock) 284 omp_lock_symver (omp_init_nest_lock) 285 omp_lock_symver (omp_destroy_nest_lock) 286 omp_lock_symver (omp_set_nest_lock) 287 omp_lock_symver (omp_unset_nest_lock) 288 omp_lock_symver (omp_test_nest_lock) 289 290 #else 291 292 ialias (omp_init_lock) 293 ialias (omp_init_nest_lock) 294 ialias (omp_destroy_lock) 295 ialias (omp_destroy_nest_lock) 296 ialias (omp_set_lock) 297 ialias (omp_set_nest_lock) 298 ialias (omp_unset_lock) 299 ialias (omp_unset_nest_lock) 300 ialias (omp_test_lock) 301 ialias (omp_test_nest_lock) 302 303 #endif 304