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
  #include <linux/preempt.h>
  #include <linux/linkage.h>
  #include <linux/compiler.h>
df9ee2927   David Howells   Fix IRQ flag hand...
52
  #include <linux/irqflags.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
55
  #include <linux/thread_info.h>
  #include <linux/kernel.h>
  #include <linux/stringify.h>
676dcb8bc   Andrew Morton   [PATCH] add botto...
56
  #include <linux/bottom_half.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57

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

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

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

0199c4e68   Thomas Gleixner   locking: Convert ...
114
  #ifdef arch_spin_is_contended
c2f21ce2e   Thomas Gleixner   locking: Implemen...
115
  #define raw_spin_is_contended(lock)	arch_spin_is_contended(&(lock)->raw_lock)
a5ef7ca0e   Kyle McMartin   x86: spinlocks: d...
116
  #else
c2f21ce2e   Thomas Gleixner   locking: Implemen...
117
  #define raw_spin_is_contended(lock)	(((void)(lock), 0))
0199c4e68   Thomas Gleixner   locking: Convert ...
118
  #endif /*arch_spin_is_contended*/
95c354fe9   Nick Piggin   spinlock: lockbre...
119
  #endif
ad4627695   Jiri Olsa   memory barrier: a...
120
121
122
123
  /* 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 ...
124
  /**
c2f21ce2e   Thomas Gleixner   locking: Implemen...
125
   * raw_spin_unlock_wait - wait until the spinlock gets unlocked
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
126
127
   * @lock: the spinlock in question.
   */
c2f21ce2e   Thomas Gleixner   locking: Implemen...
128
  #define raw_spin_unlock_wait(lock)	arch_spin_unlock_wait(&(lock)->raw_lock)
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
129

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  /*
ef12f1099   Thomas Gleixner   locking: Split rw...
160
161
162
163
   * 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
164
   */
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
165
  #define raw_spin_trylock(lock)	__cond_lock(lock, _raw_spin_trylock(lock))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166

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

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

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  #endif
9c1721aa4   Thomas Gleixner   locking: Cleanup ...
214
215
216
217
  #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
218

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

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

c2f21ce2e   Thomas Gleixner   locking: Implemen...
229
  #define raw_spin_trylock_irq(lock) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
  ({ \
  	local_irq_disable(); \
c2f21ce2e   Thomas Gleixner   locking: Implemen...
232
  	raw_spin_trylock(lock) ? \
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
233
  	1 : ({ local_irq_enable(); 0;  }); \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  })
c2f21ce2e   Thomas Gleixner   locking: Implemen...
235
  #define raw_spin_trylock_irqsave(lock, flags) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
  ({ \
  	local_irq_save(flags); \
c2f21ce2e   Thomas Gleixner   locking: Implemen...
238
  	raw_spin_trylock(lock) ? \
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
239
  	1 : ({ local_irq_restore(flags); 0; }); \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
  })
c2f21ce2e   Thomas Gleixner   locking: Implemen...
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
372
  /**
   * 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
373
  /*
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
374
375
   * Pull the atomic_t declaration:
   * (asm-mips/atomic.h needs above definitions)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
   */
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
377
378
379
380
381
  #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...
382
383
384
   *
   * 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
385
   */
fb1c8f93d   Ingo Molnar   [PATCH] spinlock ...
386
387
  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...
388
  		__cond_lock(lock, _atomic_dec_and_lock(atomic, lock))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389

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