1/*
2 * Copyright 2022, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _OBSD_COMPAT_SYS_RWLOCK_H_
6#define _OBSD_COMPAT_SYS_RWLOCK_H_
7
8
9#include <sys/mutex.h>
10
11
12struct rwlock_openbsd {
13	struct rw_lock lock;
14};
15#define rwlock rwlock_openbsd
16
17
18static inline void
19rw_init_flags(struct rwlock* rwl, const char* name, int flags)
20{
21	rw_lock_init(&rwl->lock, name);
22}
23#define rw_init(rwl, name)	rw_init_flags(rwl, name, 0)
24
25
26#define RW_WRITE		0x0001UL
27#define RW_READ			0x0002UL
28#define RW_OPMASK		0x0007UL
29
30#define RW_INTR			0x0010UL
31
32
33static int
34rw_enter(struct rwlock* rwl, int flags)
35{
36	const int op = (flags & RW_OPMASK);
37	const int giant = mtx_owned(&Giant);
38	if (giant)
39		mtx_unlock(&Giant);
40
41	int status;
42	if (op == RW_WRITE)
43		status = rw_lock_write_lock(&rwl->lock);
44	else if (op == RW_READ)
45		status = rw_lock_read_lock(&rwl->lock);
46	else
47		panic("bad rw op");
48
49	if (giant)
50		mtx_lock(&Giant);
51	return status;
52}
53
54static inline int
55rw_enter_write(struct rwlock* rwl)
56{
57	return rw_enter(rwl, RW_WRITE);
58}
59
60static inline void
61rw_exit(struct rwlock* rwl)
62{
63	rw_lock_write_unlock(&rwl->lock);
64}
65
66static inline void
67rw_assert_wrlock(struct rwlock* rwl)
68{
69#if KDEBUG
70	if (rwl->lock.holder != find_thread(NULL))
71		panic("rw_assert_wrlock failed!");
72#endif
73}
74
75
76#endif	/* _OBSD_COMPAT_SYS_RWLOCK_H_ */
77