Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dec_and_lock.c
Go to the documentation of this file.
1 #include <linux/export.h>
2 #include <linux/spinlock.h>
3 #include <linux/atomic.h>
4 
5 /*
6  * This is an implementation of the notion of "decrement a
7  * reference count, and return locked if it decremented to zero".
8  *
9  * NOTE NOTE NOTE! This is _not_ equivalent to
10  *
11  * if (atomic_dec_and_test(&atomic)) {
12  * spin_lock(&lock);
13  * return 1;
14  * }
15  * return 0;
16  *
17  * because the spin-lock and the decrement must be
18  * "atomic".
19  */
21 {
22  /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */
23  if (atomic_add_unless(atomic, -1, 1))
24  return 0;
25 
26  /* Otherwise do it the slow way */
27  spin_lock(lock);
28  if (atomic_dec_and_test(atomic))
29  return 1;
30  spin_unlock(lock);
31  return 0;
32 }
33