xref: /linux/include/linux/rwlock_rt.h (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
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
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)	__acquires_shared(rwlock);
28 extern int rt_read_trylock(rwlock_t *rwlock)	__cond_acquires_shared(true, rwlock);
29 extern void rt_read_unlock(rwlock_t *rwlock)	__releases_shared(rwlock);
30 extern void rt_write_lock(rwlock_t *rwlock)	__acquires(rwlock);
31 extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass)	__acquires(rwlock);
32 extern int rt_write_trylock(rwlock_t *rwlock)	__cond_acquires(true, rwlock);
33 extern void rt_write_unlock(rwlock_t *rwlock)	__releases(rwlock);
34 
35 static __always_inline void read_lock(rwlock_t *rwlock)
36 	__acquires_shared(rwlock)
37 {
38 	rt_read_lock(rwlock);
39 }
40 
41 static __always_inline void read_lock_bh(rwlock_t *rwlock)
42 	__acquires_shared(rwlock)
43 {
44 	local_bh_disable();
45 	rt_read_lock(rwlock);
46 }
47 
48 static __always_inline void read_lock_irq(rwlock_t *rwlock)
49 	__acquires_shared(rwlock)
50 {
51 	rt_read_lock(rwlock);
52 }
53 
54 #define read_lock_irqsave(lock, flags)			\
55 	do {						\
56 		typecheck(unsigned long, flags);	\
57 		rt_read_lock(lock);			\
58 		flags = 0;				\
59 	} while (0)
60 
61 #define read_trylock(lock)	rt_read_trylock(lock)
62 
63 static __always_inline void read_unlock(rwlock_t *rwlock)
64 	__releases_shared(rwlock)
65 {
66 	rt_read_unlock(rwlock);
67 }
68 
69 static __always_inline void read_unlock_bh(rwlock_t *rwlock)
70 	__releases_shared(rwlock)
71 {
72 	rt_read_unlock(rwlock);
73 	local_bh_enable();
74 }
75 
76 static __always_inline void read_unlock_irq(rwlock_t *rwlock)
77 	__releases_shared(rwlock)
78 {
79 	rt_read_unlock(rwlock);
80 }
81 
82 static __always_inline void read_unlock_irqrestore(rwlock_t *rwlock,
83 						   unsigned long flags)
84 	__releases_shared(rwlock)
85 {
86 	rt_read_unlock(rwlock);
87 }
88 
89 static __always_inline void write_lock(rwlock_t *rwlock)
90 	__acquires(rwlock)
91 {
92 	rt_write_lock(rwlock);
93 }
94 
95 #ifdef CONFIG_DEBUG_LOCK_ALLOC
96 static __always_inline void write_lock_nested(rwlock_t *rwlock, int subclass)
97 	__acquires(rwlock)
98 {
99 	rt_write_lock_nested(rwlock, subclass);
100 }
101 #else
102 #define write_lock_nested(lock, subclass)	rt_write_lock(((void)(subclass), (lock)))
103 #endif
104 
105 static __always_inline void write_lock_bh(rwlock_t *rwlock)
106 	__acquires(rwlock)
107 {
108 	local_bh_disable();
109 	rt_write_lock(rwlock);
110 }
111 
112 static __always_inline void write_lock_irq(rwlock_t *rwlock)
113 	__acquires(rwlock)
114 {
115 	rt_write_lock(rwlock);
116 }
117 
118 #define write_lock_irqsave(lock, flags)			\
119 	do {						\
120 		typecheck(unsigned long, flags);	\
121 		rt_write_lock(lock);			\
122 		flags = 0;				\
123 	} while (0)
124 
125 #define write_trylock(lock)	rt_write_trylock(lock)
126 
127 static __always_inline bool _write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags)
128 	__cond_acquires(true, rwlock)
129 {
130 	*flags = 0;
131 	return rt_write_trylock(rwlock);
132 }
133 #define write_trylock_irqsave(lock, flags) _write_trylock_irqsave(lock, &(flags))
134 
135 static __always_inline void write_unlock(rwlock_t *rwlock)
136 	__releases(rwlock)
137 {
138 	rt_write_unlock(rwlock);
139 }
140 
141 static __always_inline void write_unlock_bh(rwlock_t *rwlock)
142 	__releases(rwlock)
143 {
144 	rt_write_unlock(rwlock);
145 	local_bh_enable();
146 }
147 
148 static __always_inline void write_unlock_irq(rwlock_t *rwlock)
149 	__releases(rwlock)
150 {
151 	rt_write_unlock(rwlock);
152 }
153 
154 static __always_inline void write_unlock_irqrestore(rwlock_t *rwlock,
155 						    unsigned long flags)
156 	__releases(rwlock)
157 {
158 	rt_write_unlock(rwlock);
159 }
160 
161 #define rwlock_is_contended(lock)		(((void)(lock), 0))
162 
163 #endif /* __LINUX_RWLOCK_RT_H */
164