rwlock_api_smp.h 7.63 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 161
	LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock,
			     do_raw_read_lock_flags, &flags);
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 188
	LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock,
			     do_raw_write_lock_flags, &flags);
189 190 191
	return flags;
}

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

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

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

#endif /* CONFIG_PREEMPT */

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

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

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

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

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

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

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

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

#endif /* __LINUX_RWLOCK_API_SMP_H */