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