locks.c revision 1.15.2.2 1 /* $NetBSD: locks.c,v 1.15.2.2 2008/09/18 04:37:04 wrstuden 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