0001
0002 #ifndef _LINUX_AVERAGE_H
0003 #define _LINUX_AVERAGE_H
0004
0005 #include <linux/bug.h>
0006 #include <linux/compiler.h>
0007 #include <linux/log2.h>
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #define DECLARE_EWMA(name, _precision, _weight_rcp) \
0029 struct ewma_##name { \
0030 unsigned long internal; \
0031 }; \
0032 static inline void ewma_##name##_init(struct ewma_##name *e) \
0033 { \
0034 BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
0035 BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
0036
0037
0038
0039 \
0040 BUILD_BUG_ON((_precision) > 30); \
0041 BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
0042 e->internal = 0; \
0043 } \
0044 static inline unsigned long \
0045 ewma_##name##_read(struct ewma_##name *e) \
0046 { \
0047 BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
0048 BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
0049 BUILD_BUG_ON((_precision) > 30); \
0050 BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
0051 return e->internal >> (_precision); \
0052 } \
0053 static inline void ewma_##name##_add(struct ewma_##name *e, \
0054 unsigned long val) \
0055 { \
0056 unsigned long internal = READ_ONCE(e->internal); \
0057 unsigned long weight_rcp = ilog2(_weight_rcp); \
0058 unsigned long precision = _precision; \
0059 \
0060 BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
0061 BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
0062 BUILD_BUG_ON((_precision) > 30); \
0063 BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
0064 \
0065 WRITE_ONCE(e->internal, internal ? \
0066 (((internal << weight_rcp) - internal) + \
0067 (val << precision)) >> weight_rcp : \
0068 (val << precision)); \
0069 }
0070
0071 #endif