| /* | |
| * Define default pcounter functions | |
| * Note that often used pcounters use dedicated functions to get a speed increase. | |
| * (see DEFINE_PCOUNTER/REF_PCOUNTER_MEMBER) | |
| */ | |
| #include <linux/module.h> | |
| #include <linux/pcounter.h> | |
| #include <linux/smp.h> | |
| #include <linux/cpumask.h> | |
| static void pcounter_dyn_add(struct pcounter *self, int inc) | |
| { | |
| per_cpu_ptr(self->per_cpu_values, smp_processor_id())[0] += inc; | |
| } | |
| static int pcounter_dyn_getval(const struct pcounter *self, int cpu) | |
| { | |
| return per_cpu_ptr(self->per_cpu_values, cpu)[0]; | |
| } | |
| int pcounter_getval(const struct pcounter *self) | |
| { | |
| int res = 0, cpu; | |
| for_each_possible_cpu(cpu) | |
| res += self->getval(self, cpu); | |
| return res; | |
| } | |
| EXPORT_SYMBOL_GPL(pcounter_getval); | |
| int pcounter_alloc(struct pcounter *self) | |
| { | |
| int rc = 0; | |
| if (self->add == NULL) { | |
| self->per_cpu_values = alloc_percpu(int); | |
| if (self->per_cpu_values != NULL) { | |
| self->add = pcounter_dyn_add; | |
| self->getval = pcounter_dyn_getval; | |
| } else | |
| rc = 1; | |
| } | |
| return rc; | |
| } | |
| EXPORT_SYMBOL_GPL(pcounter_alloc); | |
| void pcounter_free(struct pcounter *self) | |
| { | |
| if (self->per_cpu_values != NULL) { | |
| free_percpu(self->per_cpu_values); | |
| self->per_cpu_values = NULL; | |
| self->getval = NULL; | |
| self->add = NULL; | |
| } | |
| } | |
| EXPORT_SYMBOL_GPL(pcounter_free); | |