rwlock_api_smp.h 7.6 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 20 21 22 23 24
void __lockfunc _raw_read_lock(rwlock_t *lock)		__acquires(lock);
void __lockfunc _raw_write_lock(rwlock_t *lock)		__acquires(lock);
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)
25
							__acquires(lock);
26
unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock)
27
							__acquires(lock);
28 29 30 31 32 33 34 35 36 37
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)
38
							__releases(lock);
39 40
void __lockfunc
_raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
41 42 43
							__releases(lock);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

128
static inline int __raw_write_trylock(rwlock_t *lock)
129 130
{
	preempt_disable();
131
	if (do_raw_write_trylock(lock)) {
132 133 134 135 136 137 138 139 140 141 142 143 144 145
		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)

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

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

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

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

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

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

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

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

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

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

C
Cheng Jian 已提交
212
#endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */
213

214
static inline void __raw_write_unlock(rwlock_t *lock)
215
{
216
	rwlock_release(&lock->dep_map, _RET_IP_);
217
	do_raw_write_unlock(lock);
218 219 220
	preempt_enable();
}

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

228 229
static inline void
__raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
230
{
231
	rwlock_release(&lock->dep_map, _RET_IP_);
232
	do_raw_read_unlock(lock);
233 234 235 236
	local_irq_restore(flags);
	preempt_enable();
}

237
static inline void __raw_read_unlock_irq(rwlock_t *lock)
238
{
239
	rwlock_release(&lock->dep_map, _RET_IP_);
240
	do_raw_read_unlock(lock);
241 242 243 244
	local_irq_enable();
	preempt_enable();
}

245
static inline void __raw_read_unlock_bh(rwlock_t *lock)
246
{
247
	rwlock_release(&lock->dep_map, _RET_IP_);
248
	do_raw_read_unlock(lock);
249
	__local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
250 251
}

252
static inline void __raw_write_unlock_irqrestore(rwlock_t *lock,
253 254
					     unsigned long flags)
{
255
	rwlock_release(&lock->dep_map, _RET_IP_);
256
	do_raw_write_unlock(lock);
257 258 259 260
	local_irq_restore(flags);
	preempt_enable();
}

261
static inline void __raw_write_unlock_irq(rwlock_t *lock)
262
{
263
	rwlock_release(&lock->dep_map, _RET_IP_);
264
	do_raw_write_unlock(lock);
265 266 267 268
	local_irq_enable();
	preempt_enable();
}

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

#endif /* __LINUX_RWLOCK_API_SMP_H */