rwlock_api_smp.h 7.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#ifndef __LINUX_RWLOCK_API_SMP_H
#define __LINUX_RWLOCK_API_SMP_H

#ifndef __LINUX_SPINLOCK_API_SMP_H
# error "please don't include this file directly"
#endif

/*
 * include/linux/rwlock_api_smp.h
 *
 * spinlock API declarations on SMP (and debug)
 * (implemented in kernel/spinlock.c)
 *
 * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
 * Released under the General Public License (GPL).
 */

18 19
void __lockfunc _raw_read_lock(rwlock_t *lock)		__acquires(lock);
void __lockfunc _raw_write_lock(rwlock_t *lock)		__acquires(lock);
20
void __lockfunc _raw_write_lock_nested(rwlock_t *lock, int subclass)	__acquires(lock);
21 22 23 24 25
void __lockfunc _raw_read_lock_bh(rwlock_t *lock)	__acquires(lock);
void __lockfunc _raw_write_lock_bh(rwlock_t *lock)	__acquires(lock);
void __lockfunc _raw_read_lock_irq(rwlock_t *lock)	__acquires(lock);
void __lockfunc _raw_write_lock_irq(rwlock_t *lock)	__acquires(lock);
unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock)
26
							__acquires(lock);
27
unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock)
28
							__acquires(lock);
29 30 31 32 33 34 35 36 37 38
int __lockfunc _raw_read_trylock(rwlock_t *lock);
int __lockfunc _raw_write_trylock(rwlock_t *lock);
void __lockfunc _raw_read_unlock(rwlock_t *lock)	__releases(lock);
void __lockfunc _raw_write_unlock(rwlock_t *lock)	__releases(lock);
void __lockfunc _raw_read_unlock_bh(rwlock_t *lock)	__releases(lock);
void __lockfunc _raw_write_unlock_bh(rwlock_t *lock)	__releases(lock);
void __lockfunc _raw_read_unlock_irq(rwlock_t *lock)	__releases(lock);
void __lockfunc _raw_write_unlock_irq(rwlock_t *lock)	__releases(lock);
void __lockfunc
_raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
39
							__releases(lock);
40 41
void __lockfunc
_raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
42 43 44
							__releases(lock);

#ifdef CONFIG_INLINE_READ_LOCK
45
#define _raw_read_lock(lock) __raw_read_lock(lock)
46 47 48
#endif

#ifdef CONFIG_INLINE_WRITE_LOCK
49
#define _raw_write_lock(lock) __raw_write_lock(lock)
50 51 52
#endif

#ifdef CONFIG_INLINE_READ_LOCK_BH
53
#define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock)
54 55 56
#endif

#ifdef CONFIG_INLINE_WRITE_LOCK_BH
57
#define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock)
58 59 60
#endif

#ifdef CONFIG_INLINE_READ_LOCK_IRQ
61
#define _raw_read_lock_irq(lock) __raw_read_lock_irq(lock)
62 63 64
#endif

#ifdef CONFIG_INLINE_WRITE_LOCK_IRQ
65
#define _raw_write_lock_irq(lock) __raw_write_lock_irq(lock)
66 67 68
#endif

#ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE
69
#define _raw_read_lock_irqsave(lock) __raw_read_lock_irqsave(lock)
70 71 72
#endif

#ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE
73
#define _raw_write_lock_irqsave(lock) __raw_write_lock_irqsave(lock)
74 75 76
#endif

#ifdef CONFIG_INLINE_READ_TRYLOCK
77
#define _raw_read_trylock(lock) __raw_read_trylock(lock)
78 79 80
#endif

#ifdef CONFIG_INLINE_WRITE_TRYLOCK
81
#define _raw_write_trylock(lock) __raw_write_trylock(lock)
82 83 84
#endif

#ifdef CONFIG_INLINE_READ_UNLOCK
85
#define _raw_read_unlock(lock) __raw_read_unlock(lock)
86 87 88
#endif

#ifdef CONFIG_INLINE_WRITE_UNLOCK
89
#define _raw_write_unlock(lock) __raw_write_unlock(lock)
90 91 92
#endif

#ifdef CONFIG_INLINE_READ_UNLOCK_BH
93
#define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock)
94 95 96
#endif

#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH
97
#define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock)
98 99 100
#endif

#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ
101
#define _raw_read_unlock_irq(lock) __raw_read_unlock_irq(lock)
102 103 104
#endif

#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ
105
#define _raw_write_unlock_irq(lock) __raw_write_unlock_irq(lock)
106 107 108
#endif

#ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE
109 110
#define _raw_read_unlock_irqrestore(lock, flags) \
	__raw_read_unlock_irqrestore(lock, flags)
