xref: /netbsd-src/sys/rump/librump/rumpkern/locks.c (revision b78992537496bc71ee3d761f9fe0be0fc0a9a001)
1 /*	$NetBSD: locks.c,v 1.18 2008/07/29 13:17:47 pooka Exp $	*/
2 
3 /*-
4  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
31  *
32  * Development of this software was supported by the
33  * Finnish Cultural Foundation.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  * 1. Redistributions of source code must retain the above copyright
39  *    notice, this list of conditions and the following disclaimer.
40  * 2. Redistributions in binary form must reproduce the above copyright
41  *    notice, this list of conditions and the following disclaimer in the
42  *    documentation and/or other materials provided with the distribution.
43  *
44  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
45  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
48  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54  * SUCH DAMAGE.
55  */
56 
57 #include <sys/param.h>
58 #include <sys/mutex.h>
59 #include <sys/rwlock.h>
60 #include <sys/atomic.h>
61 
62 #include <rump/rumpuser.h>
63 
64 #include "rump_private.h"
65 
66 void
67 mutex_init(kmutex_t *mtx, kmutex_type_t type, int ipl)
68 {
69 
70 	rumpuser_mutex_init(&mtx->kmtx_mtx);
71 }
72 
73 void
74 mutex_destroy(kmutex_t *mtx)
75 {
76 
77 	rumpuser_mutex_destroy(mtx->kmtx_mtx);
78 }
79 
80 void
81 mutex_enter(kmutex_t *mtx)
82 {
83 
84 	rumpuser_mutex_enter(mtx->kmtx_mtx);
85 }
86 
87 void
88 mutex_spin_enter(kmutex_t *mtx)
89 {
90 
91 	mutex_enter(mtx);
92 }
93 
94 int
95 mutex_tryenter(kmutex_t *mtx)
96 {
97 
98 	return rumpuser_mutex_tryenter(mtx->kmtx_mtx);
99 }
100 
101 void
102 mutex_exit(kmutex_t *mtx)
103 {
104 
105 	rumpuser_mutex_exit(mtx->kmtx_mtx);
106 }
107 
108 void
109 mutex_spin_exit(kmutex_t *mtx)
110 {
111 
112 	mutex_exit(mtx);
113 }
114 
115 int
116 mutex_owned(kmutex_t *mtx)
117 {
118 
119 	return rumpuser_mutex_held(mtx->kmtx_mtx);
120 }
121 
122 /* reader/writer locks */
123 
124 void
125 rw_init(krwlock_t *rw)
126 {
127 
128 	rumpuser_rw_init(&rw->krw_pthlock);
129 }
130 
131 void
132 rw_destroy(krwlock_t *rw)
133 {
134 
135 	rumpuser_rw_destroy(rw->krw_pthlock);
136 }
137 
138 void
139 rw_enter(krwlock_t *rw, const krw_t op)
140 {
141 
142 	rumpuser_rw_enter(rw->krw_pthlock, op == RW_WRITER);
143 }
144 
145 int
146 rw_tryenter(krwlock_t *rw, const krw_t op)
147 {
148 
149 	return rumpuser_rw_tryenter(rw->krw_pthlock, op == RW_WRITER);
150 }
151 
152 void
153 rw_exit(krwlock_t *rw)
154 {
155 
156 	rumpuser_rw_exit(rw->krw_pthlock);
157 }
158 
159 /* always fails */
160 int
161 rw_tryupgrade(krwlock_t *rw)
162 {
163 
164 	return 0;
165 }
166 
167 int
168 rw_write_held(krwlock_t *rw)
169 {
170 
171 	return rumpuser_rw_wrheld(rw->krw_pthlock);
172 }
173 
174 int
175 rw_read_held(krwlock_t *rw)
176 {
177 
178 	return rumpuser_rw_rdheld(rw->krw_pthlock);
179 }
180 
181 int
182 rw_lock_held(krwlock_t *rw)
183 {
184 
185 	return rumpuser_rw_held(rw->krw_pthlock);
186 }
187 
188 /* curriculum vitaes */
189 
190 /* forgive me for I have sinned */
191 #define RUMPCV(a) ((struct rumpuser_cv *)(__UNCONST((a)->cv_wmesg)))
192 
193 void
194 cv_init(kcondvar_t *cv, const char *msg)
195 {
196 
197 	rumpuser_cv_init((struct rumpuser_cv **)__UNCONST(&cv->cv_wmesg));
198 }
199 
200 void
201 cv_destroy(kcondvar_t *cv)
202 {
203 
204 	rumpuser_cv_destroy(RUMPCV(cv));
205 }
206 
207 void
208 cv_wait(kcondvar_t *cv, kmutex_t *mtx)
209 {
210 
211 	rumpuser_cv_wait(RUMPCV(cv), mtx->kmtx_mtx);
212 }
213 
214 int
215 cv_wait_sig(kcondvar_t *cv, kmutex_t *mtx)
216 {
217 
218 	rumpuser_cv_wait(RUMPCV(cv), mtx->kmtx_mtx);
219 	return 0;
220 }
221 
222 int
223 cv_timedwait(kcondvar_t *cv, kmutex_t *mtx, int ticks)
224 {
225 #ifdef DIAGNOSTIC
226 	extern int hz;
227 #endif
228 
229 	if (ticks == 0) {
230 		cv_wait(cv, mtx);
231 		return 0;
232 	} else {
233 		KASSERT(hz == 100);
234 		return rumpuser_cv_timedwait(RUMPCV(cv), mtx->kmtx_mtx, ticks);
235 	}
236 }
237 
238 int
239 cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, int ticks)
240 {
241 
242 	return cv_timedwait(cv, mtx, ticks);
243 }
244 
245 void
246 cv_signal(kcondvar_t *cv)
247 {
248 
249 	rumpuser_cv_signal(RUMPCV(cv));
250 }
251 
252 void
253 cv_broadcast(kcondvar_t *cv)
254 {
255 
256 	rumpuser_cv_broadcast(RUMPCV(cv));
257 }
258 
259 bool
260 cv_has_waiters(kcondvar_t *cv)
261 {
262 
263 	return rumpuser_cv_has_waiters(RUMPCV(cv));
264 }
265 
266 /* kernel biglock, only for vnode_if */
267 
268 void
269 _kernel_lock(int nlocks)
270 {
271 
272 	KASSERT(nlocks == 1);
273 	mutex_enter(&rump_giantlock);
274 }
275 
276 void
277 _kernel_unlock(int nlocks, int *countp)
278 {
279 
280 	KASSERT(nlocks == 1);
281 	mutex_exit(&rump_giantlock);
282 	if (countp)
283 		*countp = 1;
284 }
285 
286 struct kmutexobj {
287 	kmutex_t	mo_lock;
288 	u_int		mo_refcnt;
289 };
290 
291 kmutex_t *
292 mutex_obj_alloc(kmutex_type_t type, int ipl)
293 {
294 	struct kmutexobj *mo;
295 
296 	mo = kmem_alloc(sizeof(*mo), KM_SLEEP);
297 	mutex_init(&mo->mo_lock, type, ipl);
298 	mo->mo_refcnt = 1;
299 
300 	return (kmutex_t *)mo;
301 }
302 
303 void
304 mutex_obj_hold(kmutex_t *lock)
305 {
306 	struct kmutexobj *mo = (struct kmutexobj *)lock;
307 
308 	atomic_inc_uint(&mo->mo_refcnt);
309 }
310 
311 bool
312 mutex_obj_free(kmutex_t *lock)
313 {
314 	struct kmutexobj *mo = (struct kmutexobj *)lock;
315 
316 	if (atomic_dec_uint_nv(&mo->mo_refcnt) > 0) {
317 		return false;
318 	}
319 	mutex_destroy(&mo->mo_lock);
320 	kmem_free(mo, sizeof(*mo));
321 	return true;
322 }
323