Ticket #11112: 970-ewma.patch

File 970-ewma.patch, 4.5 KB (added by Viktar Palstsiuk <viktar.palstsiuk@…>, 5 years ago)
  • new file include/linux/average.h

    From c5485a7e7569ab32eea240c850198519e2a765ef Mon Sep 17 00:00:00 2001
    From: Bruno Randolf <br1@einfach.org>
    Date: Tue, 16 Nov 2010 10:58:37 +0900
    Subject: [PATCH] lib: Add generic exponentially weighted moving average
     (EWMA) function
    
    This adds generic functions for calculating Exponentially Weighted Moving
    Averages (EWMA). This implementation makes use of a structure which keeps the
    EWMA parameters and a scaled up internal representation to reduce rounding
    errors.
    
    The original idea for this implementation came from the rt2x00 driver
    (rt2x00link.c). I would like to use it in several places in the mac80211 and
    ath5k code and I hope it can be useful in many other places in the kernel code.
    
    Signed-off-by: Bruno Randolf <br1@einfach.org>
    Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    ---
     include/linux/average.h |   32 ++++++++++++++++++++++++++
     lib/Kconfig             |    3 ++
     lib/Makefile            |    2 +
     lib/average.c           |   57 +++++++++++++++++++++++++++++++++++++++++++++++
     4 files changed, 94 insertions(+), 0 deletions(-)
     create mode 100644 include/linux/average.h
     create mode 100644 lib/average.c
    
    diff --git a/include/linux/average.h b/include/linux/average.h
    new file mode 100644
    index 0000000..7706e40
    - +  
     1#ifndef _LINUX_AVERAGE_H 
     2#define _LINUX_AVERAGE_H 
     3 
     4#include <linux/kernel.h> 
     5 
     6/* Exponentially weighted moving average (EWMA) */ 
     7 
     8/* For more documentation see lib/average.c */ 
     9 
     10struct ewma { 
     11        unsigned long internal; 
     12        unsigned long factor; 
     13        unsigned long weight; 
     14}; 
     15 
     16extern void ewma_init(struct ewma *avg, unsigned long factor, 
     17                      unsigned long weight); 
     18 
     19extern struct ewma *ewma_add(struct ewma *avg, unsigned long val); 
     20 
     21/** 
     22 * ewma_read() - Get average value 
     23 * @avg: Average structure 
     24 * 
     25 * Returns the average value held in @avg. 
     26 */ 
     27static inline unsigned long ewma_read(const struct ewma *avg) 
     28{ 
     29        return DIV_ROUND_CLOSEST(avg->internal, avg->factor); 
     30} 
     31 
     32#endif /* _LINUX_AVERAGE_H */ 
  • lib/Kconfig

    diff --git a/lib/Kconfig b/lib/Kconfig
    index fa9bf2c..3116aa6 100644
    a b config GENERIC_ATOMIC64 
    210210config LRU_CACHE 
    211211        tristate 
    212212 
     213config AVERAGE 
     214        bool 
     215 
    213216endmenu 
  • lib/Makefile

    diff --git a/lib/Makefile b/lib/Makefile
    index e6a3763..76d3b85 100644
    a b obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o 
    106106 
    107107obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o 
    108108 
     109obj-$(CONFIG_AVERAGE) += average.o 
     110 
    109111hostprogs-y     := gen_crc32table 
    110112clean-files     := crc32table.h 
    111113 
  • new file lib/average.c

    diff --git a/lib/average.c b/lib/average.c
    new file mode 100644
    index 0000000..f1d1b46
    - +  
     1/* 
     2 * lib/average.c 
     3 * 
     4 * This source code is licensed under the GNU General Public License, 
     5 * Version 2.  See the file COPYING for more details. 
     6 */ 
     7 
     8#include <linux/module.h> 
     9#include <linux/average.h> 
     10#include <linux/bug.h> 
     11 
     12/** 
     13 * DOC: Exponentially Weighted Moving Average (EWMA) 
     14 * 
     15 * These are generic functions for calculating Exponentially Weighted Moving 
     16 * Averages (EWMA). We keep a structure with the EWMA parameters and a scaled 
     17 * up internal representation of the average value to prevent rounding errors. 
     18 * The factor for scaling up and the exponential weight (or decay rate) have to 
     19 * be specified thru the init fuction. The structure should not be accessed 
     20 * directly but only thru the helper functions. 
     21 */ 
     22 
     23/** 
     24 * ewma_init() - Initialize EWMA parameters 
     25 * @avg: Average structure 
     26 * @factor: Factor to use for the scaled up internal value. The maximum value 
     27 *      of averages can be ULONG_MAX/(factor*weight). 
     28 * @weight: Exponential weight, or decay rate. This defines how fast the 
     29 *      influence of older values decreases. Has to be bigger than 1. 
     30 * 
     31 * Initialize the EWMA parameters for a given struct ewma @avg. 
     32 */ 
     33void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight) 
     34{ 
     35        WARN_ON(weight <= 1 || factor == 0); 
     36        avg->internal = 0; 
     37        avg->weight = weight; 
     38        avg->factor = factor; 
     39} 
     40EXPORT_SYMBOL(ewma_init); 
     41 
     42/** 
     43 * ewma_add() - Exponentially weighted moving average (EWMA) 
     44 * @avg: Average structure 
     45 * @val: Current value 
     46 * 
     47 * Add a sample to the average. 
     48 */ 
     49struct ewma *ewma_add(struct ewma *avg, unsigned long val) 
     50{ 
     51        avg->internal = avg->internal  ? 
     52                (((avg->internal * (avg->weight - 1)) + 
     53                        (val * avg->factor)) / avg->weight) : 
     54                (val * avg->factor); 
     55        return avg; 
     56} 
     57EXPORT_SYMBOL(ewma_add);