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