Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 224616
b: refs/heads/master
c: c5485a7
h: refs/heads/master
v: v3
  • Loading branch information
Bruno Randolf authored and John W. Linville committed Nov 18, 2010
1 parent a9247e3 commit 823846c
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 50a9432daeece6fc1309bef1dc0a7b8fde8204cb
refs/heads/master: c5485a7e7569ab32eea240c850198519e2a765ef
32 changes: 32 additions & 0 deletions trunk/include/linux/average.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef _LINUX_AVERAGE_H
#define _LINUX_AVERAGE_H

#include <linux/kernel.h>

/* 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_AVERAGE_H */
3 changes: 3 additions & 0 deletions trunk/lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,7 @@ config GENERIC_ATOMIC64
config LRU_CACHE
tristate

config AVERAGE
bool

endmenu
2 changes: 2 additions & 0 deletions trunk/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o

obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o

obj-$(CONFIG_AVERAGE) += average.o

hostprogs-y := gen_crc32table
clean-files := crc32table.h

Expand Down
57 changes: 57 additions & 0 deletions trunk/lib/average.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* lib/average.c
*
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/

#include <linux/module.h>
#include <linux/average.h>
#include <linux/bug.h>

/**
* DOC: Exponentially Weighted Moving Average (EWMA)
*
* These are generic functions for calculating Exponentially Weighted Moving
* Averages (EWMA). We keep a structure with the EWMA parameters and a scaled
* up internal representation of the average value to prevent rounding errors.
* The factor for scaling up and the exponential weight (or decay rate) have to
* be specified thru the init fuction. The structure should not be accessed
* directly but only thru the helper functions.
*/

/**
* 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);

0 comments on commit 823846c

Please sign in to comment.