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