]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/percpu_counter.h
percpu_counter: new function percpu_counter_sum_and_set
[linux-2.6-omap-h63xx.git] / include / linux / percpu_counter.h
index f5aa593ccf32fe358da38271e4a25d0653cfd8a0..20838883535704c89cf72bafe29a28d12dea45e3 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/smp.h>
+#include <linux/list.h>
 #include <linux/threads.h>
 #include <linux/percpu.h>
 #include <linux/types.h>
@@ -17,6 +18,9 @@
 struct percpu_counter {
        spinlock_t lock;
        s64 count;
+#ifdef CONFIG_HOTPLUG_CPU
+       struct list_head list;  /* All percpu_counters are on a list */
+#endif
        s32 *counters;
 };
 
@@ -26,20 +30,34 @@ struct percpu_counter {
 #define FBC_BATCH      (NR_CPUS*4)
 #endif
 
-static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
+int percpu_counter_init(struct percpu_counter *fbc, s64 amount);
+int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount);
+void percpu_counter_destroy(struct percpu_counter *fbc);
+void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
+void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
+s64 __percpu_counter_sum(struct percpu_counter *fbc, int set);
+
+static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
 {
-       spin_lock_init(&fbc->lock);
-       fbc->count = amount;
-       fbc->counters = alloc_percpu(s32);
+       __percpu_counter_add(fbc, amount, FBC_BATCH);
 }
 
-static inline void percpu_counter_destroy(struct percpu_counter *fbc)
+static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
+{
+       s64 ret = __percpu_counter_sum(fbc, 0);
+       return ret < 0 ? 0 : ret;
+}
+
+static inline s64 percpu_counter_sum_and_set(struct percpu_counter *fbc)
 {
-       free_percpu(fbc->counters);
+       return __percpu_counter_sum(fbc, 1);
 }
 
-void percpu_counter_mod(struct percpu_counter *fbc, s32 amount);
-s64 percpu_counter_sum(struct percpu_counter *fbc);
+
+static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
+{
+       return __percpu_counter_sum(fbc, 0);
+}
 
 static inline s64 percpu_counter_read(struct percpu_counter *fbc)
 {
@@ -67,17 +85,28 @@ struct percpu_counter {
        s64 count;
 };
 
-static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
+static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
 {
        fbc->count = amount;
+       return 0;
 }
 
+#define percpu_counter_init_irq percpu_counter_init
+
 static inline void percpu_counter_destroy(struct percpu_counter *fbc)
 {
 }
 
+static inline void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
+{
+       fbc->count = amount;
+}
+
+#define __percpu_counter_add(fbc, amount, batch) \
+       percpu_counter_add(fbc, amount)
+
 static inline void
-percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
+percpu_counter_add(struct percpu_counter *fbc, s64 amount)
 {
        preempt_disable();
        fbc->count += amount;
@@ -94,21 +123,31 @@ static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
        return fbc->count;
 }
 
-static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
+static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
 {
        return percpu_counter_read_positive(fbc);
 }
 
+static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
+{
+       return percpu_counter_read(fbc);
+}
+
 #endif /* CONFIG_SMP */
 
 static inline void percpu_counter_inc(struct percpu_counter *fbc)
 {
-       percpu_counter_mod(fbc, 1);
+       percpu_counter_add(fbc, 1);
 }
 
 static inline void percpu_counter_dec(struct percpu_counter *fbc)
 {
-       percpu_counter_mod(fbc, -1);
+       percpu_counter_add(fbc, -1);
+}
+
+static inline void percpu_counter_sub(struct percpu_counter *fbc, s64 amount)
+{
+       percpu_counter_add(fbc, -amount);
 }
 
 #endif /* _LINUX_PERCPU_COUNTER_H */