Blame view

include/linux/spinlock.h 10.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  #ifndef __LINUX_SPINLOCK_H
  #define __LINUX_SPINLOCK_H
  
  /*
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
5
6
7
8
9
10
   * include/linux/spinlock.h - generic spinlock/rwlock declarations
   *
   * here's the role of the various spinlock/rwlock related include files:
   *
   * on SMP builds:
   *
fb3a6bbc9   Thomas Gleixner   locking: Convert ...
11
   *  asm/spinlock_types.h: contains the arch_spinlock_t/arch_rwlock_t and the
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
12
13
14
15
16
   *                        initializers
   *
   *  linux/spinlock_types.h:
   *                        defines the generic type and initializers
   *
0199c4e68   Thomas Gleixner   locking: Convert ...
17
   *  asm/spinlock.h:       contains the arch_spin_*()/etc. lowlevel
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
   *                        implementations, mostly inline assembly code
   *
   *   (also included on UP-debug builds:)
   *
   *  linux/spinlock_api_smp.h:
   *                        contains the prototypes for the _spin_*() APIs.
   *
   *  linux/spinlock.h:     builds the final spin_*() APIs.
   *
   * on UP builds:
   *
   *  linux/spinlock_type_up.h:
   *                        contains the generic, simplified UP spinlock type.
   *                        (which is an empty structure on non-debug builds)
   *
   *  linux/spinlock_types.h:
   *                        defines the generic type and initializers
   *
   *  linux/spinlock_up.h:
0199c4e68   Thomas Gleixner   locking: Convert ...
37
   *                        contains the arch_spin_*()/etc. version of UP
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
38
39
40
41
42
43
44
45
46
   *                        builds. (which are NOPs on non-debug, non-preempt
   *                        builds)
   *
   *   (included on UP-non-debug builds:)
   *
   *  linux/spinlock_api_up.h:
   *                        builds the _spin_*() APIs.
   *
   *  linux/spinlock.h:     builds the final spin_*() APIs.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
   */
3f307891c   Steven Rostedt   locking: add type...
48
  #include <linux/typecheck.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
54
  #include <linux/preempt.h>
  #include <linux/linkage.h>
  #include <linux/compiler.h>
  #include <linux/thread_info.h>
  #include <linux/kernel.h>
  #include <linux/stringify.h>
676dcb8bc   Andrew Morton   [PATCH] add botto...
55
  #include <linux/bottom_half.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
  #include <asm/system.h>
  
  /*
   * Must define these before including other files, inline functions need them
   */
75ddb0e87   Denys Vlasenko   Rename .text.lock...
62
  #define LOCK_SECTION_NAME ".text..lock."KBUILD_BASENAME
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  
  #define LOCK_SECTION_START(extra)               \
          ".subsection 1
  \t"                     \
          extra                                   \
          ".ifndef " LOCK_SECTION_NAME "
  \t"     \
          LOCK_SECTION_NAME ":
  \t"               \
          ".endif
  "
  
  #define LOCK_SECTION_END                        \
          ".previous
  \t"
ec7015840   Harvey Harrison   Remove fastcall f...
78
  #define __lockfunc __attribute__((section(".spinlock.text")))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
  
  /*
fb3a6bbc9   Thomas Gleixner   locking: Convert ...
81
   * Pull the arch_spinlock_t and arch_rwlock_t definitions:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
   */
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
83
  #include <linux/spinlock_types.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  /*
c2f21ce2e   Thomas Gleixner   locking: Implemen...
86
   * Pull the arch_spin*() functions/declarations (UP-nondebug doesnt need them):
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
   */
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
88
  #ifdef CONFIG_SMP
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
89
  # include <asm/spinlock.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  #else
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
91
  # include <linux/spinlock_up.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  #endif
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
93
  #ifdef CONFIG_DEBUG_SPINLOCK
