| /* Copyright (C) 1991-2017, the Linux Kernel authors */ | 
 |  | 
 | #ifndef _LINUX_PERCPU_COUNTER_H | 
 | #define _LINUX_PERCPU_COUNTER_H | 
 | /* | 
 |  * A simple "approximate counter". | 
 |  */ | 
 |  | 
 | #include <atomic.h> | 
 | #include <list.h> | 
 |  | 
 | struct percpu_counter { | 
 | 	spinlock_t lock; | 
 | 	int64_t count; | 
 | #ifdef CONFIG_HOTPLUG_CPU | 
 | 	struct list_head list;	/* All percpu_counters are on a list */ | 
 | #endif | 
 | 	int32_t *counters; | 
 | }; | 
 |  | 
 | extern int percpu_counter_batch; | 
 |  | 
 | int percpu_counter_init(struct percpu_counter *fbc, int64_t amount, int gfp); | 
 | void percpu_counter_destroy(struct percpu_counter *fbc); | 
 | void percpu_counter_set(struct percpu_counter *fbc, int64_t amount); | 
 | void percpu_counter_add_batch(struct percpu_counter *fbc, int64_t amount, | 
 | 			      int32_t batch); | 
 | int64_t __percpu_counter_sum(struct percpu_counter *fbc); | 
 | int __percpu_counter_compare(struct percpu_counter *fbc, int64_t rhs, | 
 | 			     int32_t batch); | 
 |  | 
 | static inline int percpu_counter_compare(struct percpu_counter *fbc, | 
 | 					 int64_t rhs) | 
 | { | 
 | 	return __percpu_counter_compare(fbc, rhs, percpu_counter_batch); | 
 | } | 
 |  | 
 | static inline void percpu_counter_add(struct percpu_counter *fbc, | 
 | 				      int64_t amount) | 
 | { | 
 | 	percpu_counter_add_batch(fbc, amount, percpu_counter_batch); | 
 | } | 
 |  | 
 | static inline int64_t percpu_counter_sum_positive(struct percpu_counter *fbc) | 
 | { | 
 | 	int64_t ret = __percpu_counter_sum(fbc); | 
 | 	return ret < 0 ? 0 : ret; | 
 | } | 
 |  | 
 | static inline int64_t percpu_counter_sum(struct percpu_counter *fbc) | 
 | { | 
 | 	return __percpu_counter_sum(fbc); | 
 | } | 
 |  | 
 | static inline int64_t percpu_counter_read(struct percpu_counter *fbc) | 
 | { | 
 | 	return fbc->count; | 
 | } | 
 |  | 
 | /* | 
 |  * It is possible for the percpu_counter_read() to return a small negative | 
 |  * number for some counter which should never be negative. | 
 |  * | 
 |  */ | 
 | static inline int64_t percpu_counter_read_positive(struct percpu_counter *fbc) | 
 | { | 
 | 	int64_t ret = fbc->count; | 
 |  | 
 | 	cmb();		/* Prevent reloads of fbc->count */ | 
 | 	if (ret >= 0) | 
 | 		return ret; | 
 | 	return 0; | 
 | } | 
 |  | 
 | static inline int percpu_counter_initialized(struct percpu_counter *fbc) | 
 | { | 
 | 	return (fbc->counters != NULL); | 
 | } | 
 |  | 
 | static inline void percpu_counter_inc(struct percpu_counter *fbc) | 
 | { | 
 | 	percpu_counter_add(fbc, 1); | 
 | } | 
 |  | 
 | static inline void percpu_counter_dec(struct percpu_counter *fbc) | 
 | { | 
 | 	percpu_counter_add(fbc, -1); | 
 | } | 
 |  | 
 | static inline void percpu_counter_sub(struct percpu_counter *fbc, | 
 | 				      int64_t amount) | 
 | { | 
 | 	percpu_counter_add(fbc, -amount); | 
 | } | 
 |  | 
 | #endif /* _LINUX_PERCPU_COUNTER_H */ |