ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / linux / netfilter_ipv4 / lockhelp.h
1 #ifndef _LOCKHELP_H
2 #define _LOCKHELP_H
3 #include <linux/config.h>
4
5 #include <linux/spinlock.h>
6 #include <asm/atomic.h>
7 #include <linux/interrupt.h>
8 #include <linux/smp.h>
9
10 /* Header to do help in lock debugging. */
11
12 #ifdef CONFIG_NETFILTER_DEBUG
13 struct spinlock_debug
14 {
15         spinlock_t l;
16         atomic_t locked_by;
17 };
18
19 struct rwlock_debug
20 {
21         rwlock_t l;
22         long read_locked_map;
23         long write_locked_map;
24 };
25
26 #define DECLARE_LOCK(l)                                                 \
27 struct spinlock_debug l = { SPIN_LOCK_UNLOCKED, ATOMIC_INIT(-1) }
28 #define DECLARE_LOCK_EXTERN(l)                  \
29 extern struct spinlock_debug l
30 #define DECLARE_RWLOCK(l)                               \
31 struct rwlock_debug l = { RW_LOCK_UNLOCKED, 0, 0 }
32 #define DECLARE_RWLOCK_EXTERN(l)                \
33 extern struct rwlock_debug l
34
35 #define MUST_BE_LOCKED(l)                                               \
36 do { if (atomic_read(&(l)->locked_by) != smp_processor_id())            \
37         printk("ASSERT %s:%u %s unlocked\n", __FILE__, __LINE__, #l);   \
38 } while(0)
39
40 #define MUST_BE_UNLOCKED(l)                                             \
41 do { if (atomic_read(&(l)->locked_by) == smp_processor_id())            \
42         printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l);     \
43 } while(0)
44
45 /* Write locked OK as well. */
46 #define MUST_BE_READ_LOCKED(l)                                              \
47 do { if (!((l)->read_locked_map & (1UL << smp_processor_id()))              \
48          && !((l)->write_locked_map & (1UL << smp_processor_id())))         \
49         printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \
50 } while(0)
51
52 #define MUST_BE_WRITE_LOCKED(l)                                              \
53 do { if (!((l)->write_locked_map & (1UL << smp_processor_id())))             \
54         printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \
55 } while(0)
56
57 #define MUST_BE_READ_WRITE_UNLOCKED(l)                                    \
58 do { if ((l)->read_locked_map & (1UL << smp_processor_id()))              \
59         printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l);   \
60  else if ((l)->write_locked_map & (1UL << smp_processor_id()))            \
61          printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \
62 } while(0)
63
64 #define LOCK_BH(lk)                                             \
65 do {                                                            \
66         MUST_BE_UNLOCKED(lk);                                   \
67         spin_lock_bh(&(lk)->l);                                 \
68         atomic_set(&(lk)->locked_by, smp_processor_id());       \
69 } while(0)
70
71 #define UNLOCK_BH(lk)                           \
72 do {                                            \
73         MUST_BE_LOCKED(lk);                     \
74         atomic_set(&(lk)->locked_by, -1);       \
75         spin_unlock_bh(&(lk)->l);               \
76 } while(0)
77
78 #define READ_LOCK(lk)                                           \
79 do {                                                            \
80         MUST_BE_READ_WRITE_UNLOCKED(lk);                        \
81         read_lock_bh(&(lk)->l);                                 \
82         set_bit(smp_processor_id(), &(lk)->read_locked_map);    \
83 } while(0)
84
85 #define WRITE_LOCK(lk)                                                    \
86 do {                                                                      \
87         MUST_BE_READ_WRITE_UNLOCKED(lk);                                  \
88         write_lock_bh(&(lk)->l);                                          \
89         set_bit(smp_processor_id(), &(lk)->write_locked_map);             \
90 } while(0)
91
92 #define READ_UNLOCK(lk)                                                 \
93 do {                                                                    \
94         if (!((lk)->read_locked_map & (1UL << smp_processor_id())))     \
95                 printk("ASSERT: %s:%u %s not readlocked\n",             \
96                        __FILE__, __LINE__, #lk);                        \
97         clear_bit(smp_processor_id(), &(lk)->read_locked_map);          \
98         read_unlock_bh(&(lk)->l);                                       \
99 } while(0)
100
101 #define WRITE_UNLOCK(lk)                                        \
102 do {                                                            \
103         MUST_BE_WRITE_LOCKED(lk);                               \
104         clear_bit(smp_processor_id(), &(lk)->write_locked_map); \
105         write_unlock_bh(&(lk)->l);                              \
106 } while(0)
107
108 #else
109 #define DECLARE_LOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED
110 #define DECLARE_LOCK_EXTERN(l) extern spinlock_t l
111 #define DECLARE_RWLOCK(l) rwlock_t l = RW_LOCK_UNLOCKED
112 #define DECLARE_RWLOCK_EXTERN(l) extern rwlock_t l
113
114 #define MUST_BE_LOCKED(l)
115 #define MUST_BE_UNLOCKED(l)
116 #define MUST_BE_READ_LOCKED(l)
117 #define MUST_BE_WRITE_LOCKED(l)
118 #define MUST_BE_READ_WRITE_UNLOCKED(l)
119
120 #define LOCK_BH(l) spin_lock_bh(l)
121 #define UNLOCK_BH(l) spin_unlock_bh(l)
122
123 #define READ_LOCK(l) read_lock_bh(l)
124 #define WRITE_LOCK(l) write_lock_bh(l)
125 #define READ_UNLOCK(l) read_unlock_bh(l)
126 #define WRITE_UNLOCK(l) write_unlock_bh(l)
127 #endif /*CONFIG_NETFILTER_DEBUG*/
128
129 #endif /* _LOCKHELP_H */