c2f21ce2e   Thomas Gleixner   locking: Implemen...
94
95
96
    extern void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
  				   struct lock_class_key *key);
  # define raw_spin_lock_init(lock)				\
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
97
98
99
  do {								\
  	static struct lock_class_key __key;			\
  								\
c2f21ce2e   Thomas Gleixner   locking: Implemen...
100
  	__raw_spin_lock_init((lock), #lock, &__key);		\
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
101
102
103
  } while (0)
  
  #else
c2f21ce2e   Thomas Gleixner   locking: Implemen...
104
105
  # define raw_spin_lock_init(lock)				\
  	do { *(lock) = __RAW_SPIN_LOCK_UNLOCKED(lock); } while (0)
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
106
  #endif
c2f21ce2e   Thomas Gleixner   locking: Implemen...
107
  #define raw_spin_is_locked(lock)	arch_spin_is_locked(&(lock)->raw_lock)
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
108

95c354fe9   Nick Piggin   spinlock: lockbre...
109
  #ifdef CONFIG_GENERIC_LOCKBREAK
c2f21ce2e   Thomas Gleixner   locking: Implemen...
110
  #define raw_spin_is_contended(lock) ((lock)->break_lock)
95c354fe9   Nick Piggin   spinlock: lockbre...
111
  #else
a5ef7ca0e   Kyle McMartin   x86: spinlocks: d...
112

0199c4e68   Thomas Gleixner   locking: Convert ...
113
  #ifdef arch_spin_is_contended
c2f21ce2e   Thomas Gleixner   locking: Implemen...
114
  #define raw_spin_is_contended(lock)	arch_spin_is_contended(&(lock)->raw_lock)
a5ef7ca0e   Kyle McMartin   x86: spinlocks: d...
115
  #else
c2f21ce2e   Thomas Gleixner   locking: Implemen...
116
  #define raw_spin_is_contended(lock)	(((void)(lock), 0))
0199c4e68   Thomas Gleixner   locking: Convert ...
117
  #endif /*arch_spin_is_contended*/
95c354fe9   Nick Piggin   spinlock: lockbre...
118
  #endif
ad4627695   Jiri Olsa   memory barrier: a...
119
120
121
122
  /* The lock does not imply full memory barrier. */
  #ifndef ARCH_HAS_SMP_MB_AFTER_LOCK
  static inline void smp_mb__after_lock(void) { smp_mb(); }
  #endif
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
123
  /**
c2f21ce2e   Thomas Gleixner   locking: Implemen...
124
   * raw_spin_unlock_wait - wait until the spinlock gets unlocked
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
125
126
   * @lock: the spinlock in question.
   */
c2f21ce2e   Thomas Gleixner   locking: Implemen...
127
  #define raw_spin_unlock_wait(lock)	arch_spin_unlock_wait(&(lock)->raw_lock)
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
128

fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
129
  #ifdef CONFIG_DEBUG_SPINLOCK
b97c4bc16   Luca Barbieri   locking: Make spa...
130
   extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock);
9828ea9d7   Thomas Gleixner   locking: Further ...
131
132
  #define do_raw_spin_lock_flags(lock, flags) do_raw_spin_lock(lock)
   extern int do_raw_spin_trylock(raw_spinlock_t *lock);
b97c4bc16   Luca Barbieri   locking: Make spa...
133
   extern void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock);
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
134
  #else
b97c4bc16   Luca Barbieri   locking: Make spa...
135
  static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
c2f21ce2e   Thomas Gleixner   locking: Implemen...
136
  {
b97c4bc16   Luca Barbieri   locking: Make spa...
137
  	__acquire(lock);
c2f21ce2e   Thomas Gleixner   locking: Implemen...
138
139
140
141
  	arch_spin_lock(&lock->raw_lock);
  }
  
  static inline void
b97c4bc16   Luca Barbieri   locking: Make spa...
142
  do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) __acquires(lock)
c2f21ce2e   Thomas Gleixner   locking: Implemen...
143
  {
b97c4bc16   Luca Barbieri   locking: Make spa...
144
  	__acquire(lock);
c2f21ce2e   Thomas Gleixner   locking: Implemen...
145
146
  	arch_spin_lock_flags(&lock->raw_lock, *flags);
  }
