[NETFILTER]: x_tables: add RATEEST target
[pandora-kernel.git] / include / linux / pcounter.h
1 #ifndef __LINUX_PCOUNTER_H
2 #define __LINUX_PCOUNTER_H
3
4 struct pcounter {
5 #ifdef CONFIG_SMP
6         void            (*add)(struct pcounter *self, int inc);
7         int             (*getval)(const struct pcounter *self);
8         int             *per_cpu_values;
9 #else
10         int             val;
11 #endif
12 };
13
14 /*
15  * Special macros to let pcounters use a fast version of {getvalue|add}
16  * using a static percpu variable per pcounter instead of an allocated one,
17  * saving one dereference.
18  * This might be changed if/when dynamic percpu vars become fast.
19  */
20 #ifdef CONFIG_SMP
21 #include <linux/cpumask.h>
22 #include <linux/percpu.h>
23
24 #define DEFINE_PCOUNTER(NAME)                                   \
25 static DEFINE_PER_CPU(int, NAME##_pcounter_values);             \
26 static void NAME##_pcounter_add(struct pcounter *self, int inc) \
27 {                                                               \
28        __get_cpu_var(NAME##_pcounter_values) += inc;            \
29 }                                                               \
30                                                                 \
31 static int NAME##_pcounter_getval(const struct pcounter *self)  \
32 {                                                               \
33        int res = 0, cpu;                                        \
34                                                                 \
35        for_each_possible_cpu(cpu)                               \
36                res += per_cpu(NAME##_pcounter_values, cpu);     \
37        return res;                                              \
38 }
39
40 #define PCOUNTER_MEMBER_INITIALIZER(NAME, MEMBER)               \
41         MEMBER = {                                              \
42                 .add    = NAME##_pcounter_add,                  \
43                 .getval = NAME##_pcounter_getval,               \
44         }
45
46 extern void pcounter_def_add(struct pcounter *self, int inc);
47 extern int pcounter_def_getval(const struct pcounter *self);
48
49 static inline int pcounter_alloc(struct pcounter *self)
50 {
51         int rc = 0;
52         if (self->add == NULL) {
53                 self->per_cpu_values = alloc_percpu(int);
54                 if (self->per_cpu_values != NULL) {
55                         self->add    = pcounter_def_add;
56                         self->getval = pcounter_def_getval;
57                 } else
58                         rc = 1;
59         }
60         return rc;
61 }
62
63 static inline void pcounter_free(struct pcounter *self)
64 {
65         if (self->per_cpu_values != NULL) {
66                 free_percpu(self->per_cpu_values);
67                 self->per_cpu_values = NULL;
68                 self->getval = NULL;
69                 self->add = NULL;
70         }
71 }
72
73 static inline void pcounter_add(struct pcounter *self, int inc)
74 {
75         self->add(self, inc);
76 }
77
78 static inline int pcounter_getval(const struct pcounter *self)
79 {
80         return self->getval(self);
81 }
82
83 #else /* CONFIG_SMP */
84
85 static inline void pcounter_add(struct pcounter *self, int inc)
86 {
87         self->val += inc;
88 }
89
90 static inline int pcounter_getval(const struct pcounter *self)
91 {
92         return self->val;
93 }
94
95 #define DEFINE_PCOUNTER(NAME)
96 #define PCOUNTER_MEMBER_INITIALIZER(NAME, MEMBER)
97 #define pcounter_alloc(self) 0
98 #define pcounter_free(self)
99
100 #endif /* CONFIG_SMP */
101
102 #endif /* __LINUX_PCOUNTER_H */