diff options
-rw-r--r-- | include/linux/percpu_counter.h | 11 | ||||
-rw-r--r-- | lib/percpu_counter.c | 27 |
2 files changed, 38 insertions, 0 deletions
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index c88d67b59394..8a7d510ffa9c 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h | |||
@@ -40,6 +40,7 @@ void percpu_counter_destroy(struct percpu_counter *fbc); | |||
40 | void percpu_counter_set(struct percpu_counter *fbc, s64 amount); | 40 | void percpu_counter_set(struct percpu_counter *fbc, s64 amount); |
41 | void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); | 41 | void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); |
42 | s64 __percpu_counter_sum(struct percpu_counter *fbc); | 42 | s64 __percpu_counter_sum(struct percpu_counter *fbc); |
43 | int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs); | ||
43 | 44 | ||
44 | static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) | 45 | static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) |
45 | { | 46 | { |
@@ -98,6 +99,16 @@ static inline void percpu_counter_set(struct percpu_counter *fbc, s64 amount) | |||
98 | fbc->count = amount; | 99 | fbc->count = amount; |
99 | } | 100 | } |
100 | 101 | ||
102 | static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) | ||
103 | { | ||
104 | if (fbc->count > rhs) | ||
105 | return 1; | ||
106 | else if (fbc->count < rhs) | ||
107 | return -1; | ||
108 | else | ||
109 | return 0; | ||
110 | } | ||
111 | |||
101 | static inline void | 112 | static inline void |
102 | percpu_counter_add(struct percpu_counter *fbc, s64 amount) | 113 | percpu_counter_add(struct percpu_counter *fbc, s64 amount) |
103 | { | 114 | { |
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index aeaa6d734447..ec9048e74f44 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c | |||
@@ -137,6 +137,33 @@ static int __cpuinit percpu_counter_hotcpu_callback(struct notifier_block *nb, | |||
137 | return NOTIFY_OK; | 137 | return NOTIFY_OK; |
138 | } | 138 | } |
139 | 139 | ||
140 | /* | ||
141 | * Compare counter against given value. | ||
142 | * Return 1 if greater, 0 if equal and -1 if less | ||
143 | */ | ||
144 | int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) | ||
145 | { | ||
146 | s64 count; | ||
147 | |||
148 | count = percpu_counter_read(fbc); | ||
149 | /* Check to see if rough count will be sufficient for comparison */ | ||
150 | if (abs(count - rhs) > (percpu_counter_batch*num_online_cpus())) { | ||
151 | if (count > rhs) | ||
152 | return 1; | ||
153 | else | ||
154 | return -1; | ||
155 | } | ||
156 | /* Need to use precise count */ | ||
157 | count = percpu_counter_sum(fbc); | ||
158 | if (count > rhs) | ||
159 | return 1; | ||
160 | else if (count < rhs) | ||
161 | return -1; | ||
162 | else | ||
163 | return 0; | ||
164 | } | ||
165 | EXPORT_SYMBOL(percpu_counter_compare); | ||
166 | |||
140 | static int __init percpu_counter_startup(void) | 167 | static int __init percpu_counter_startup(void) |
141 | { | 168 | { |
142 | compute_batch_value(); | 169 | compute_batch_value(); |