9828ea9d7   Thomas Gleixner   locking: Further ...
147
  static inline int do_raw_spin_trylock(raw_spinlock_t *lock)
c2f21ce2e   Thomas Gleixner   locking: Implemen...
148
149
150
  {
  	return arch_spin_trylock(&(lock)->raw_lock);
  }
b97c4bc16   Luca Barbieri   locking: Make spa...
151
  static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)
c2f21ce2e   Thomas Gleixner   locking: Implemen...
152
153
  {
  	arch_spin_unlock(&lock->raw_lock);
b97c4bc16   Luca Barbieri   locking: Make spa...
154
  	__release(lock);
c2f21ce2e   Thomas Gleixner   locking: Implemen...
155
  }
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
156
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  /*
ef12f1099   Thomas Gleixner   locking: Split rw...
159
160
161
162
   * Define the various spin_lock methods.  Note we define these
   * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The
   * various methods are defined as nops in the case they are not
   * required.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
   */
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
164
  #define raw_spin_trylock(lock)	__cond_lock(lock, _raw_spin_trylock(lock))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165

9c1721aa4   Thomas Gleixner   locking: Cleanup ...
166
  #define raw_spin_lock(lock)	_raw_spin_lock(lock)
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
167
168
  
  #ifdef CONFIG_DEBUG_LOCK_ALLOC
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
169
170
  # define raw_spin_lock_nested(lock, subclass) \
  	_raw_spin_lock_nested(lock, subclass)
c2f21ce2e   Thomas Gleixner   locking: Implemen...
171
  # define raw_spin_lock_nest_lock(lock, nest_lock)			\
b7d39aff9   Peter Zijlstra   lockdep: spin_loc...
172
173
  	 do {								\
  		 typecheck(struct lockdep_map *, &(nest_lock)->dep_map);\
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
174
  		 _raw_spin_lock_nest_lock(lock, &(nest_lock)->dep_map);	\
b7d39aff9   Peter Zijlstra   lockdep: spin_loc...
175
  	 } while (0)
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
176
  #else
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
177
178
  # define raw_spin_lock_nested(lock, subclass)		_raw_spin_lock(lock)
  # define raw_spin_lock_nest_lock(lock, nest_lock)	_raw_spin_lock(lock)
8a25d5deb   Ingo Molnar   [PATCH] lockdep: ...
179
  #endif
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
180
  #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
b8e6ec865   Linus Torvalds   Revert "[PATCH] E...
181

c2f21ce2e   Thomas Gleixner   locking: Implemen...
182
  #define raw_spin_lock_irqsave(lock, flags)			\
3f307891c   Steven Rostedt   locking: add type...
183
184
  	do {						\
  		typecheck(unsigned long, flags);	\
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
185
  		flags = _raw_spin_lock_irqsave(lock);	\
3f307891c   Steven Rostedt   locking: add type...
186
  	} while (0)
cfd3ef234   Arjan van de Ven   [PATCH] lockdep: ...
187
188
  
  #ifdef CONFIG_DEBUG_LOCK_ALLOC
c2f21ce2e   Thomas Gleixner   locking: Implemen...
189
  #define raw_spin_lock_irqsave_nested(lock, flags, subclass)		\
3f307891c   Steven Rostedt   locking: add type...
190
191
  	do {								\
  		typecheck(unsigned long, flags);			\
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
192
  		flags = _raw_spin_lock_irqsave_nested(lock, subclass);	\
3f307891c   Steven Rostedt   locking: add type...
193
  	} while (0)
cfd3ef234   Arjan van de Ven   [PATCH] lockdep: ...
194
  #else
c2f21ce2e   Thomas Gleixner   locking: Implemen...
195
  #define raw_spin_lock_irqsave_nested(lock, flags, subclass)		\
