1 // SPDX-License-Identifier: GPL-2.0-only
2 #ifndef __LINUX_RWLOCK_RT_H
3 #define __LINUX_RWLOCK_RT_H
4 
5 #ifndef __LINUX_SPINLOCK_RT_H
6 #error Do not #include directly. Use <linux/spinlock.h>.
7 #endif
8 
9 #ifdef CONFIG_DEBUG_LOCK_ALLOC
10 extern void __rt_rwlock_init(rwlock_t *rwlock, const char *name,
11 			     struct lock_class_key *key);
12 #else
__rt_rwlock_init(rwlock_t * rwlock,char * name,struct lock_class_key * key)13 static inline void __rt_rwlock_init(rwlock_t *rwlock, char *name,
14 				    struct lock_class_key *key)
15 {
16 }
17 #endif
18 
19 #define rwlock_init(rwl)				\
20 do {							\
21 	static struct lock_class_key __key;		\
22 							\
23 	init_rwbase_rt(&(rwl)->rwbase);			\
24 	__rt_rwlock_init(rwl, #rwl, &__key);		\
25 } while (0)
26 
27 extern void rt_read_lock(rwlock_t *rwlock);
28 extern int rt_read_trylock(rwlock_t *rwlock);
29 extern void rt_read_unlock(rwlock_t *rwlock);
30 extern void rt_write_lock(rwlock_t *rwlock);
31 extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass);
32 extern int rt_write_trylock(rwlock_t *rwlock);
33 extern void rt_write_unlock(rwlock_t *rwlock);
34 
read_lock(rwlock_t * rwlock)35 static __always_inline void read_lock(rwlock_t *rwlock)
36 {
37 	rt_read_lock(rwlock);
38 }
39 
read_lock_bh(rwlock_t * rwlock)40 static __always_inline void read_lock_bh(rwlock_t *rwlock)
41 {
42 	local_bh_disable();
43 	rt_read_lock(rwlock);
44 }
45 
read_lock_irq(rwlock_t * rwlock)46 static __always_inline void read_lock_irq(rwlock_t *rwlock)
47 {
48 	rt_read_lock(rwlock);
49 }
50 
51 #define read_lock_irqsave(lock, flags)			\
52 	do {						\
53 		typecheck(unsigned long, flags);	\
54 		rt_read_lock(lock);			\
55 		flags = 0;				\
56 	} while (0)
57 
58 #define read_trylock(lock)	__cond_lock(lock, rt_read_trylock(lock))
59 
read_unlock(rwlock_t * rwlock)60 static __always_inline void read_unlock(rwlock_t *rwlock)
61 {
62 	rt_read_unlock(rwlock);
63 }
64 
read_unlock_bh(rwlock_t * rwlock)65 static __always_inline void read_unlock_bh(rwlock_t *rwlock)
66 {
67 	rt_read_unlock(rwlock);
68 	local_bh_enable();
69 }
70 
read_unlock_irq(rwlock_t * rwlock)71 static __always_inline void read_unlock_irq(rwlock_t *rwlock)
72 {
73 	rt_read_unlock(rwlock);
74 }
75 
read_unlock_irqrestore(rwlock_t * rwlock,unsigned long flags)76 static __always_inline void read_unlock_irqrestore(rwlock_t *rwlock,
77 						   unsigned long flags)
78 {
79 	rt_read_unlock(rwlock);
80 }
81 
write_lock(rwlock_t * rwlock)82 static __always_inline void write_lock(rwlock_t *rwlock)
83 {
84 	rt_write_lock(rwlock);
85 }
86 
87 #ifdef CONFIG_DEBUG_LOCK_ALLOC
write_lock_nested(rwlock_t * rwlock,int subclass)88 static __always_inline void write_lock_nested(rwlock_t *rwlock, int subclass)
89 {
90 	rt_write_lock_nested(rwlock, subclass);
91 }
92 #else
93 #define write_lock_nested(lock, subclass)	rt_write_lock(((void)(subclass), (lock)))
94 #endif
95 
write_lock_bh(rwlock_t * rwlock)96 static __always_inline void write_lock_bh(rwlock_t *rwlock)
97 {
98 	local_bh_disable();
99 	rt_write_lock(rwlock);
100 }
101 
write_lock_irq(rwlock_t * rwlock)102 static __always_inline void write_lock_irq(rwlock_t *rwlock)
103 {
104 	rt_write_lock(rwlock);
105 }
106 
107 #define write_lock_irqsave(lock, flags)			\
108 	do {						\
109 		typecheck(unsigned long, flags);	\
110 		rt_write_lock(lock);			\
111 		flags = 0;				\
112 	} while (0)
113 
114 #define write_trylock(lock)	__cond_lock(lock, rt_write_trylock(lock))
115 
116 #define write_trylock_irqsave(lock, flags)		\
117 ({							\
118 	int __locked;					\
119 							\
120 	typecheck(unsigned long, flags);		\
121 	flags = 0;					\
122 	__locked = write_trylock(lock);			\
123 	__locked;					\
124 })
125 
write_unlock(rwlock_t * rwlock)126 static __always_inline void write_unlock(rwlock_t *rwlock)
127 {
128 	rt_write_unlock(rwlock);
129 }
130 
write_unlock_bh(rwlock_t * rwlock)131 static __always_inline void write_unlock_bh(rwlock_t *rwlock)
132 {
133 	rt_write_unlock(rwlock);
134 	local_bh_enable();
135 }
136 
write_unlock_irq(rwlock_t * rwlock)137 static __always_inline void write_unlock_irq(rwlock_t *rwlock)
138 {
139 	rt_write_unlock(rwlock);
140 }
141 
write_unlock_irqrestore(rwlock_t * rwlock,unsigned long flags)142 static __always_inline void write_unlock_irqrestore(rwlock_t *rwlock,
143 						    unsigned long flags)
144 {
145 	rt_write_unlock(rwlock);
146 }
147 
148 #define rwlock_is_contended(lock)		(((void)(lock), 0))
149 
150 #endif /* __LINUX_RWLOCK_RT_H */
151