1*3ecfeb85Schristos /* $NetBSD: sem.c,v 1.9 2019/02/21 21:33:34 christos Exp $ */
237946878Sthorpej
337946878Sthorpej /*-
468e270a2Sthorpej * Copyright (c) 2003, 2019 The NetBSD Foundation, Inc.
537946878Sthorpej * All rights reserved.
637946878Sthorpej *
737946878Sthorpej * This code is derived from software contributed to The NetBSD Foundation
837946878Sthorpej * by Jason R. Thorpe.
937946878Sthorpej *
1037946878Sthorpej * Redistribution and use in source and binary forms, with or without
1137946878Sthorpej * modification, are permitted provided that the following conditions
1237946878Sthorpej * are met:
1337946878Sthorpej * 1. Redistributions of source code must retain the above copyright
1437946878Sthorpej * notice, this list of conditions and the following disclaimer.
1537946878Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
1637946878Sthorpej * notice, this list of conditions and the following disclaimer in the
1737946878Sthorpej * documentation and/or other materials provided with the distribution.
1837946878Sthorpej *
1937946878Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2037946878Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2137946878Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2237946878Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2337946878Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2437946878Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2537946878Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2637946878Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2737946878Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2837946878Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2937946878Sthorpej * POSSIBILITY OF SUCH DAMAGE.
3037946878Sthorpej */
3137946878Sthorpej
3237946878Sthorpej /*
3337946878Sthorpej * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
3437946878Sthorpej * All rights reserved.
3537946878Sthorpej *
3637946878Sthorpej * Redistribution and use in source and binary forms, with or without
3737946878Sthorpej * modification, are permitted provided that the following conditions
3837946878Sthorpej * are met:
3937946878Sthorpej * 1. Redistributions of source code must retain the above copyright
4037946878Sthorpej * notice(s), this list of conditions and the following disclaimer as
4137946878Sthorpej * the first lines of this file unmodified other than the possible
4237946878Sthorpej * addition of one or more copyright notices.
4337946878Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
4437946878Sthorpej * notice(s), this list of conditions and the following disclaimer in
4537946878Sthorpej * the documentation and/or other materials provided with the
4637946878Sthorpej * distribution.
4737946878Sthorpej *
4837946878Sthorpej * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
4937946878Sthorpej * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5037946878Sthorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5137946878Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
5237946878Sthorpej * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5337946878Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5437946878Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
5537946878Sthorpej * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5637946878Sthorpej * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
5737946878Sthorpej * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
5837946878Sthorpej * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5937946878Sthorpej */
6037946878Sthorpej
61ca2cd8e0Slukem #include <sys/cdefs.h>
62*3ecfeb85Schristos __RCSID("$NetBSD: sem.c,v 1.9 2019/02/21 21:33:34 christos Exp $");
63ca2cd8e0Slukem
6468e270a2Sthorpej #ifndef __LIBPTHREAD_SOURCE__
6537946878Sthorpej /*
6668e270a2Sthorpej * There is no longer any difference between the libpthread and the librt
6768e270a2Sthorpej * versions of sem.c; both are fully kernel-assisted via the _ksem_*()
6868e270a2Sthorpej * system calls. The only difference is the need to lock some internal
6968e270a2Sthorpej * data structures in the pthread version, which could be achieved by
7068e270a2Sthorpej * different means. However, in order to maintain binary compatibility
7168e270a2Sthorpej * with applications that use POSIX semaphores and linked against only
7268e270a2Sthorpej * libpthread, we continue to maintain a copy of the implementation here
7368e270a2Sthorpej * that does not depend on any additional libraries (other than libc).
7437946878Sthorpej */
7537946878Sthorpej #define sem_init _librt_sem_init
7637946878Sthorpej #define sem_destroy _librt_sem_destroy
7737946878Sthorpej #define sem_open _librt_sem_open
7837946878Sthorpej #define sem_close _librt_sem_close
7937946878Sthorpej #define sem_unlink _librt_sem_unlink
8037946878Sthorpej #define sem_wait _librt_sem_wait
814acff4c0Sjoerg #define sem_timedwait _librt_sem_timedwait
8237946878Sthorpej #define sem_trywait _librt_sem_trywait
8337946878Sthorpej #define sem_post _librt_sem_post
8437946878Sthorpej #define sem_getvalue _librt_sem_getvalue
8568e270a2Sthorpej #endif /* ! __LIBPTHREAD_SOURCE__ */
8637946878Sthorpej
8768e270a2Sthorpej #undef _LIBC
8818e73e1eSad #define _LIBC
8937946878Sthorpej
9037946878Sthorpej #include <sys/types.h>
9137946878Sthorpej #include <sys/ksem.h>
9237946878Sthorpej #include <sys/queue.h>
9337946878Sthorpej #include <stdlib.h>
9437946878Sthorpej #include <errno.h>
9537946878Sthorpej #include <fcntl.h>
96*3ecfeb85Schristos #include <stdint.h>
9737946878Sthorpej #include <semaphore.h>
9837946878Sthorpej #include <stdarg.h>
9937946878Sthorpej
10068e270a2Sthorpej #ifdef __LIBPTHREAD_SOURCE__
10168e270a2Sthorpej #include "pthread.h"
10268e270a2Sthorpej #endif /* __LIBPTHREAD_SOURCE__ */
10368e270a2Sthorpej
10468e270a2Sthorpej #define SEM_NAMED 0x4e414d44U /* 'NAMD' */
10568e270a2Sthorpej #define SEM_MAGIC 0x90af0421U
10668e270a2Sthorpej #define SEM_MAGIC_NAMED (SEM_MAGIC ^ SEM_NAMED)
10768e270a2Sthorpej
108*3ecfeb85Schristos #define SEMID_IS_KSEMID(id) (((uint32_t)(id) & KSEM_MARKER_MASK) \
10968e270a2Sthorpej == KSEM_PSHARED_MARKER)
110*3ecfeb85Schristos #define SEM_IS_KSEMID(k) SEMID_IS_KSEMID((intptr_t)(k))
111*3ecfeb85Schristos
11268e270a2Sthorpej
11368e270a2Sthorpej #define SEM_IS_UNNAMED(k) (SEM_IS_KSEMID(k) || \
11468e270a2Sthorpej (k)->ksem_magic == SEM_MAGIC)
11568e270a2Sthorpej
11668e270a2Sthorpej #define SEM_IS_NAMED(k) (!SEM_IS_UNNAMED(k))
11768e270a2Sthorpej
11868e270a2Sthorpej #define SEM_MAGIC_OK(k) (SEM_IS_KSEMID(k) || \
11968e270a2Sthorpej (k)->ksem_magic == SEM_MAGIC || \
12068e270a2Sthorpej (k)->ksem_magic == SEM_MAGIC_NAMED)
12168e270a2Sthorpej
12237946878Sthorpej struct _sem_st {
12337946878Sthorpej unsigned int ksem_magic;
12468e270a2Sthorpej intptr_t ksem_semid;
12537946878Sthorpej
12668e270a2Sthorpej /* Used only to de-dup named semaphores. */
12737946878Sthorpej LIST_ENTRY(_sem_st) ksem_list;
12837946878Sthorpej sem_t *ksem_identity;
12937946878Sthorpej };
13037946878Sthorpej
13137946878Sthorpej static LIST_HEAD(, _sem_st) named_sems = LIST_HEAD_INITIALIZER(&named_sems);
13268e270a2Sthorpej #ifdef __LIBPTHREAD_SOURCE__
13368e270a2Sthorpej static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER;
13437946878Sthorpej
13568e270a2Sthorpej #define LOCK_NAMED_SEMS() pthread_mutex_lock(&named_sems_mtx)
13668e270a2Sthorpej #define UNLOCK_NAMED_SEMS() pthread_mutex_unlock(&named_sems_mtx)
13768e270a2Sthorpej #else /* ! __LIBPTHREAD_SOURCE__ */
13868e270a2Sthorpej #define LOCK_NAMED_SEMS() __nothing
13968e270a2Sthorpej #define UNLOCK_NAMED_SEMS() __nothing
14068e270a2Sthorpej #endif /* __LIBPTHREAD_SOURCE__ */
14168e270a2Sthorpej
14268e270a2Sthorpej #ifndef __LIBPTHREAD_SOURCE__
143758f7fd2Ssimonb #ifdef __weak_alias
__weak_alias(sem_init,_librt_sem_init)14437946878Sthorpej __weak_alias(sem_init,_librt_sem_init)
14537946878Sthorpej __weak_alias(sem_destroy,_librt_sem_destroy)
14637946878Sthorpej __weak_alias(sem_open,_librt_sem_open)
14737946878Sthorpej __weak_alias(sem_close,_librt_sem_close)
14837946878Sthorpej __weak_alias(sem_unlink,_librt_sem_unlink)
14937946878Sthorpej __weak_alias(sem_wait,_librt_sem_wait)
1504acff4c0Sjoerg __weak_alias(sem_timedwait,_librt_sem_timedwait)
15137946878Sthorpej __weak_alias(sem_trywait,_librt_sem_trywait)
15237946878Sthorpej __weak_alias(sem_post,_librt_sem_post)
15337946878Sthorpej __weak_alias(sem_getvalue,_librt_sem_getvalue)
15468e270a2Sthorpej #else
15568e270a2Sthorpej #error Weak aliases required to build POSIX semaphore support.
15668e270a2Sthorpej #endif /* __weak_alias */
15768e270a2Sthorpej #endif /* __LIBPTHREAD_SOURCE__ */
15868e270a2Sthorpej
15968e270a2Sthorpej static inline intptr_t
16068e270a2Sthorpej sem_to_semid(sem_t *sem)
16168e270a2Sthorpej {
16268e270a2Sthorpej
16368e270a2Sthorpej if (SEM_IS_KSEMID(*sem))
16468e270a2Sthorpej return (intptr_t)*sem;
16568e270a2Sthorpej
16668e270a2Sthorpej return (*sem)->ksem_semid;
16768e270a2Sthorpej }
16837946878Sthorpej
16937946878Sthorpej static void
sem_free(sem_t sem)17037946878Sthorpej sem_free(sem_t sem)
17137946878Sthorpej {
17237946878Sthorpej
17337946878Sthorpej sem->ksem_magic = 0;
17437946878Sthorpej free(sem);
17537946878Sthorpej }
17637946878Sthorpej
17737946878Sthorpej static int
sem_alloc(unsigned int value,intptr_t semid,unsigned int magic,sem_t * semp)17868e270a2Sthorpej sem_alloc(unsigned int value, intptr_t semid, unsigned int magic, sem_t *semp)
17937946878Sthorpej {
18037946878Sthorpej sem_t sem;
18137946878Sthorpej
18237946878Sthorpej if (value > SEM_VALUE_MAX)
183*3ecfeb85Schristos return EINVAL;
18437946878Sthorpej
18537946878Sthorpej if ((sem = malloc(sizeof(struct _sem_st))) == NULL)
186*3ecfeb85Schristos return ENOSPC;
18737946878Sthorpej
18868e270a2Sthorpej sem->ksem_magic = magic;
18937946878Sthorpej sem->ksem_semid = semid;
19037946878Sthorpej
19137946878Sthorpej *semp = sem;
192*3ecfeb85Schristos return 0;
19337946878Sthorpej }
19437946878Sthorpej
19537946878Sthorpej /* ARGSUSED */
19637946878Sthorpej int
sem_init(sem_t * sem,int pshared,unsigned int value)19737946878Sthorpej sem_init(sem_t *sem, int pshared, unsigned int value)
19837946878Sthorpej {
19968e270a2Sthorpej intptr_t semid = pshared ? KSEM_PSHARED : 0;
20037946878Sthorpej int error;
20137946878Sthorpej
20237946878Sthorpej if (_ksem_init(value, &semid) == -1)
203*3ecfeb85Schristos return -1;
20437946878Sthorpej
20568e270a2Sthorpej /*
20668e270a2Sthorpej * pshared anonymous semaphores are treated a little differently.
20768e270a2Sthorpej * We don't allocate a sem structure and return a pointer to it.
20868e270a2Sthorpej * That pointer might live in the shared memory segment that's
20968e270a2Sthorpej * shared between processes, but the _sem_st that contains the
21068e270a2Sthorpej * important bits certainly would not be.
21168e270a2Sthorpej *
21268e270a2Sthorpej * So, instead, we return the ksem ID given to us by the kernel.
21368e270a2Sthorpej * The kernel has arranged for the least-significant bit of the
21468e270a2Sthorpej * ksem ID to always be 1 so as to ensure we can always tell
21568e270a2Sthorpej * these IDs apart from the pointers that we vend out for other
21668e270a2Sthorpej * non-pshared semaphores.
21768e270a2Sthorpej */
21868e270a2Sthorpej if (pshared) {
219*3ecfeb85Schristos if (!SEMID_IS_KSEMID(semid)) {
22068e270a2Sthorpej _ksem_destroy(semid);
22168e270a2Sthorpej errno = ENOTSUP;
222*3ecfeb85Schristos return -1;
22368e270a2Sthorpej }
22468e270a2Sthorpej *sem = (sem_t)semid;
225*3ecfeb85Schristos return 0;
22668e270a2Sthorpej }
22768e270a2Sthorpej
22868e270a2Sthorpej if ((error = sem_alloc(value, semid, SEM_MAGIC, sem)) != 0) {
22937946878Sthorpej _ksem_destroy(semid);
23037946878Sthorpej errno = error;
231*3ecfeb85Schristos return -1;
23237946878Sthorpej }
23337946878Sthorpej
234*3ecfeb85Schristos return 0;
23537946878Sthorpej }
23637946878Sthorpej
23737946878Sthorpej int
sem_destroy(sem_t * sem)23837946878Sthorpej sem_destroy(sem_t *sem)
23937946878Sthorpej {
240654395b2Sjoerg int error, save_errno;
24137946878Sthorpej
24237946878Sthorpej #ifdef ERRORCHECK
24368e270a2Sthorpej if (sem == NULL || *sem == NULL || !SEM_MAGIC_OK(*sem)) {
24437946878Sthorpej errno = EINVAL;
245*3ecfeb85Schristos return -1;
24637946878Sthorpej }
24737946878Sthorpej #endif
24837946878Sthorpej
24968e270a2Sthorpej if (SEM_IS_KSEMID(*sem)) {
25068e270a2Sthorpej error = _ksem_destroy((intptr_t)*sem);
25168e270a2Sthorpej } else {
25268e270a2Sthorpej if (SEM_IS_NAMED(*sem)) {
25368e270a2Sthorpej errno = EINVAL;
254*3ecfeb85Schristos return -1;
25568e270a2Sthorpej }
25668e270a2Sthorpej
257654395b2Sjoerg error = _ksem_destroy((*sem)->ksem_semid);
258654395b2Sjoerg save_errno = errno;
25937946878Sthorpej sem_free(*sem);
260*3ecfeb85Schristos if (error == -1)
261654395b2Sjoerg errno = save_errno;
26268e270a2Sthorpej }
26337946878Sthorpej
264654395b2Sjoerg return error;
26537946878Sthorpej }
26637946878Sthorpej
26737946878Sthorpej sem_t *
sem_open(const char * name,int oflag,...)26837946878Sthorpej sem_open(const char *name, int oflag, ...)
26937946878Sthorpej {
27037946878Sthorpej sem_t *sem, s;
27118e73e1eSad intptr_t semid;
27237946878Sthorpej mode_t mode;
27337946878Sthorpej unsigned int value;
27437946878Sthorpej int error;
27537946878Sthorpej va_list ap;
27637946878Sthorpej
27737946878Sthorpej mode = 0;
27837946878Sthorpej value = 0;
27937946878Sthorpej
28037946878Sthorpej if (oflag & O_CREAT) {
28137946878Sthorpej va_start(ap, oflag);
28237946878Sthorpej mode = va_arg(ap, int);
28337946878Sthorpej value = va_arg(ap, unsigned int);
28437946878Sthorpej va_end(ap);
28537946878Sthorpej }
28637946878Sthorpej
28737946878Sthorpej /*
28837946878Sthorpej * We can be lazy and let the kernel handle the oflag,
28937946878Sthorpej * we'll just merge duplicate IDs into our list.
29037946878Sthorpej */
29137946878Sthorpej if (_ksem_open(name, oflag, mode, value, &semid) == -1)
292*3ecfeb85Schristos return SEM_FAILED;
29337946878Sthorpej
29437946878Sthorpej /*
29537946878Sthorpej * Search for a duplicate ID, we must return the same sem_t *
29637946878Sthorpej * if we locate one.
29737946878Sthorpej */
29868e270a2Sthorpej LOCK_NAMED_SEMS();
29937946878Sthorpej LIST_FOREACH(s, &named_sems, ksem_list) {
30068e270a2Sthorpej if (s->ksem_semid == semid) {
30168e270a2Sthorpej UNLOCK_NAMED_SEMS();
302*3ecfeb85Schristos return s->ksem_identity;
30337946878Sthorpej }
30468e270a2Sthorpej }
30537946878Sthorpej
30637946878Sthorpej if ((sem = malloc(sizeof(*sem))) == NULL) {
30737946878Sthorpej error = ENOSPC;
30837946878Sthorpej goto bad;
30937946878Sthorpej }
31068e270a2Sthorpej if ((error = sem_alloc(value, semid, SEM_MAGIC_NAMED, sem)) != 0)
31137946878Sthorpej goto bad;
31237946878Sthorpej
31337946878Sthorpej LIST_INSERT_HEAD(&named_sems, *sem, ksem_list);
31468e270a2Sthorpej UNLOCK_NAMED_SEMS();
31537946878Sthorpej (*sem)->ksem_identity = sem;
31637946878Sthorpej
317*3ecfeb85Schristos return sem;
31837946878Sthorpej
31937946878Sthorpej bad:
32068e270a2Sthorpej UNLOCK_NAMED_SEMS();
32137946878Sthorpej _ksem_close(semid);
32237946878Sthorpej if (sem != NULL) {
32337946878Sthorpej if (*sem != NULL)
32437946878Sthorpej sem_free(*sem);
32537946878Sthorpej free(sem);
32637946878Sthorpej }
32737946878Sthorpej errno = error;
328*3ecfeb85Schristos return SEM_FAILED;
32937946878Sthorpej }
33037946878Sthorpej
33137946878Sthorpej int
sem_close(sem_t * sem)33237946878Sthorpej sem_close(sem_t *sem)
33337946878Sthorpej {
334654395b2Sjoerg int error, save_errno;
33537946878Sthorpej
33637946878Sthorpej #ifdef ERRORCHECK
33768e270a2Sthorpej if (sem == NULL || *sem == NULL || !SEM_MAGIC_OK(*sem)) {
33837946878Sthorpej errno = EINVAL;
339*3ecfeb85Schristos return -1;
34037946878Sthorpej }
34137946878Sthorpej #endif
34237946878Sthorpej
34368e270a2Sthorpej if (!SEM_IS_NAMED(*sem)) {
34468e270a2Sthorpej errno = EINVAL;
345*3ecfeb85Schristos return -1;
34668e270a2Sthorpej }
34737946878Sthorpej
34868e270a2Sthorpej LOCK_NAMED_SEMS();
34968e270a2Sthorpej error = _ksem_close((*sem)->ksem_semid);
35037946878Sthorpej LIST_REMOVE((*sem), ksem_list);
351654395b2Sjoerg save_errno = errno;
35268e270a2Sthorpej UNLOCK_NAMED_SEMS();
35337946878Sthorpej sem_free(*sem);
35437946878Sthorpej free(sem);
355*3ecfeb85Schristos if (error == -1)
356654395b2Sjoerg errno = save_errno;
357654395b2Sjoerg return error;
35837946878Sthorpej }
35937946878Sthorpej
36037946878Sthorpej int
sem_unlink(const char * name)36137946878Sthorpej sem_unlink(const char *name)
36237946878Sthorpej {
36337946878Sthorpej
364*3ecfeb85Schristos return _ksem_unlink(name);
36537946878Sthorpej }
36637946878Sthorpej
36737946878Sthorpej int
sem_wait(sem_t * sem)36837946878Sthorpej sem_wait(sem_t *sem)
36937946878Sthorpej {
37037946878Sthorpej
37137946878Sthorpej #ifdef ERRORCHECK
37268e270a2Sthorpej if (sem == NULL || *sem == NULL || !SEM_MAGIC_OK(*sem)) {
37337946878Sthorpej errno = EINVAL;
374*3ecfeb85Schristos return -1;
37537946878Sthorpej }
37637946878Sthorpej #endif
37737946878Sthorpej
378*3ecfeb85Schristos return _ksem_wait(sem_to_semid(sem));
37937946878Sthorpej }
38037946878Sthorpej
38137946878Sthorpej int
sem_timedwait(sem_t * sem,const struct timespec * __restrict abstime)3824acff4c0Sjoerg sem_timedwait(sem_t *sem, const struct timespec * __restrict abstime)
3834acff4c0Sjoerg {
3844acff4c0Sjoerg
3854acff4c0Sjoerg #ifdef ERRORCHECK
38668e270a2Sthorpej if (sem == NULL || *sem == NULL || !SEM_MAGIC_OK(*sem)) {
3874acff4c0Sjoerg errno = EINVAL;
388*3ecfeb85Schristos return -1;
3894acff4c0Sjoerg }
3904acff4c0Sjoerg #endif
3914acff4c0Sjoerg
392*3ecfeb85Schristos return _ksem_timedwait(sem_to_semid(sem), abstime);
3934acff4c0Sjoerg }
3944acff4c0Sjoerg
3954acff4c0Sjoerg int
sem_trywait(sem_t * sem)39637946878Sthorpej sem_trywait(sem_t *sem)
39737946878Sthorpej {
39837946878Sthorpej
39937946878Sthorpej #ifdef ERRORCHECK
40068e270a2Sthorpej if (sem == NULL || *sem == NULL || !SEM_MAGIC_OK(*sem)) {
40137946878Sthorpej errno = EINVAL;
402*3ecfeb85Schristos return -1;
40337946878Sthorpej }
40437946878Sthorpej #endif
40537946878Sthorpej
406*3ecfeb85Schristos return _ksem_trywait(sem_to_semid(sem));
40737946878Sthorpej }
40837946878Sthorpej
40937946878Sthorpej int
sem_post(sem_t * sem)41037946878Sthorpej sem_post(sem_t *sem)
41137946878Sthorpej {
41237946878Sthorpej
41337946878Sthorpej #ifdef ERRORCHECK
41468e270a2Sthorpej if (sem == NULL || *sem == NULL || !SEM_MAGIC_OK(*sem)) {
41537946878Sthorpej errno = EINVAL;
416*3ecfeb85Schristos return -1;
41737946878Sthorpej }
41837946878Sthorpej #endif
41937946878Sthorpej
420*3ecfeb85Schristos return _ksem_post(sem_to_semid(sem));
42137946878Sthorpej }
42237946878Sthorpej
42337946878Sthorpej int
sem_getvalue(sem_t * __restrict sem,int * __restrict sval)42437946878Sthorpej sem_getvalue(sem_t * __restrict sem, int * __restrict sval)
42537946878Sthorpej {
42637946878Sthorpej
42737946878Sthorpej #ifdef ERRORCHECK
42868e270a2Sthorpej if (sem == NULL || *sem == NULL || !SEM_MAGIC_OK(*sem)) {
42937946878Sthorpej errno = EINVAL;
430*3ecfeb85Schristos return -1;
43137946878Sthorpej }
43237946878Sthorpej #endif
43368e270a2Sthorpej
434*3ecfeb85Schristos return _ksem_getvalue(sem_to_semid(sem), sval);
43537946878Sthorpej }
436