3f307891c   Steven Rostedt   locking: add type...
196
197
  	do {								\
  		typecheck(unsigned long, flags);			\
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
198
  		flags = _raw_spin_lock_irqsave(lock);			\
3f307891c   Steven Rostedt   locking: add type...
199
  	} while (0)
cfd3ef234   Arjan van de Ven   [PATCH] lockdep: ...
200
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  #else
b8e6ec865   Linus Torvalds   Revert "[PATCH] E...
202

c2f21ce2e   Thomas Gleixner   locking: Implemen...
203
  #define raw_spin_lock_irqsave(lock, flags)		\
3f307891c   Steven Rostedt   locking: add type...
204
205
  	do {						\
  		typecheck(unsigned long, flags);	\
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
206
  		_raw_spin_lock_irqsave(lock, flags);	\
3f307891c   Steven Rostedt   locking: add type...
207
  	} while (0)
ef12f1099   Thomas Gleixner   locking: Split rw...
208

c2f21ce2e   Thomas Gleixner   locking: Implemen...
209
210
  #define raw_spin_lock_irqsave_nested(lock, flags, subclass)	\
  	raw_spin_lock_irqsave(lock, flags)
cfd3ef234   Arjan van de Ven   [PATCH] lockdep: ...
211

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
  #endif
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
213
214
215
216
  #define raw_spin_lock_irq(lock)		_raw_spin_lock_irq(lock)
  #define raw_spin_lock_bh(lock)		_raw_spin_lock_bh(lock)
  #define raw_spin_unlock(lock)		_raw_spin_unlock(lock)
  #define raw_spin_unlock_irq(lock)	_raw_spin_unlock_irq(lock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217

c2f21ce2e   Thomas Gleixner   locking: Implemen...
218
219
220
  #define raw_spin_unlock_irqrestore(lock, flags)		\
  	do {							\
  		typecheck(unsigned long, flags);		\
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
221
  		_raw_spin_unlock_irqrestore(lock, flags);	\
3f307891c   Steven Rostedt   locking: add type...
222
  	} while (0)
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
223
  #define raw_spin_unlock_bh(lock)	_raw_spin_unlock_bh(lock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224

9c1721aa4   Thomas Gleixner   locking: Cleanup ...
225
226
  #define raw_spin_trylock_bh(lock) \
  	__cond_lock(lock, _raw_spin_trylock_bh(lock))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227

c2f21ce2e   Thomas Gleixner   locking: Implemen...
228
  #define raw_spin_trylock_irq(lock) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
  ({ \
  	local_irq_disable(); \
c2f21ce2e   Thomas Gleixner   locking: Implemen...
231
  	raw_spin_trylock(lock) ? \
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
232
  	1 : ({ local_irq_enable(); 0;  }); \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  })
c2f21ce2e   Thomas Gleixner   locking: Implemen...
234
  #define raw_spin_trylock_irqsave(lock, flags) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
  ({ \
  	local_irq_save(flags); \
c2f21ce2e   Thomas Gleixner   locking: Implemen...
237
  	raw_spin_trylock(lock) ? \
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
238
  	1 : ({ local_irq_restore(flags); 0; }); \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
  })
