1#ifndef _LINUX_AVERAGE_H 2#define _LINUX_AVERAGE_H 3 4/* Exponentially weighted moving average (EWMA) */ 5 6#define DECLARE_EWMA(name, _factor, _weight) \ 7 struct ewma_##name { \ 8 unsigned long internal; \ 9 }; \ 10 static inline void ewma_##name##_init(struct ewma_##name *e) \ 11 { \ 12 BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ 13 BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ 14 BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ 15 BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ 16 e->internal = 0; \ 17 } \ 18 static inline unsigned long \ 19 ewma_##name##_read(struct ewma_##name *e) \ 20 { \ 21 BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ 22 BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ 23 BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ 24 BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ 25 return e->internal >> ilog2(_factor); \ 26 } \ 27 static inline void ewma_##name##_add(struct ewma_##name *e, \ 28 unsigned long val) \ 29 { \ 30 unsigned long internal = ACCESS_ONCE(e->internal); \ 31 unsigned long weight = ilog2(_weight); \ 32 unsigned long factor = ilog2(_factor); \ 33 \ 34 BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ 35 BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ 36 BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ 37 BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ 38 \ 39 ACCESS_ONCE(e->internal) = internal ? \ 40 (((internal << weight) - internal) + \ 41 (val << factor)) >> weight : \ 42 (val << factor); \ 43 } 44 45#endif /* _LINUX_AVERAGE_H */ 46