percpu_counter.c 964 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /*
  2. * Fast batching percpu counters.
  3. */
  4. #include <linux/percpu_counter.h>
  5. #include <linux/module.h>
  6. void percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
  7. {
  8. long count;
  9. s32 *pcount;
  10. int cpu = get_cpu();
  11. pcount = per_cpu_ptr(fbc->counters, cpu);
  12. count = *pcount + amount;
  13. if (count >= FBC_BATCH || count <= -FBC_BATCH) {
  14. spin_lock(&fbc->lock);
  15. fbc->count += count;
  16. *pcount = 0;
  17. spin_unlock(&fbc->lock);
  18. } else {
  19. *pcount = count;
  20. }
  21. put_cpu();
  22. }
  23. EXPORT_SYMBOL(percpu_counter_mod);
  24. /*
  25. * Add up all the per-cpu counts, return the result. This is a more accurate
  26. * but much slower version of percpu_counter_read_positive()
  27. */
  28. s64 percpu_counter_sum(struct percpu_counter *fbc)
  29. {
  30. s64 ret;
  31. int cpu;
  32. spin_lock(&fbc->lock);
  33. ret = fbc->count;
  34. for_each_possible_cpu(cpu) {
  35. s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
  36. ret += *pcount;
  37. }
  38. spin_unlock(&fbc->lock);
  39. return ret < 0 ? 0 : ret;
  40. }
  41. EXPORT_SYMBOL(percpu_counter_sum);