locks.c revision 1.14.4.1 1 /* $NetBSD: locks.c,v 1.14.4.1 2008/05/16 02:25:50 yamt 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_private.h"
63
64 #include "rumpuser.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 extern int hz;
226
227 if (ticks == 0) {
228 cv_wait(cv, mtx);
229 return 0;
230 } else {
231 KASSERT(hz == 100);
232 return rumpuser_cv_timedwait(RUMPCV(cv), mtx->kmtx_mtx, ticks);
233 }
234 }
235
236 int
237 cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, int ticks)
238 {
239
240 return cv_timedwait(cv, mtx, ticks);
241 }
242
243 void
244 cv_signal(kcondvar_t *cv)
245 {
246
247 rumpuser_cv_signal(RUMPCV(cv));
248 }
249
250 void
251 cv_broadcast(kcondvar_t *cv)
252 {
253
254 rumpuser_cv_broadcast(RUMPCV(cv));
255 }
256
257 /* kernel biglock, only for vnode_if */
258
259 void
260 _kernel_lock(int nlocks)
261 {
262
263 KASSERT(nlocks == 1);
264 mutex_enter(&rump_giantlock);
265 }
266
267 void
268 _kernel_unlock(int nlocks, int *countp)
269 {
270
271 KASSERT(nlocks == 1);
272 mutex_exit(&rump_giantlock);
273 if (countp)
274 *countp = 1;
275 }
276
277 struct kmutexobj {
278 kmutex_t mo_lock;
279 u_int mo_refcnt;
280 };
281
282 kmutex_t *
283 mutex_obj_alloc(kmutex_type_t type, int ipl)
284 {
285 struct kmutexobj *mo;
286
287 mo = kmem_alloc(sizeof(*mo), KM_SLEEP);
288 mutex_init(&mo->mo_lock, type, ipl);
289 mo->mo_refcnt = 1;
290
291 return (kmutex_t *)mo;
292 }
293
294 void
295 mutex_obj_hold(kmutex_t *lock)
296 {
297 struct kmutexobj *mo = (struct kmutexobj *)lock;
298
299 atomic_inc_uint(&mo->mo_refcnt);
300 }
301
302 bool
303 mutex_obj_free(kmutex_t *lock)
304 {
305 struct kmutexobj *mo = (struct kmutexobj *)lock;
306
307 if (atomic_dec_uint_nv(&mo->mo_refcnt) > 0) {
308 return false;
309 }
310 mutex_destroy(&mo->mo_lock);
311 kmem_free(mo, sizeof(*mo));
312 return true;
313 }
314