1 /* Copyright (C) 2005-2014 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
gomp_init_lock_30(omp_lock_t * lock)40 gomp_init_lock_30 (omp_lock_t *lock)
41 {
42   pthread_mutex_init (lock, NULL);
43 }
44 
45 void
gomp_destroy_lock_30(omp_lock_t * lock)46 gomp_destroy_lock_30 (omp_lock_t *lock)
47 {
48   pthread_mutex_destroy (lock);
49 }
50 
51 void
gomp_set_lock_30(omp_lock_t * lock)52 gomp_set_lock_30 (omp_lock_t *lock)
53 {
54   pthread_mutex_lock (lock);
55 }
56 
57 void
gomp_unset_lock_30(omp_lock_t * lock)58 gomp_unset_lock_30 (omp_lock_t *lock)
59 {
60   pthread_mutex_unlock (lock);
61 }
62 
63 int
gomp_test_lock_30(omp_lock_t * lock)64 gomp_test_lock_30 (omp_lock_t *lock)
65 {
66   return pthread_mutex_trylock (lock) == 0;
67 }
68 
69 void
gomp_init_nest_lock_30(omp_nest_lock_t * lock)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
gomp_destroy_nest_lock_30(omp_nest_lock_t * lock)78 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock)
79 {
80   pthread_mutex_destroy (&lock->lock);
81 }
82 
83 void
gomp_set_nest_lock_30(omp_nest_lock_t * lock)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
gomp_unset_nest_lock_30(omp_nest_lock_t * lock)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
gomp_test_nest_lock_30(omp_nest_lock_t * lock)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
gomp_init_lock_30(omp_lock_t * lock)124 gomp_init_lock_30 (omp_lock_t *lock)
125 {
126   sem_init (lock, 0, 1);
127 }
128 
129 void
gomp_destroy_lock_30(omp_lock_t * lock)130 gomp_destroy_lock_30 (omp_lock_t *lock)
131 {
132   sem_destroy (lock);
133 }
134 
135 void
gomp_set_lock_30(omp_lock_t * lock)136 gomp_set_lock_30 (omp_lock_t *lock)
137 {
138   while (sem_wait (lock) != 0)
139     ;
140 }
141 
142 void
gomp_unset_lock_30(omp_lock_t * lock)143 gomp_unset_lock_30 (omp_lock_t *lock)
144 {
145   sem_post (lock);
146 }
147 
148 int
gomp_test_lock_30(omp_lock_t * lock)149 gomp_test_lock_30 (omp_lock_t *lock)
150 {
151   return sem_trywait (lock) == 0;
152 }
153 
154 void
gomp_init_nest_lock_30(omp_nest_lock_t * lock)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
gomp_destroy_nest_lock_30(omp_nest_lock_t * lock)163 gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock)
164 {
165   sem_destroy (&lock->lock);
166 }
167 
168 void
gomp_set_nest_lock_30(omp_nest_lock_t * lock)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
gomp_unset_nest_lock_30(omp_nest_lock_t * lock)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
gomp_test_nest_lock_30(omp_nest_lock_t * lock)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
gomp_init_lock_25(omp_lock_25_t * lock)210 gomp_init_lock_25 (omp_lock_25_t *lock)
211 {
212   pthread_mutex_init (lock, NULL);
213 }
214 
215 void
gomp_destroy_lock_25(omp_lock_25_t * lock)216 gomp_destroy_lock_25 (omp_lock_25_t *lock)
217 {
218   pthread_mutex_destroy (lock);
219 }
220 
221 void
gomp_set_lock_25(omp_lock_25_t * lock)222 gomp_set_lock_25 (omp_lock_25_t *lock)
223 {
224   pthread_mutex_lock (lock);
225 }
226 
227 void
gomp_unset_lock_25(omp_lock_25_t * lock)228 gomp_unset_lock_25 (omp_lock_25_t *lock)
229 {
230   pthread_mutex_unlock (lock);
231 }
232 
233 int
gomp_test_lock_25(omp_lock_25_t * lock)234 gomp_test_lock_25 (omp_lock_25_t *lock)
235 {
236   return pthread_mutex_trylock (lock) == 0;
237 }
238 
239 void
gomp_init_nest_lock_25(omp_nest_lock_25_t * lock)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
gomp_destroy_nest_lock_25(omp_nest_lock_25_t * lock)252 gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *lock)
253 {
254   pthread_mutex_destroy (&lock->lock);
255 }
256 
257 void
gomp_set_nest_lock_25(omp_nest_lock_25_t * lock)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
gomp_unset_nest_lock_25(omp_nest_lock_25_t * lock)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
gomp_test_nest_lock_25(omp_nest_lock_25_t * lock)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