1#ifndef _LINUX_AVERAGE_H 2#define _LINUX_AVERAGE_H 3 4/* Exponentially weighted moving average (EWMA) */ 5 6/* For more documentation see lib/average.c */ 7 8struct ewma { 9 unsigned long internal; 10 unsigned long factor; 11 unsigned long weight; 12}; 13 14extern void ewma_init(struct ewma *avg, unsigned long factor, 15 unsigned long weight); 16 17extern struct ewma *ewma_add(struct ewma *avg, unsigned long val); 18 19/** 20 * ewma_read() - Get average value 21 * @avg: Average structure 22 * 23 * Returns the average value held in @avg. 24 */ 25static inline unsigned long ewma_read(const struct ewma *avg) 26{ 27 return avg->internal >> avg->factor; 28} 29 30#define DECLARE_EWMA(name, _factor, _weight) \ 31 struct ewma_##name { \ 32 unsigned long internal; \ 33 }; \ 34 static inline void ewma_##name##_init(struct ewma_##name *e) \ 35 { \ 36 BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ 37 BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ 38 BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ 39 BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ 40 e->internal = 0; \ 41 } \ 42 static inline unsigned long \ 43 ewma_##name##_read(struct ewma_##name *e) \ 44 { \ 45 BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ 46 BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ 47 BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ 48 BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ 49 return e->internal >> ilog2(_factor); \ 50 } \ 51 static inline void ewma_##name##_add(struct ewma_##name *e, \ 52 unsigned long val) \ 53 { \ 54 unsigned long internal = ACCESS_ONCE(e->internal); \ 55 unsigned long weight = ilog2(_weight); \ 56 unsigned long factor = ilog2(_factor); \ 57 \ 58 BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ 59 BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ 60 BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ 61 BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ 62 \ 63 ACCESS_ONCE(e->internal) = internal ? \ 64 (((internal << weight) - internal) + \ 65 (val << factor)) >> weight : \ 66 (val << factor); \ 67 } 68 69#endif /* _LINUX_AVERAGE_H */ 70