xref: /freebsd/lib/libc/gen/sem.c (revision b6897522fadfcea200575c93e52f7b66f860d9cc)
1bf4dc877SAlfred Perlstein /*
2bf4dc877SAlfred Perlstein  * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
3bf4dc877SAlfred Perlstein  * All rights reserved.
4bf4dc877SAlfred Perlstein  *
5bf4dc877SAlfred Perlstein  * Redistribution and use in source and binary forms, with or without
6bf4dc877SAlfred Perlstein  * modification, are permitted provided that the following conditions
7bf4dc877SAlfred Perlstein  * are met:
8bf4dc877SAlfred Perlstein  * 1. Redistributions of source code must retain the above copyright
9bf4dc877SAlfred Perlstein  *    notice(s), this list of conditions and the following disclaimer as
10bf4dc877SAlfred Perlstein  *    the first lines of this file unmodified other than the possible
11bf4dc877SAlfred Perlstein  *    addition of one or more copyright notices.
12bf4dc877SAlfred Perlstein  * 2. Redistributions in binary form must reproduce the above copyright
13bf4dc877SAlfred Perlstein  *    notice(s), this list of conditions and the following disclaimer in
14bf4dc877SAlfred Perlstein  *    the documentation and/or other materials provided with the
15bf4dc877SAlfred Perlstein  *    distribution.
16bf4dc877SAlfred Perlstein  *
17bf4dc877SAlfred Perlstein  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
18bf4dc877SAlfred Perlstein  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19bf4dc877SAlfred Perlstein  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20bf4dc877SAlfred Perlstein  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
21bf4dc877SAlfred Perlstein  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22bf4dc877SAlfred Perlstein  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23bf4dc877SAlfred Perlstein  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24bf4dc877SAlfred Perlstein  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25bf4dc877SAlfred Perlstein  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26bf4dc877SAlfred Perlstein  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27bf4dc877SAlfred Perlstein  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28bf4dc877SAlfred Perlstein  *
29bf4dc877SAlfred Perlstein  * $FreeBSD$
30bf4dc877SAlfred Perlstein  */
31bf4dc877SAlfred Perlstein 
32e0554a53SJacques Vidrine #include "namespace.h"
33bf4dc877SAlfred Perlstein #include <stdlib.h>
34bf4dc877SAlfred Perlstein #include <errno.h>
35bf4dc877SAlfred Perlstein #include <fcntl.h>
36bf4dc877SAlfred Perlstein #include <semaphore.h>
37bf4dc877SAlfred Perlstein #include <stdarg.h>
38bf4dc877SAlfred Perlstein #include <pthread.h>
39bf4dc877SAlfred Perlstein #include <sys/queue.h>
40bf4dc877SAlfred Perlstein #include <_semaphore.h>
41e0554a53SJacques Vidrine #include "un-namespace.h"
42bf4dc877SAlfred Perlstein 
43bf4dc877SAlfred Perlstein #define _SEM_CHECK_VALIDITY(sem)		\
44bf4dc877SAlfred Perlstein 	if ((*(sem))->magic != SEM_MAGIC) {	\
45bf4dc877SAlfred Perlstein 		errno = EINVAL;			\
46bf4dc877SAlfred Perlstein 		retval = -1;			\
47bf4dc877SAlfred Perlstein 		goto RETURN;			\
48bf4dc877SAlfred Perlstein 	}
49bf4dc877SAlfred Perlstein 
50bf4dc877SAlfred Perlstein static sem_t sem_alloc(unsigned int value, semid_t semid, int system_sem);
51bf4dc877SAlfred Perlstein static void sem_free(sem_t sem);
52bf4dc877SAlfred Perlstein 
53bf4dc877SAlfred Perlstein static LIST_HEAD(, sem) named_sems = LIST_HEAD_INITIALIZER(&named_sems);
54bf4dc877SAlfred Perlstein static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER;
55bf4dc877SAlfred Perlstein 
56bf4dc877SAlfred Perlstein static void
57bf4dc877SAlfred Perlstein sem_free(sem_t sem)
58bf4dc877SAlfred Perlstein {
59bf4dc877SAlfred Perlstein 
60bf4dc877SAlfred Perlstein 	_pthread_mutex_destroy(&sem->lock);
61bf4dc877SAlfred Perlstein 	_pthread_cond_destroy(&sem->gtzero);
62bf4dc877SAlfred Perlstein 	sem->magic = 0;
63bf4dc877SAlfred Perlstein 	free(sem);
64bf4dc877SAlfred Perlstein }
65bf4dc877SAlfred Perlstein 
66bf4dc877SAlfred Perlstein static sem_t
67bf4dc877SAlfred Perlstein sem_alloc(unsigned int value, semid_t semid, int system_sem)
68bf4dc877SAlfred Perlstein {
69bf4dc877SAlfred Perlstein 	sem_t sem;
70bf4dc877SAlfred Perlstein 
71bf4dc877SAlfred Perlstein 	if (value > SEM_VALUE_MAX) {
72bf4dc877SAlfred Perlstein 		errno = EINVAL;
73bf4dc877SAlfred Perlstein 		return (NULL);
74bf4dc877SAlfred Perlstein 	}
75bf4dc877SAlfred Perlstein 
76bf4dc877SAlfred Perlstein 	sem = (sem_t)malloc(sizeof(struct sem));
77bf4dc877SAlfred Perlstein 	if (sem == NULL) {
78bf4dc877SAlfred Perlstein 		errno = ENOSPC;
79bf4dc877SAlfred Perlstein 		return (NULL);
80bf4dc877SAlfred Perlstein 	}
81bf4dc877SAlfred Perlstein 
82bf4dc877SAlfred Perlstein 	/*
83bf4dc877SAlfred Perlstein 	 * Initialize the semaphore.
84bf4dc877SAlfred Perlstein 	 */
85bf4dc877SAlfred Perlstein 	if (_pthread_mutex_init(&sem->lock, NULL) != 0) {
86bf4dc877SAlfred Perlstein 		free(sem);
87bf4dc877SAlfred Perlstein 		errno = ENOSPC;
88bf4dc877SAlfred Perlstein 		return (NULL);
89bf4dc877SAlfred Perlstein 	}
90bf4dc877SAlfred Perlstein 
91bf4dc877SAlfred Perlstein 	if (_pthread_cond_init(&sem->gtzero, NULL) != 0) {
92bf4dc877SAlfred Perlstein 		_pthread_mutex_destroy(&sem->lock);
93bf4dc877SAlfred Perlstein 		free(sem);
94bf4dc877SAlfred Perlstein 		errno = ENOSPC;
95bf4dc877SAlfred Perlstein 		return (NULL);
96bf4dc877SAlfred Perlstein 	}
97bf4dc877SAlfred Perlstein 
98bf4dc877SAlfred Perlstein 	sem->count = (u_int32_t)value;
99bf4dc877SAlfred Perlstein 	sem->nwaiters = 0;
100bf4dc877SAlfred Perlstein 	sem->magic = SEM_MAGIC;
101bf4dc877SAlfred Perlstein 	sem->semid = semid;
102bf4dc877SAlfred Perlstein 	sem->syssem = system_sem;
103bf4dc877SAlfred Perlstein 	return (sem);
104bf4dc877SAlfred Perlstein }
105bf4dc877SAlfred Perlstein 
106bf4dc877SAlfred Perlstein int
107bf4dc877SAlfred Perlstein sem_init(sem_t *sem, int pshared, unsigned int value)
108bf4dc877SAlfred Perlstein {
109bf4dc877SAlfred Perlstein 	int	retval, got_system_sem;
110bf4dc877SAlfred Perlstein 	semid_t	semid;
111bf4dc877SAlfred Perlstein 
112bf4dc877SAlfred Perlstein 	got_system_sem = 0;
113bf4dc877SAlfred Perlstein 	semid = SEM_USER;
114bf4dc877SAlfred Perlstein 	/*
115bf4dc877SAlfred Perlstein 	 * Range check the arguments.
116bf4dc877SAlfred Perlstein 	 */
117bf4dc877SAlfred Perlstein 	if (pshared != 0) {
118bf4dc877SAlfred Perlstein 		retval = ksem_init(&semid, value);
119bf4dc877SAlfred Perlstein 		if (retval == -1)
120bf4dc877SAlfred Perlstein 			goto RETURN;
121bf4dc877SAlfred Perlstein 		got_system_sem = 1;
122bf4dc877SAlfred Perlstein 	}
123bf4dc877SAlfred Perlstein 
124bf4dc877SAlfred Perlstein 	(*sem) = sem_alloc(value, semid, got_system_sem);
125bf4dc877SAlfred Perlstein 	if ((*sem) == NULL)
126bf4dc877SAlfred Perlstein 		retval = -1;
127bf4dc877SAlfred Perlstein 	else
128bf4dc877SAlfred Perlstein 		retval = 0;
129bf4dc877SAlfred Perlstein   RETURN:
130bf4dc877SAlfred Perlstein 	if (retval != 0 && got_system_sem)
131bf4dc877SAlfred Perlstein 		ksem_destroy(semid);
132bf4dc877SAlfred Perlstein 	return retval;
133bf4dc877SAlfred Perlstein }
134bf4dc877SAlfred Perlstein 
135bf4dc877SAlfred Perlstein int
136bf4dc877SAlfred Perlstein sem_destroy(sem_t *sem)
137bf4dc877SAlfred Perlstein {
138bf4dc877SAlfred Perlstein 	int	retval;
139bf4dc877SAlfred Perlstein 
140bf4dc877SAlfred Perlstein 	_SEM_CHECK_VALIDITY(sem);
141bf4dc877SAlfred Perlstein 
142bf4dc877SAlfred Perlstein 	_pthread_mutex_lock(&(*sem)->lock);
143bf4dc877SAlfred Perlstein 	/*
144bf4dc877SAlfred Perlstein 	 * If this is a system semaphore let the kernel track it otherwise
145bf4dc877SAlfred Perlstein 	 * make sure there are no waiters.
146bf4dc877SAlfred Perlstein 	 */
147bf4dc877SAlfred Perlstein 	if ((*sem)->syssem != 0) {
148bf4dc877SAlfred Perlstein 		retval = ksem_destroy((*sem)->semid);
149bf4dc877SAlfred Perlstein 		if (retval == -1) {
150bf4dc877SAlfred Perlstein 			_pthread_mutex_unlock(&(*sem)->lock);
151bf4dc877SAlfred Perlstein 			goto RETURN;
152bf4dc877SAlfred Perlstein 		}
153bf4dc877SAlfred Perlstein 	} else if ((*sem)->nwaiters > 0) {
154bf4dc877SAlfred Perlstein 		_pthread_mutex_unlock(&(*sem)->lock);
155bf4dc877SAlfred Perlstein 		errno = EBUSY;
156bf4dc877SAlfred Perlstein 		retval = -1;
157bf4dc877SAlfred Perlstein 		goto RETURN;
158bf4dc877SAlfred Perlstein 	}
159bf4dc877SAlfred Perlstein 	_pthread_mutex_unlock(&(*sem)->lock);
160bf4dc877SAlfred Perlstein 
161bf4dc877SAlfred Perlstein 	sem_free(*sem);
162bf4dc877SAlfred Perlstein 
163bf4dc877SAlfred Perlstein 	retval = 0;
164bf4dc877SAlfred Perlstein   RETURN:
165bf4dc877SAlfred Perlstein 	return retval;
166bf4dc877SAlfred Perlstein }
167bf4dc877SAlfred Perlstein 
168bf4dc877SAlfred Perlstein sem_t *
169bf4dc877SAlfred Perlstein sem_open(const char *name, int oflag, ...)
170bf4dc877SAlfred Perlstein {
171bf4dc877SAlfred Perlstein 	sem_t *sem;
172bf4dc877SAlfred Perlstein 	sem_t s;
173bf4dc877SAlfred Perlstein 	semid_t semid;
174bf4dc877SAlfred Perlstein 	mode_t mode;
175bf4dc877SAlfred Perlstein 	unsigned int value;
176bf4dc877SAlfred Perlstein 
177bf4dc877SAlfred Perlstein 	mode = 0;
178bf4dc877SAlfred Perlstein 	value = 0;
179bf4dc877SAlfred Perlstein 
180bf4dc877SAlfred Perlstein 	if ((oflag & O_CREAT) != 0) {
181bf4dc877SAlfred Perlstein 		va_list ap;
182bf4dc877SAlfred Perlstein 
183bf4dc877SAlfred Perlstein 		va_start(ap, oflag);
184bf4dc877SAlfred Perlstein 		mode = va_arg(ap, int);
185bf4dc877SAlfred Perlstein 		value = va_arg(ap, unsigned int);
186bf4dc877SAlfred Perlstein 		va_end(ap);
187bf4dc877SAlfred Perlstein 	}
188bf4dc877SAlfred Perlstein 	/*
189bf4dc877SAlfred Perlstein 	 * we can be lazy and let the kernel handle the "oflag",
190bf4dc877SAlfred Perlstein 	 * we'll just merge duplicate IDs into our list.
191bf4dc877SAlfred Perlstein 	 */
192bf4dc877SAlfred Perlstein 	if (ksem_open(&semid, name, oflag, mode, value) == -1)
193bf4dc877SAlfred Perlstein 		return (SEM_FAILED);
194bf4dc877SAlfred Perlstein 	/*
195bf4dc877SAlfred Perlstein 	 * search for a duplicate ID, we must return the same sem_t *
196bf4dc877SAlfred Perlstein 	 * if we locate one.
197bf4dc877SAlfred Perlstein 	 */
198bf4dc877SAlfred Perlstein 	_pthread_mutex_lock(&named_sems_mtx);
199bf4dc877SAlfred Perlstein 	LIST_FOREACH(s, &named_sems, entry) {
200bf4dc877SAlfred Perlstein 	    if (s->semid == semid) {
201bf4dc877SAlfred Perlstein 		    _pthread_mutex_unlock(&named_sems_mtx);
202bf4dc877SAlfred Perlstein 		    return (s->backpointer);
203bf4dc877SAlfred Perlstein 	    }
204bf4dc877SAlfred Perlstein 	}
205bf4dc877SAlfred Perlstein 	sem = (sem_t *)malloc(sizeof(*sem));
206bf4dc877SAlfred Perlstein 	if (sem == NULL)
207bf4dc877SAlfred Perlstein 		goto err;
208bf4dc877SAlfred Perlstein 	*sem = sem_alloc(value, semid, 1);
209bf4dc877SAlfred Perlstein 	if ((*sem) == NULL)
210bf4dc877SAlfred Perlstein 		goto err;
211a91b25dcSTim J. Robbins 	LIST_INSERT_HEAD(&named_sems, *sem, entry);
212bf4dc877SAlfred Perlstein 	(*sem)->backpointer = sem;
213a91b25dcSTim J. Robbins 	_pthread_mutex_unlock(&named_sems_mtx);
214bf4dc877SAlfred Perlstein 	return (sem);
215bf4dc877SAlfred Perlstein err:
216bf4dc877SAlfred Perlstein 	_pthread_mutex_unlock(&named_sems_mtx);
217bf4dc877SAlfred Perlstein 	ksem_close(semid);
218bf4dc877SAlfred Perlstein 	if (sem != NULL) {
219bf4dc877SAlfred Perlstein 		if (*sem != NULL)
220bf4dc877SAlfred Perlstein 			sem_free(*sem);
221bf4dc877SAlfred Perlstein 		else
222bf4dc877SAlfred Perlstein 			errno = ENOSPC;
223bf4dc877SAlfred Perlstein 		free(sem);
224bf4dc877SAlfred Perlstein 	} else {
225bf4dc877SAlfred Perlstein 		errno = ENOSPC;
226bf4dc877SAlfred Perlstein 	}
227bf4dc877SAlfred Perlstein 	return (SEM_FAILED);
228bf4dc877SAlfred Perlstein }
229bf4dc877SAlfred Perlstein 
230bf4dc877SAlfred Perlstein int
231bf4dc877SAlfred Perlstein sem_close(sem_t *sem)
232bf4dc877SAlfred Perlstein {
233bf4dc877SAlfred Perlstein 
234bf4dc877SAlfred Perlstein 	if ((*sem)->syssem == 0) {
235bf4dc877SAlfred Perlstein 		errno = EINVAL;
236bf4dc877SAlfred Perlstein 		return (-1);
237bf4dc877SAlfred Perlstein 	}
238bf4dc877SAlfred Perlstein 	_pthread_mutex_lock(&named_sems_mtx);
239bf4dc877SAlfred Perlstein 	if (ksem_close((*sem)->semid) == -1) {
240bf4dc877SAlfred Perlstein 		_pthread_mutex_unlock(&named_sems_mtx);
241bf4dc877SAlfred Perlstein 		return (-1);
242bf4dc877SAlfred Perlstein 	}
243bf4dc877SAlfred Perlstein 	LIST_REMOVE((*sem), entry);
244bf4dc877SAlfred Perlstein 	_pthread_mutex_unlock(&named_sems_mtx);
245bf4dc877SAlfred Perlstein 	sem_free(*sem);
246bf4dc877SAlfred Perlstein 	free(sem);
247bf4dc877SAlfred Perlstein 	return (0);
248bf4dc877SAlfred Perlstein }
249bf4dc877SAlfred Perlstein 
250bf4dc877SAlfred Perlstein int
251bf4dc877SAlfred Perlstein sem_unlink(const char *name)
252bf4dc877SAlfred Perlstein {
253bf4dc877SAlfred Perlstein 
254bf4dc877SAlfred Perlstein 	return (ksem_unlink(name));
255bf4dc877SAlfred Perlstein }
256bf4dc877SAlfred Perlstein 
257b6897522SDavid Xu int
258bf4dc877SAlfred Perlstein sem_wait(sem_t *sem)
259bf4dc877SAlfred Perlstein {
260bf4dc877SAlfred Perlstein 	int	retval;
261bf4dc877SAlfred Perlstein 
262bf4dc877SAlfred Perlstein 	_SEM_CHECK_VALIDITY(sem);
263bf4dc877SAlfred Perlstein 
264bf4dc877SAlfred Perlstein 	if ((*sem)->syssem != 0) {
265bf4dc877SAlfred Perlstein 		retval = ksem_wait((*sem)->semid);
266bf4dc877SAlfred Perlstein 		goto RETURN;
267bf4dc877SAlfred Perlstein 	}
268bf4dc877SAlfred Perlstein 
269bf4dc877SAlfred Perlstein 	_pthread_mutex_lock(&(*sem)->lock);
270bf4dc877SAlfred Perlstein 
271bf4dc877SAlfred Perlstein 	while ((*sem)->count == 0) {
272bf4dc877SAlfred Perlstein 		(*sem)->nwaiters++;
273b6897522SDavid Xu 		_pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
274bf4dc877SAlfred Perlstein 		(*sem)->nwaiters--;
275bf4dc877SAlfred Perlstein 	}
276bf4dc877SAlfred Perlstein 	(*sem)->count--;
277bf4dc877SAlfred Perlstein 
278bf4dc877SAlfred Perlstein 	_pthread_mutex_unlock(&(*sem)->lock);
279bf4dc877SAlfred Perlstein 
280bf4dc877SAlfred Perlstein 	retval = 0;
281bf4dc877SAlfred Perlstein   RETURN:
282bf4dc877SAlfred Perlstein 	return retval;
283bf4dc877SAlfred Perlstein }
284bf4dc877SAlfred Perlstein 
285bf4dc877SAlfred Perlstein int
286bf4dc877SAlfred Perlstein sem_trywait(sem_t *sem)
287bf4dc877SAlfred Perlstein {
288bf4dc877SAlfred Perlstein 	int	retval;
289bf4dc877SAlfred Perlstein 
290bf4dc877SAlfred Perlstein 	_SEM_CHECK_VALIDITY(sem);
291bf4dc877SAlfred Perlstein 
292bf4dc877SAlfred Perlstein 	if ((*sem)->syssem != 0) {
293bf4dc877SAlfred Perlstein 		retval = ksem_trywait((*sem)->semid);
294bf4dc877SAlfred Perlstein 		goto RETURN;
295bf4dc877SAlfred Perlstein 	}
296bf4dc877SAlfred Perlstein 
297bf4dc877SAlfred Perlstein 	_pthread_mutex_lock(&(*sem)->lock);
298bf4dc877SAlfred Perlstein 
299bf4dc877SAlfred Perlstein 	if ((*sem)->count > 0) {
300bf4dc877SAlfred Perlstein 		(*sem)->count--;
301bf4dc877SAlfred Perlstein 		retval = 0;
302bf4dc877SAlfred Perlstein 	} else {
303bf4dc877SAlfred Perlstein 		errno = EAGAIN;
304bf4dc877SAlfred Perlstein 		retval = -1;
305bf4dc877SAlfred Perlstein 	}
306bf4dc877SAlfred Perlstein 
307bf4dc877SAlfred Perlstein 	_pthread_mutex_unlock(&(*sem)->lock);
308bf4dc877SAlfred Perlstein 
309bf4dc877SAlfred Perlstein   RETURN:
310bf4dc877SAlfred Perlstein 	return retval;
311bf4dc877SAlfred Perlstein }
312bf4dc877SAlfred Perlstein 
313bf4dc877SAlfred Perlstein int
314bf4dc877SAlfred Perlstein sem_post(sem_t *sem)
315bf4dc877SAlfred Perlstein {
316bf4dc877SAlfred Perlstein 	int	retval;
317bf4dc877SAlfred Perlstein 
318bf4dc877SAlfred Perlstein 	_SEM_CHECK_VALIDITY(sem);
319bf4dc877SAlfred Perlstein 
320bf4dc877SAlfred Perlstein 	if ((*sem)->syssem != 0) {
321bf4dc877SAlfred Perlstein 		retval = ksem_post((*sem)->semid);
322bf4dc877SAlfred Perlstein 		goto RETURN;
323bf4dc877SAlfred Perlstein 	}
324bf4dc877SAlfred Perlstein 
325bf4dc877SAlfred Perlstein 	_pthread_mutex_lock(&(*sem)->lock);
326bf4dc877SAlfred Perlstein 
327bf4dc877SAlfred Perlstein 	(*sem)->count++;
328bf4dc877SAlfred Perlstein 	if ((*sem)->nwaiters > 0)
329bf4dc877SAlfred Perlstein 		_pthread_cond_signal(&(*sem)->gtzero);
330bf4dc877SAlfred Perlstein 
331bf4dc877SAlfred Perlstein 	_pthread_mutex_unlock(&(*sem)->lock);
332bf4dc877SAlfred Perlstein 
333bf4dc877SAlfred Perlstein 	retval = 0;
334bf4dc877SAlfred Perlstein   RETURN:
335bf4dc877SAlfred Perlstein 	return retval;
336bf4dc877SAlfred Perlstein }
337bf4dc877SAlfred Perlstein 
338bf4dc877SAlfred Perlstein int
339ddb4fb5bSMike Barcroft sem_getvalue(sem_t * __restrict sem, int * __restrict sval)
340bf4dc877SAlfred Perlstein {
341bf4dc877SAlfred Perlstein 	int	retval;
342bf4dc877SAlfred Perlstein 
343bf4dc877SAlfred Perlstein 	_SEM_CHECK_VALIDITY(sem);
344bf4dc877SAlfred Perlstein 
345bf4dc877SAlfred Perlstein 	if ((*sem)->syssem != 0) {
346bf4dc877SAlfred Perlstein 		retval = ksem_getvalue((*sem)->semid, sval);
347bf4dc877SAlfred Perlstein 		goto RETURN;
348bf4dc877SAlfred Perlstein 	}
349bf4dc877SAlfred Perlstein 
350bf4dc877SAlfred Perlstein 	_pthread_mutex_lock(&(*sem)->lock);
351bf4dc877SAlfred Perlstein 	*sval = (int)(*sem)->count;
352bf4dc877SAlfred Perlstein 	_pthread_mutex_unlock(&(*sem)->lock);
353bf4dc877SAlfred Perlstein 
354bf4dc877SAlfred Perlstein 	retval = 0;
355bf4dc877SAlfred Perlstein   RETURN:
356bf4dc877SAlfred Perlstein 	return retval;
357bf4dc877SAlfred Perlstein }
358