2 * A simple "approximate counter" for use in ext2 and ext3 superblocks.
4 * WARNING: these things are HUGE. 4 kbytes per counter on 32-way P4.
7 #include <linux/config.h>
8 #include <linux/spinlock.h>
10 #include <linux/threads.h>
11 #include <linux/percpu.h>
15 struct percpu_counter {
22 #define FBC_BATCH (NR_CPUS*2)
24 #define FBC_BATCH (NR_CPUS*4)
27 static inline void percpu_counter_init(struct percpu_counter *fbc)
29 spin_lock_init(&fbc->lock);
31 fbc->counters = alloc_percpu(long);
34 static inline void percpu_counter_destroy(struct percpu_counter *fbc)
36 free_percpu(fbc->counters);
39 void percpu_counter_mod(struct percpu_counter *fbc, long amount);
41 static inline long percpu_counter_read(struct percpu_counter *fbc)
47 * It is possible for the percpu_counter_read() to return a small negative
48 * number for some counter which should never be negative.
50 static inline long percpu_counter_read_positive(struct percpu_counter *fbc)
52 long ret = fbc->count;
54 barrier(); /* Prevent reloads of fbc->count */
62 struct percpu_counter {
66 static inline void percpu_counter_init(struct percpu_counter *fbc)
71 static inline void percpu_counter_destroy(struct percpu_counter *fbc)
76 percpu_counter_mod(struct percpu_counter *fbc, long amount)
83 static inline long percpu_counter_read(struct percpu_counter *fbc)
88 static inline long percpu_counter_read_positive(struct percpu_counter *fbc)
93 #endif /* CONFIG_SMP */
95 static inline void percpu_counter_inc(struct percpu_counter *fbc)
97 percpu_counter_mod(fbc, 1);
100 static inline void percpu_counter_dec(struct percpu_counter *fbc)
102 percpu_counter_mod(fbc, -1);