pcounter.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  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. #include <linux/module.h>
  7. #include <linux/pcounter.h>
  8. #include <linux/smp.h>
  9. #include <linux/cpumask.h>
  10. static void pcounter_dyn_add(struct pcounter *self, int inc)
  11. {
  12. per_cpu_ptr(self->per_cpu_values, smp_processor_id())[0] += inc;
  13. }
  14. static int pcounter_dyn_getval(const struct pcounter *self, int cpu)
  15. {
  16. return per_cpu_ptr(self->per_cpu_values, cpu)[0];
  17. }
  18. int pcounter_getval(const struct pcounter *self)
  19. {
  20. int res = 0, cpu;
  21. for_each_possible_cpu(cpu)
  22. res += self->getval(self, cpu);
  23. return res;
  24. }
  25. EXPORT_SYMBOL_GPL(pcounter_getval);
  26. int pcounter_alloc(struct pcounter *self)
  27. {
  28. int rc = 0;
  29. if (self->add == NULL) {
  30. self->per_cpu_values = alloc_percpu(int);
  31. if (self->per_cpu_values != NULL) {
  32. self->add = pcounter_dyn_add;
  33. self->getval = pcounter_dyn_getval;
  34. } else
  35. rc = 1;
  36. }
  37. return rc;
  38. }
  39. EXPORT_SYMBOL_GPL(pcounter_alloc);
  40. void pcounter_free(struct pcounter *self)
  41. {
  42. if (self->per_cpu_values != NULL) {
  43. free_percpu(self->per_cpu_values);
  44. self->per_cpu_values = NULL;
  45. self->getval = NULL;
  46. self->add = NULL;
  47. }
  48. }
  49. EXPORT_SYMBOL_GPL(pcounter_free);