at v2.6.23 108 lines 2.3 kB view raw
1#ifndef _LINUX_PERCPU_COUNTER_H 2#define _LINUX_PERCPU_COUNTER_H 3/* 4 * A simple "approximate counter" for use in ext2 and ext3 superblocks. 5 * 6 * WARNING: these things are HUGE. 4 kbytes per counter on 32-way P4. 7 */ 8 9#include <linux/spinlock.h> 10#include <linux/smp.h> 11#include <linux/list.h> 12#include <linux/threads.h> 13#include <linux/percpu.h> 14#include <linux/types.h> 15 16#ifdef CONFIG_SMP 17 18struct percpu_counter { 19 spinlock_t lock; 20 s64 count; 21#ifdef CONFIG_HOTPLUG_CPU 22 struct list_head list; /* All percpu_counters are on a list */ 23#endif 24 s32 *counters; 25}; 26 27#if NR_CPUS >= 16 28#define FBC_BATCH (NR_CPUS*2) 29#else 30#define FBC_BATCH (NR_CPUS*4) 31#endif 32 33void percpu_counter_init(struct percpu_counter *fbc, s64 amount); 34void percpu_counter_destroy(struct percpu_counter *fbc); 35void percpu_counter_mod(struct percpu_counter *fbc, s32 amount); 36s64 percpu_counter_sum(struct percpu_counter *fbc); 37 38static inline s64 percpu_counter_read(struct percpu_counter *fbc) 39{ 40 return fbc->count; 41} 42 43/* 44 * It is possible for the percpu_counter_read() to return a small negative 45 * number for some counter which should never be negative. 46 * 47 */ 48static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) 49{ 50 s64 ret = fbc->count; 51 52 barrier(); /* Prevent reloads of fbc->count */ 53 if (ret >= 0) 54 return ret; 55 return 1; 56} 57 58#else 59 60struct percpu_counter { 61 s64 count; 62}; 63 64static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount) 65{ 66 fbc->count = amount; 67} 68 69static inline void percpu_counter_destroy(struct percpu_counter *fbc) 70{ 71} 72 73static inline void 74percpu_counter_mod(struct percpu_counter *fbc, s32 amount) 75{ 76 preempt_disable(); 77 fbc->count += amount; 78 preempt_enable(); 79} 80 81static inline s64 percpu_counter_read(struct percpu_counter *fbc) 82{ 83 return fbc->count; 84} 85 86static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) 87{ 88 return fbc->count; 89} 90 91static inline s64 percpu_counter_sum(struct percpu_counter *fbc) 92{ 93 return percpu_counter_read_positive(fbc); 94} 95 96#endif /* CONFIG_SMP */ 97 98static inline void percpu_counter_inc(struct percpu_counter *fbc) 99{ 100 percpu_counter_mod(fbc, 1); 101} 102 103static inline void percpu_counter_dec(struct percpu_counter *fbc) 104{ 105 percpu_counter_mod(fbc, -1); 106} 107 108#endif /* _LINUX_PERCPU_COUNTER_H */