1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
14  */
15 
16 /*
17  * semaphore(9f)
18  */
19 
20 /* This is the API we're emulating */
21 #include <sys/semaphore.h>
22 
23 #include <sys/errno.h>
24 #include <sys/debug.h>
25 
26 /* <synch.h> */
27 int	_lwp_sema_init(lwp_sema_t *, int);
28 int	_lwp_sema_wait(lwp_sema_t *);
29 int	_lwp_sema_trywait(lwp_sema_t *);
30 int	_lwp_sema_post(lwp_sema_t *);
31 
32 
33 /* ARGSUSED */
34 void
ksema_init(ksema_t * sem,uint32_t val,char * name,ksema_type_t st,void * arg)35 ksema_init(ksema_t *sem, uint32_t val,
36 	char *name, ksema_type_t st, void *arg)
37 {
38 	(void) _lwp_sema_init(sem, val);
39 }
40 
41 /* ARGSUSED */
42 void
ksema_destroy(ksema_t * sem)43 ksema_destroy(ksema_t *sem)
44 {
45 }
46 
47 void
sema_p(ksema_t * sem)48 sema_p(ksema_t *sem)
49 {
50 	int rv;
51 	do {
52 		rv = _lwp_sema_wait(sem);
53 	} while (rv == EINTR);
54 }
55 
56 void
sema_v(ksema_t * sem)57 sema_v(ksema_t *sem)
58 {
59 	(void) _lwp_sema_post(sem);
60 }
61 
62 /*
63  * Return values:
64  * 1: interrupted
65  * 0: success
66  */
67 int
sema_p_sig(ksema_t * sem)68 sema_p_sig(ksema_t *sem)
69 {
70 	int rv;
71 	rv = _lwp_sema_wait(sem);
72 	switch (rv) {
73 	case 0:
74 		/* rv = 0 ; success */
75 		break;
76 	case EINTR:
77 	default:
78 		rv = 1; /* interrrupted */
79 		break;
80 	}
81 
82 	return (rv);
83 }
84 
85 /*
86  * Return values:
87  * 0: could not get semaphore
88  * 1: successful (backwards from sema_p_sig!)
89  */
90 int
sema_tryp(ksema_t * sem)91 sema_tryp(ksema_t *sem)
92 {
93 	int rv;
94 	rv = _lwp_sema_trywait(sem);
95 
96 	switch (rv) {
97 	case 0:
98 		rv = 1; /* success */
99 		break;
100 	case EBUSY:
101 	default:
102 		rv = 0; /* failed */
103 		break;
104 	}
105 
106 	return (rv);
107 }
108