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
12 struct rwlock_openbsd {
13 struct rw_lock lock;
14 };
15 #define rwlock rwlock_openbsd
16
17
18 static inline void
rw_init_flags(struct rwlock * rwl,const char * name,int flags)19 rw_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
33 static int
rw_enter(struct rwlock * rwl,int flags)34 rw_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
54 static inline int
rw_enter_write(struct rwlock * rwl)55 rw_enter_write(struct rwlock* rwl)
56 {
57 return rw_enter(rwl, RW_WRITE);
58 }
59
60 static inline void
rw_exit(struct rwlock * rwl)61 rw_exit(struct rwlock* rwl)
62 {
63 rw_lock_write_unlock(&rwl->lock);
64 }
65
66 static inline void
rw_assert_wrlock(struct rwlock * rwl)67 rw_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