1 /* $NetBSD: kernel2.c,v 1.1 2009/03/26 22:11:44 ad Exp $ */
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: kernel2.c,v 1.1 2009/03/26 22:11:44 ad Exp $");
35 #include <sys/zfs_context.h>
40 #define GET(ptr) (*(void **)ptr)
41 #define SET(ptr, val) (*(void **)ptr = val)
44 mutex_init(kmutex_t
*mtx
, void *junk1
, kmutex_type_t type
, void *junk2
)
46 pthread_mutex_t
*mutex
;
49 mutex
= malloc(sizeof(*mutex
));
51 err(1, "mutex_init: malloc\n");
53 rv
= pthread_mutex_init(mutex
, NULL
);
55 errx(1, "mutex_init: err %d\n", rv
);
61 mutex_destroy(kmutex_t
*mtx
)
63 pthread_mutex_t
*mutex
= GET(mtx
);
65 pthread_mutex_destroy(mutex
);
70 mutex_enter(kmutex_t
*mtx
)
73 pthread_mutex_lock(GET(mtx
));
77 mutex_tryenter(kmutex_t
*mtx
)
80 return (pthread_mutex_trylock(GET(mtx
)) == 0);
84 mutex_exit(kmutex_t
*mtx
)
87 pthread_mutex_unlock(GET(mtx
));
91 mutex_owner(kmutex_t
*mtx
)
94 return pthread_mutex_owner_np(GET(mtx
));
98 mutex_owned(kmutex_t
*mtx
)
101 return pthread_mutex_held_np(GET(mtx
));
105 rw_init(krwlock_t
*rw
, char *name
, int type
, void *arg
)
107 pthread_rwlock_t
*rwlock
;
110 rwlock
= malloc(sizeof(*rwlock
));
111 if (rwlock
== NULL
) {
112 err(1, "rw_init: malloc\n");
114 rv
= pthread_rwlock_init(rwlock
, NULL
);
116 errx(1, "rw_init: err %d\n", rv
);
122 rw_destroy(krwlock_t
*rw
)
124 pthread_rwlock_t
*rwlock
= GET(rw
);
127 rv
= pthread_rwlock_destroy(rwlock
);
129 errx(1, "rw_destroy: err %d\n", rv
);
135 rw_enter(krwlock_t
*rw
, const krw_t op
)
137 pthread_rwlock_t
*rwlock
= GET(rw
);
140 if (op
== RW_WRITER
) {
141 rv
= pthread_rwlock_wrlock(rwlock
);
143 errx(1, "rw_enter(RW_WRITER) err %d\n", rv
);
146 rv
= pthread_rwlock_rdlock(rwlock
);
148 errx(1, "rw_enter(RW_READER) err %d\n", rv
);
154 rw_tryenter(krwlock_t
*rw
, const krw_t op
)
156 pthread_rwlock_t
*rwlock
= GET(rw
);
159 if (op
== RW_WRITER
) {
160 rv
= pthread_rwlock_trywrlock(rwlock
);
162 rv
= pthread_rwlock_tryrdlock(rwlock
);
169 rw_exit(krwlock_t
*rw
)
173 rv
= pthread_rwlock_unlock(GET(rw
));
175 errx(1, "rw_exit: err %d\n", rv
);
180 rw_tryupgrade(krwlock_t
*rw
)
187 rw_lock_held(krwlock_t
*rw
)
190 return pthread_rwlock_held_np(GET(rw
));
194 rw_read_held(krwlock_t
*rw
)
197 return pthread_rwlock_rdheld_np(GET(rw
));
201 rw_write_held(krwlock_t
*rw
)
204 return pthread_rwlock_wrheld_np(GET(rw
));
208 cv_init(kcondvar_t
*cv
, char *name
, int type
, void *arg
)
210 pthread_cond_t
*cond
;
212 cond
= malloc(sizeof(*cond
));
213 pthread_cond_init(cond
, NULL
);
218 cv_destroy(kcondvar_t
*cv
)
220 pthread_cond_t
*cond
= GET(cv
);
223 pthread_cond_destroy(cond
);
229 cv_wait(kcondvar_t
*cv
, kmutex_t
*mtx
)
232 if (GET(cv
) == NULL
) {
233 cv_init(cv
, NULL
, 0, NULL
);
236 pthread_cond_wait(GET(cv
), GET(mtx
));
240 cv_timedwait(kcondvar_t
*cv
, kmutex_t
*mp
, clock_t abstime
)
246 if (GET(cv
) == NULL
) {
247 cv_init(cv
, NULL
, 0, NULL
);
250 /* convert back from 119hz to nanoseconds. */
251 when
= abstime
<< 23;
252 ts
.tv_sec
= (long)(abstime
/ 1000000000);
253 ts
.tv_nsec
= (long)(abstime
% 1000000000);
256 error
= pthread_cond_timedwait(GET(cv
), GET(mp
), &ts
);
257 } while (error
== EINTR
);
259 if (error
== ETIMEDOUT
)
267 cv_signal(kcondvar_t
*cv
)
270 if (GET(cv
) == NULL
) {
271 cv_init(cv
, NULL
, 0, NULL
);
273 pthread_cond_signal(GET(cv
));
277 cv_broadcast(kcondvar_t
*cv
)
280 if (GET(cv
) == NULL
) {
281 cv_init(cv
, NULL
, 0, NULL
);
283 pthread_cond_broadcast(GET(cv
));