xref: /linux/include/linux/rwlock_rt.h (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
18282947fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
28282947fSThomas Gleixner #ifndef __LINUX_RWLOCK_RT_H
38282947fSThomas Gleixner #define __LINUX_RWLOCK_RT_H
48282947fSThomas Gleixner 
58282947fSThomas Gleixner #ifndef __LINUX_SPINLOCK_RT_H
68282947fSThomas Gleixner #error Do not #include directly. Use <linux/spinlock.h>.
78282947fSThomas Gleixner #endif
88282947fSThomas Gleixner 
98282947fSThomas Gleixner #ifdef CONFIG_DEBUG_LOCK_ALLOC
108282947fSThomas Gleixner extern void __rt_rwlock_init(rwlock_t *rwlock, const char *name,
118282947fSThomas Gleixner 			     struct lock_class_key *key);
128282947fSThomas Gleixner #else
__rt_rwlock_init(rwlock_t * rwlock,char * name,struct lock_class_key * key)138282947fSThomas Gleixner static inline void __rt_rwlock_init(rwlock_t *rwlock, char *name,
148282947fSThomas Gleixner 				    struct lock_class_key *key)
158282947fSThomas Gleixner {
168282947fSThomas Gleixner }
178282947fSThomas Gleixner #endif
188282947fSThomas Gleixner 
198282947fSThomas Gleixner #define rwlock_init(rwl)				\
208282947fSThomas Gleixner do {							\
218282947fSThomas Gleixner 	static struct lock_class_key __key;		\
228282947fSThomas Gleixner 							\
238282947fSThomas Gleixner 	init_rwbase_rt(&(rwl)->rwbase);			\
248282947fSThomas Gleixner 	__rt_rwlock_init(rwl, #rwl, &__key);		\
258282947fSThomas Gleixner } while (0)
268282947fSThomas Gleixner 
278282947fSThomas Gleixner extern void rt_read_lock(rwlock_t *rwlock);
288282947fSThomas Gleixner extern int rt_read_trylock(rwlock_t *rwlock);
298282947fSThomas Gleixner extern void rt_read_unlock(rwlock_t *rwlock);
308282947fSThomas Gleixner extern void rt_write_lock(rwlock_t *rwlock);
31*4a57d6bbSMinchan Kim extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass);
328282947fSThomas Gleixner extern int rt_write_trylock(rwlock_t *rwlock);
338282947fSThomas Gleixner extern void rt_write_unlock(rwlock_t *rwlock);
348282947fSThomas Gleixner 
read_lock(rwlock_t * rwlock)358282947fSThomas Gleixner static __always_inline void read_lock(rwlock_t *rwlock)
368282947fSThomas Gleixner {
378282947fSThomas Gleixner 	rt_read_lock(rwlock);
388282947fSThomas Gleixner }
398282947fSThomas Gleixner 
read_lock_bh(rwlock_t * rwlock)408282947fSThomas Gleixner static __always_inline void read_lock_bh(rwlock_t *rwlock)
418282947fSThomas Gleixner {
428282947fSThomas Gleixner 	local_bh_disable();
438282947fSThomas Gleixner 	rt_read_lock(rwlock);
448282947fSThomas Gleixner }
458282947fSThomas Gleixner 
read_lock_irq(rwlock_t * rwlock)468282947fSThomas Gleixner static __always_inline void read_lock_irq(rwlock_t *rwlock)
478282947fSThomas Gleixner {
488282947fSThomas Gleixner 	rt_read_lock(rwlock);
498282947fSThomas Gleixner }
508282947fSThomas Gleixner 
518282947fSThomas Gleixner #define read_lock_irqsave(lock, flags)			\
528282947fSThomas Gleixner 	do {						\
538282947fSThomas Gleixner 		typecheck(unsigned long, flags);	\
548282947fSThomas Gleixner 		rt_read_lock(lock);			\
558282947fSThomas Gleixner 		flags = 0;				\
568282947fSThomas Gleixner 	} while (0)
578282947fSThomas Gleixner 
588282947fSThomas Gleixner #define read_trylock(lock)	__cond_lock(lock, rt_read_trylock(lock))
598282947fSThomas Gleixner 
read_unlock(rwlock_t * rwlock)608282947fSThomas Gleixner static __always_inline void read_unlock(rwlock_t *rwlock)
618282947fSThomas Gleixner {
628282947fSThomas Gleixner 	rt_read_unlock(rwlock);
638282947fSThomas Gleixner }
648282947fSThomas Gleixner 
read_unlock_bh(rwlock_t * rwlock)658282947fSThomas Gleixner static __always_inline void read_unlock_bh(rwlock_t *rwlock)
668282947fSThomas Gleixner {
678282947fSThomas Gleixner 	rt_read_unlock(rwlock);
688282947fSThomas Gleixner 	local_bh_enable();
698282947fSThomas Gleixner }
708282947fSThomas Gleixner 
read_unlock_irq(rwlock_t * rwlock)718282947fSThomas Gleixner static __always_inline void read_unlock_irq(rwlock_t *rwlock)
728282947fSThomas Gleixner {
738282947fSThomas Gleixner 	rt_read_unlock(rwlock);
748282947fSThomas Gleixner }
758282947fSThomas Gleixner 
read_unlock_irqrestore(rwlock_t * rwlock,unsigned long flags)768282947fSThomas Gleixner static __always_inline void read_unlock_irqrestore(rwlock_t *rwlock,
778282947fSThomas Gleixner 						   unsigned long flags)
788282947fSThomas Gleixner {
798282947fSThomas Gleixner 	rt_read_unlock(rwlock);
808282947fSThomas Gleixner }
818282947fSThomas Gleixner 
write_lock(rwlock_t * rwlock)828282947fSThomas Gleixner static __always_inline void write_lock(rwlock_t *rwlock)
838282947fSThomas Gleixner {
848282947fSThomas Gleixner 	rt_write_lock(rwlock);
858282947fSThomas Gleixner }
868282947fSThomas Gleixner 
87*4a57d6bbSMinchan Kim #ifdef CONFIG_DEBUG_LOCK_ALLOC
write_lock_nested(rwlock_t * rwlock,int subclass)88*4a57d6bbSMinchan Kim static __always_inline void write_lock_nested(rwlock_t *rwlock, int subclass)
89*4a57d6bbSMinchan Kim {
90*4a57d6bbSMinchan Kim 	rt_write_lock_nested(rwlock, subclass);
91*4a57d6bbSMinchan Kim }
92*4a57d6bbSMinchan Kim #else
93*4a57d6bbSMinchan Kim #define write_lock_nested(lock, subclass)	rt_write_lock(((void)(subclass), (lock)))
94*4a57d6bbSMinchan Kim #endif
95*4a57d6bbSMinchan Kim 
write_lock_bh(rwlock_t * rwlock)968282947fSThomas Gleixner static __always_inline void write_lock_bh(rwlock_t *rwlock)
978282947fSThomas Gleixner {
988282947fSThomas Gleixner 	local_bh_disable();
998282947fSThomas Gleixner 	rt_write_lock(rwlock);
1008282947fSThomas Gleixner }
1018282947fSThomas Gleixner 
write_lock_irq(rwlock_t * rwlock)1028282947fSThomas Gleixner static __always_inline void write_lock_irq(rwlock_t *rwlock)
1038282947fSThomas Gleixner {
1048282947fSThomas Gleixner 	rt_write_lock(rwlock);
1058282947fSThomas Gleixner }
1068282947fSThomas Gleixner 
1078282947fSThomas Gleixner #define write_lock_irqsave(lock, flags)			\
1088282947fSThomas Gleixner 	do {						\
1098282947fSThomas Gleixner 		typecheck(unsigned long, flags);	\
1108282947fSThomas Gleixner 		rt_write_lock(lock);			\
1118282947fSThomas Gleixner 		flags = 0;				\
1128282947fSThomas Gleixner 	} while (0)
1138282947fSThomas Gleixner 
1148282947fSThomas Gleixner #define write_trylock(lock)	__cond_lock(lock, rt_write_trylock(lock))
1158282947fSThomas Gleixner 
1168282947fSThomas Gleixner #define write_trylock_irqsave(lock, flags)		\
1178282947fSThomas Gleixner ({							\
1188282947fSThomas Gleixner 	int __locked;					\
1198282947fSThomas Gleixner 							\
1208282947fSThomas Gleixner 	typecheck(unsigned long, flags);		\
1218282947fSThomas Gleixner 	flags = 0;					\
1228282947fSThomas Gleixner 	__locked = write_trylock(lock);			\
1238282947fSThomas Gleixner 	__locked;					\
1248282947fSThomas Gleixner })
1258282947fSThomas Gleixner 
write_unlock(rwlock_t * rwlock)1268282947fSThomas Gleixner static __always_inline void write_unlock(rwlock_t *rwlock)
1278282947fSThomas Gleixner {
1288282947fSThomas Gleixner 	rt_write_unlock(rwlock);
1298282947fSThomas Gleixner }
1308282947fSThomas Gleixner 
write_unlock_bh(rwlock_t * rwlock)1318282947fSThomas Gleixner static __always_inline void write_unlock_bh(rwlock_t *rwlock)
1328282947fSThomas Gleixner {
1338282947fSThomas Gleixner 	rt_write_unlock(rwlock);
1348282947fSThomas Gleixner 	local_bh_enable();
1358282947fSThomas Gleixner }
1368282947fSThomas Gleixner 
write_unlock_irq(rwlock_t * rwlock)1378282947fSThomas Gleixner static __always_inline void write_unlock_irq(rwlock_t *rwlock)
1388282947fSThomas Gleixner {
1398282947fSThomas Gleixner 	rt_write_unlock(rwlock);
1408282947fSThomas Gleixner }
1418282947fSThomas Gleixner 
write_unlock_irqrestore(rwlock_t * rwlock,unsigned long flags)1428282947fSThomas Gleixner static __always_inline void write_unlock_irqrestore(rwlock_t *rwlock,
1438282947fSThomas Gleixner 						    unsigned long flags)
1448282947fSThomas Gleixner {
1458282947fSThomas Gleixner 	rt_write_unlock(rwlock);
1468282947fSThomas Gleixner }
1478282947fSThomas Gleixner 
1488282947fSThomas Gleixner #define rwlock_is_contended(lock)		(((void)(lock), 0))
1498282947fSThomas Gleixner 
1508282947fSThomas Gleixner #endif /* __LINUX_RWLOCK_RT_H */
151