]>
Commit | Line | Data |
---|---|---|
de4d1db3 ACM |
1 | /* |
2 | * Define default pcounter functions | |
3 | * Note that often used pcounters use dedicated functions to get a speed increase. | |
4 | * (see DEFINE_PCOUNTER/REF_PCOUNTER_MEMBER) | |
5 | */ | |
6 | ||
7 | #include <linux/module.h> | |
8 | #include <linux/pcounter.h> | |
9 | #include <linux/smp.h> | |
571e7682 | 10 | #include <linux/cpumask.h> |
de4d1db3 | 11 | |
571e7682 | 12 | static void pcounter_dyn_add(struct pcounter *self, int inc) |
de4d1db3 ACM |
13 | { |
14 | per_cpu_ptr(self->per_cpu_values, smp_processor_id())[0] += inc; | |
15 | } | |
16 | ||
571e7682 ED |
17 | static int pcounter_dyn_getval(const struct pcounter *self, int cpu) |
18 | { | |
19 | return per_cpu_ptr(self->per_cpu_values, cpu)[0]; | |
20 | } | |
de4d1db3 | 21 | |
571e7682 | 22 | int pcounter_getval(const struct pcounter *self) |
de4d1db3 ACM |
23 | { |
24 | int res = 0, cpu; | |
571e7682 | 25 | |
de4d1db3 | 26 | for_each_possible_cpu(cpu) |
571e7682 ED |
27 | res += self->getval(self, cpu); |
28 | ||
de4d1db3 ACM |
29 | return res; |
30 | } | |
571e7682 ED |
31 | EXPORT_SYMBOL_GPL(pcounter_getval); |
32 | ||
33 | int pcounter_alloc(struct pcounter *self) | |
34 | { | |
35 | int rc = 0; | |
36 | if (self->add == NULL) { | |
37 | self->per_cpu_values = alloc_percpu(int); | |
38 | if (self->per_cpu_values != NULL) { | |
39 | self->add = pcounter_dyn_add; | |
40 | self->getval = pcounter_dyn_getval; | |
41 | } else | |
42 | rc = 1; | |
43 | } | |
44 | return rc; | |
45 | } | |
46 | EXPORT_SYMBOL_GPL(pcounter_alloc); | |
47 | ||
48 | void pcounter_free(struct pcounter *self) | |
49 | { | |
50 | if (self->per_cpu_values != NULL) { | |
51 | free_percpu(self->per_cpu_values); | |
52 | self->per_cpu_values = NULL; | |
53 | self->getval = NULL; | |
54 | self->add = NULL; | |
55 | } | |
56 | } | |
57 | EXPORT_SYMBOL_GPL(pcounter_free); | |
de4d1db3 | 58 |