c2f21ce2e   Thomas Gleixner   locking: Implemen...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  /**
   * raw_spin_can_lock - would raw_spin_trylock() succeed?
   * @lock: the spinlock in question.
   */
  #define raw_spin_can_lock(lock)	(!raw_spin_is_locked(lock))
  
  /* Include rwlock functions */
  #include <linux/rwlock.h>
  
  /*
   * Pull the _spin_*()/_read_*()/_write_*() functions/declarations:
   */
  #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
  # include <linux/spinlock_api_smp.h>
  #else
  # include <linux/spinlock_api_up.h>
  #endif
  
  /*
   * Map the spin_lock functions to the raw variants for PREEMPT_RT=n
   */
  
  static inline raw_spinlock_t *spinlock_check(spinlock_t *lock)
  {
  	return &lock->rlock;
  }
  
  #define spin_lock_init(_lock)				\
  do {							\
  	spinlock_check(_lock);				\
  	raw_spin_lock_init(&(_lock)->rlock);		\
  } while (0)
  
  static inline void spin_lock(spinlock_t *lock)
  {
  	raw_spin_lock(&lock->rlock);
  }
  
  static inline void spin_lock_bh(spinlock_t *lock)
  {
  	raw_spin_lock_bh(&lock->rlock);
  }
  
  static inline int spin_trylock(spinlock_t *lock)
  {
  	return raw_spin_trylock(&lock->rlock);
  }
  
  #define spin_lock_nested(lock, subclass)			\
  do {								\
  	raw_spin_lock_nested(spinlock_check(lock), subclass);	\
  } while (0)
  
  #define spin_lock_nest_lock(lock, nest_lock)				\
  do {									\
  	raw_spin_lock_nest_lock(spinlock_check(lock), nest_lock);	\
  } while (0)
  
  static inline void spin_lock_irq(spinlock_t *lock)
  {
  	raw_spin_lock_irq(&lock->rlock);
  }
  
  #define spin_lock_irqsave(lock, flags)				\
  do {								\
  	raw_spin_lock_irqsave(spinlock_check(lock), flags);	\
  } while (0)
  
  #define spin_lock_irqsave_nested(lock, flags, subclass)			\
  do {									\
  	raw_spin_lock_irqsave_nested(spinlock_check(lock), flags, subclass); \
  } while (0)
  
  static inline void spin_unlock(spinlock_t *lock)
  {
  	raw_spin_unlock(&lock->rlock);
  }
  
  static inline void spin_unlock_bh(spinlock_t *lock)
  {
  	raw_spin_unlock_bh(&lock->rlock);
  }
  
  static inline void spin_unlock_irq(spinlock_t *lock)
  {
  	raw_spin_unlock_irq(&lock->rlock);
  }
  
  static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
  {
  	raw_spin_unlock_irqrestore(&lock->rlock, flags);
  }
  
  static inline int spin_trylock_bh(spinlock_t *lock)
  {
  	return raw_spin_trylock_bh(&lock->rlock);
  }
  
  static inline int spin_trylock_irq(spinlock_t *lock)
  {
  	return raw_spin_trylock_irq(&lock->rlock);
  }
  
  #define spin_trylock_irqsave(lock, flags)			\
  ({								\
  	raw_spin_trylock_irqsave(spinlock_check(lock), flags); \
  })
  
  static inline void spin_unlock_wait(spinlock_t *lock)
  {
  	raw_spin_unlock_wait(&lock->rlock);
  }
  
  static inline int spin_is_locked(spinlock_t *lock)
  {
  	return raw_spin_is_locked(&lock->rlock);
  }
  
  static inline int spin_is_contended(spinlock_t *lock)
  {
  	return raw_spin_is_contended(&lock->rlock);
  }
  
  static inline int spin_can_lock(spinlock_t *lock)
  {
  	return raw_spin_can_lock(&lock->rlock);
  }
  
  static inline void assert_spin_locked(spinlock_t *lock)
  {
  	assert_raw_spin_locked(&lock->rlock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
  /*
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
373
374
   * Pull the atomic_t declaration:
   * (asm-mips/atomic.h needs above definitions)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
   */
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
376
377
378
379
380
  #include <asm/atomic.h>
  /**
   * atomic_dec_and_lock - lock on reaching reference count zero
   * @atomic: the atomic counter
   * @lock: the spinlock in question
dc07e721a   J. Bruce Fields   Spell out behavio...
381
382
383
   *
   * Decrements @atomic by 1.  If the result is 0, returns true and locks
   * @lock.  Returns false for all other cases.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
   */
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
385
386
  extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
  #define atomic_dec_and_lock(atomic, lock) \
dcc8e559e   Josh Triplett   [PATCH] Pass a lo...
387
  		__cond_lock(lock, _atomic_dec_and_lock(atomic, lock))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
  #endif /* __LINUX_SPINLOCK_H */