From: Hauke Mehrtens Date: Sun, 21 Nov 2010 20:48:36 +0000 (+0100) Subject: compat: backport Generic exponentially weighted moving average (EWMA) X-Git-Tag: v2.6.38-rc1-1~19 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=a24f730f0b9122b72054807c85264876af1c4a1e;p=~emulex%2Ffor-vlad%2Fcompat.git compat: backport Generic exponentially weighted moving average (EWMA) Signed-off-by: Hauke Mehrtens --- diff --git a/compat/Makefile b/compat/Makefile index 46049af..18a9afc 100644 --- a/compat/Makefile +++ b/compat/Makefile @@ -27,3 +27,4 @@ compat-$(CONFIG_COMPAT_KERNEL_33) += compat-2.6.33.o compat-$(CONFIG_COMPAT_KERNEL_35) += compat-2.6.35.o compat-$(CONFIG_COMPAT_KERNEL_36) += compat-2.6.36.o compat-$(CONFIG_COMPAT_KERNEL_37) += compat-2.6.37.o +compat-$(CONFIG_COMPAT_KERNEL_38) += compat-2.6.38.o diff --git a/compat/compat-2.6.38.c b/compat/compat-2.6.38.c new file mode 100644 index 0000000..172aa19 --- /dev/null +++ b/compat/compat-2.6.38.c @@ -0,0 +1,50 @@ +/* + * Copyright 2010 Hauke Mehrtens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.38. + */ + +#include +#include +#include + +/** + * ewma_init() - Initialize EWMA parameters + * @avg: Average structure + * @factor: Factor to use for the scaled up internal value. The maximum value + * of averages can be ULONG_MAX/(factor*weight). + * @weight: Exponential weight, or decay rate. This defines how fast the + * influence of older values decreases. Has to be bigger than 1. + * + * Initialize the EWMA parameters for a given struct ewma @avg. + */ +void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight) +{ + WARN_ON(weight <= 1 || factor == 0); + avg->internal = 0; + avg->weight = weight; + avg->factor = factor; +} +EXPORT_SYMBOL(ewma_init); + +/** + * ewma_add() - Exponentially weighted moving average (EWMA) + * @avg: Average structure + * @val: Current value + * + * Add a sample to the average. + */ +struct ewma *ewma_add(struct ewma *avg, unsigned long val) +{ + avg->internal = avg->internal ? + (((avg->internal * (avg->weight - 1)) + + (val * avg->factor)) / avg->weight) : + (val * avg->factor); + return avg; +} +EXPORT_SYMBOL(ewma_add); + diff --git a/include/linux/average.h b/include/linux/average.h new file mode 100644 index 0000000..ece86ca --- /dev/null +++ b/include/linux/average.h @@ -0,0 +1,5 @@ +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)) +#include_next +#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)) */ diff --git a/include/linux/compat-2.6.38.h b/include/linux/compat-2.6.38.h index fa77a89..85eac51 100644 --- a/include/linux/compat-2.6.38.h +++ b/include/linux/compat-2.6.38.h @@ -5,6 +5,8 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) +#include + /* * This is not part of The 2.6.37 kernel yet but we * we use it to optimize the backport code we @@ -25,6 +27,33 @@ /* rename member in struct mmc_host in include/linux/mmc/host.h */ #define max_segs max_hw_segs + +/* Exponentially weighted moving average (EWMA) */ + +/* For more documentation see lib/average.c */ + +struct ewma { + unsigned long internal; + unsigned long factor; + unsigned long weight; +}; + +extern void ewma_init(struct ewma *avg, unsigned long factor, + unsigned long weight); + +extern struct ewma *ewma_add(struct ewma *avg, unsigned long val); + +/** + * ewma_read() - Get average value + * @avg: Average structure + * + * Returns the average value held in @avg. + */ +static inline unsigned long ewma_read(const struct ewma *avg) +{ + return DIV_ROUND_CLOSEST(avg->internal, avg->factor); +} + #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) */ #endif /* LINUX_26_38_COMPAT_H */