111 112 113
#endif

#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE
114 115
#define _raw_write_unlock_irqrestore(lock, flags) \
	__raw_write_unlock_irqrestore(lock, flags)
116 117
#endif

118
static inline int __raw_read_trylock(rwlock_t *lock)
119 120
{
	preempt_disable();
121
	if (do_raw_read_trylock(lock)) {
122 123 124 125 126 127 128
		rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_);
		return 1;
	}
	preempt_enable();
	return 0;
}

129
static inline int __raw_write_trylock(rwlock_t *lock)
130 131
{
	preempt_disable();
132
	if (do_raw_write_trylock(lock)) {
133 134 135 136 137 138 139 140 141 142 143 144 145 146
		rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_);
		return 1;
	}
	preempt_enable();
	return 0;
}

/*
 * If lockdep is enabled then we use the non-preemption spin-ops
 * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are
 * not re-enabled during lock-acquire (which the preempt-spin-ops do):
 */
#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)

147
static inline void __raw_read_lock(rwlock_t *lock)
148 149 150
{
	preempt_disable();
	rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
151
	LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
152 153
}

154
static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock)
155 156 157 158 159 160
{
	unsigned long flags;

	local_irq_save(flags);
	preempt_disable();
	rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
161
	LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
162 163 164
	return flags;
}

165
static inline void __raw_read_lock_irq(rwlock_t *lock)
166 167 168 169
{
	local_irq_disable();
	preempt_disable();
	rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
170
	LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
171 172
}

173
static inline void __raw_read_lock_bh(rwlock_t *lock)
174
{
175
	__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
176
	rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
177
	LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
178 179
}

180
static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock)
181 182 183 184 185 186
{
	unsigned long flags;

	local_irq_save(flags);
	preempt_disable();
	rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
187
	LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
188 189 190
	return flags;
}

191
static inline void __raw_write_lock_irq(rwlock_t *lock)
192 193 194 195
{
	local_irq_disable();
	preempt_disable();
	rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
196
	LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
197 198
}

199
static inline void __raw_write_lock_bh(rwlock_t *lock)
200
{
201
	__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
202
	rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
203
	LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
204 205
}

206
static inline void __raw_write_lock(rwlock_t *lock)
207 208 209
{
	preempt_disable();
	rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
210
	LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
211 212
}

213 214 215 216 217 218 219
static inline void __raw_write_lock_nested(rwlock_t *lock, int subclass)
{
	preempt_disable();
	rwlock_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
	LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
}

C
Cheng Jian 已提交
220
#endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */
221

222
static inline void __raw_write_unlock(rwlock_t *lock)
223
{
224
	rwlock_release(&lock->dep_map, _RET_IP_);
225
	do_raw_write_unlock(lock);
226 227 228
	preempt_enable();
}

229
static inline void __raw_read_unlock(rwlock_t *lock)
230
{
231
	rwlock_release(&lock->dep_map, _RET_IP_);
232
	do_raw_read_unlock(lock);
233 234 235
	preempt_enable();
}

236 237
static inline void
__raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
238
{
239
	rwlock_release(&lock->dep_map, _RET_IP_);
240
	do_raw_read_unlock(lock);
241 242 243 244
	local_irq_restore(flags);
	preempt_enable();
}

245
static inline void __raw_read_unlock_irq(rwlock_t *lock)
246
{
247
	rwlock_release(&lock->dep_map, _RET_IP_);
248
	do_raw_read_unlock(lock);
249 250 251 252
	local_irq_enable();
	preempt_enable();
}

253
static inline void __raw_read_unlock_bh(rwlock_t *lock)
254
{
255
	rwlock_release(&lock->dep_map, _RET_IP_);
256
	do_raw_read_unlock(lock);
257
	__local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
258 259
}

260
static inline void __raw_write_unlock_irqrestore(rwlock_t *lock,
261 262
					     unsigned long flags)
{
263
	rwlock_release(&lock->dep_map, _RET_IP_);
264
	do_raw_write_unlock(lock);
265 266 267 268
	local_irq_restore(flags);
	preempt_enable();
}

269
static inline void __raw_write_unlock_irq(rwlock_t *lock)
270
{
271
	rwlock_release(&lock->dep_map, _RET_IP_);
272
	do_raw_write_unlock(lock);
273 274 275 276
	local_irq_enable();
	preempt_enable();
}

277
static inline void __raw_write_unlock_bh(rwlock_t *lock)
278
{
279
	rwlock_release(&lock->dep_map, _RET_IP_);
280
	do_raw_write_unlock(lock);
281
	__local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
282 283 284
}

#endif /* __LINUX_RWLOCK_API_SMP_H */