1/* Copyright (C) 2005-2015 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
41void
42gomp_init_lock_30 (omp_lock_t *lock)
43{
44  pthread_mutex_init (lock, NULL);
45}
46
47void
48gomp_destroy_lock_30 (omp_lock_t *lock)
49{
50  pthread_mutex_destroy (lock);
51}
52
53void
54gomp_set_lock_30 (omp_lock_t *lock)
55{
56  pthread_mutex_lock (lock);
57}
58
59void
60gomp_unset_lock_30 (omp_lock_t *lock)
61{
62  pthread_mutex_unlock (lock);
63}
64
65int
66gomp_test_lock_30 (omp_lock_t *lock)
67{
68  return pthread_mutex_trylock (lock) == 0;
69}
70
71void
72gomp_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
79void
80gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock)
81{
82  pthread_mutex_destroy (&lock->lock);
83}
84
85void
86gomp_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
98void
99gomp_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
108int
109gomp_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
125void
126gomp_init_lock_30 (omp_lock_t *lock)
127{
128  sem_init (lock, 0, 1);
129}
130
131void
132gomp_destroy_lock_30 (omp_lock_t *lock)
133{
134  sem_destroy (lock);
135}
136
137void
138gomp_set_lock_30 (omp_lock_t *lock)
139{
140  while (sem_wait (lock) != 0)
141    ;
142}
143
144void
145gomp_unset_lock_30 (omp_lock_t *lock)
146{
147  sem_post (lock);
148}
149
150int
151gomp_test_lock_30 (omp_lock_t *lock)
152{
153  return sem_trywait (lock) == 0;
154}
155
156void
157gomp_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
164void
165gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock)
166{
167  sem_destroy (&lock->lock);
168}
169
170void
171gomp_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
184void
185gomp_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
194int
195gomp_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
211void
212gomp_init_lock_25 (omp_lock_25_t *lock)
213{
214  pthread_mutex_init (lock, NULL);
215}
216
217void
218gomp_destroy_lock_25 (omp_lock_25_t *lock)
219{
220  pthread_mutex_destroy (lock);
221}
222
223void
224gomp_set_lock_25 (omp_lock_25_t *lock)
225{
226  pthread_mutex_lock (lock);
227}
228
229void
230gomp_unset_lock_25 (omp_lock_25_t *lock)
231{
232  pthread_mutex_unlock (lock);
233}
234
235int
236gomp_test_lock_25 (omp_lock_25_t *lock)
237{
238  return pthread_mutex_trylock (lock) == 0;
239}
240
241void
242gomp_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
253void
254gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *lock)
255{
256  pthread_mutex_destroy (&lock->lock);
257}
258
259void
260gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock)
261{
262  pthread_mutex_lock (&lock->lock);
263  lock->count++;
264}
265
266void
267gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock)
268{
269  lock->count--;
270  pthread_mutex_unlock (&lock->lock);
271}
272
273int
274gomp_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
281omp_lock_symver (omp_init_lock)
282omp_lock_symver (omp_destroy_lock)
283omp_lock_symver (omp_set_lock)
284omp_lock_symver (omp_unset_lock)
285omp_lock_symver (omp_test_lock)
286omp_lock_symver (omp_init_nest_lock)
287omp_lock_symver (omp_destroy_nest_lock)
288omp_lock_symver (omp_set_nest_lock)
289omp_lock_symver (omp_unset_nest_lock)
290omp_lock_symver (omp_test_nest_lock)
291
292#else
293
294ialias (omp_init_lock)
295ialias (omp_init_nest_lock)
296ialias (omp_destroy_lock)
297ialias (omp_destroy_nest_lock)
298ialias (omp_set_lock)
299ialias (omp_set_nest_lock)
300ialias (omp_unset_lock)
301ialias (omp_unset_nest_lock)
302ialias (omp_test_lock)
303ialias (omp_test_nest_lock)
304
305#endif
306