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
10extern void __rt_rwlock_init(rwlock_t *rwlock, const char *name,
11			     struct lock_class_key *key);
12#else
13static 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)				\
20do {							\
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
27extern void rt_read_lock(rwlock_t *rwlock);
28extern int rt_read_trylock(rwlock_t *rwlock);
29extern void rt_read_unlock(rwlock_t *rwlock);
30extern void rt_write_lock(rwlock_t *rwlock);
31extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass);
32extern int rt_write_trylock(rwlock_t *rwlock);
33extern void rt_write_unlock(rwlock_t *rwlock);
34
35static __always_inline void read_lock(rwlock_t *rwlock)
36{
37	rt_read_lock(rwlock);
38}
39
40static __always_inline void read_lock_bh(rwlock_t *rwlock)
41{
42	local_bh_disable();
43	rt_read_lock(rwlock);
44}
45
46static __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
60static __always_inline void read_unlock(rwlock_t *rwlock)
61{
62	rt_read_unlock(rwlock);
63}
64
65static __always_inline void read_unlock_bh(rwlock_t *rwlock)
66{
67	rt_read_unlock(rwlock);
68	local_bh_enable();
69}
70
71static __always_inline void read_unlock_irq(rwlock_t *rwlock)
72{
73	rt_read_unlock(rwlock);
74}
75
76static __always_inline void read_unlock_irqrestore(rwlock_t *rwlock,
77						   unsigned long flags)
78{
79	rt_read_unlock(rwlock);
80}
81
82static __always_inline void write_lock(rwlock_t *rwlock)
83{
84	rt_write_lock(rwlock);
85}
86
87#ifdef CONFIG_DEBUG_LOCK_ALLOC
88static __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
96static __always_inline void write_lock_bh(rwlock_t *rwlock)
97{
98	local_bh_disable();
99	rt_write_lock(rwlock);
100}
101
102static __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
126static __always_inline void write_unlock(rwlock_t *rwlock)
127{
128	rt_write_unlock(rwlock);
129}
130
131static __always_inline void write_unlock_bh(rwlock_t *rwlock)
132{
133	rt_write_unlock(rwlock);
134	local_bh_enable();
135}
136
137static __always_inline void write_unlock_irq(rwlock_t *rwlock)
138{
139	rt_write_unlock(rwlock);
140}
141
142static __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