linux/lib/average.c
<<
>>
Prefs
   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/export.h>
   9#include <linux/average.h>
  10#include <linux/kernel.h>
  11#include <linux/bug.h>
  12#include <linux/log2.h>
  13
  14/**
  15 * DOC: Exponentially Weighted Moving Average (EWMA)
  16 *
  17 * These are generic functions for calculating Exponentially Weighted Moving
  18 * Averages (EWMA). We keep a structure with the EWMA parameters and a scaled
  19 * up internal representation of the average value to prevent rounding errors.
  20 * The factor for scaling up and the exponential weight (or decay rate) have to
  21 * be specified thru the init fuction. The structure should not be accessed
  22 * directly but only thru the helper functions.
  23 */
  24
  25/**
  26 * ewma_init() - Initialize EWMA parameters
  27 * @avg: Average structure
  28 * @factor: Factor to use for the scaled up internal value. The maximum value
  29 *      of averages can be ULONG_MAX/(factor*weight). For performance reasons
  30 *      factor has to be a power of 2.
  31 * @weight: Exponential weight, or decay rate. This defines how fast the
  32 *      influence of older values decreases. For performance reasons weight has
  33 *      to be a power of 2.
  34 *
  35 * Initialize the EWMA parameters for a given struct ewma @avg.
  36 */
  37void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight)
  38{
  39        WARN_ON(!is_power_of_2(weight) || !is_power_of_2(factor));
  40
  41        avg->weight = ilog2(weight);
  42        avg->factor = ilog2(factor);
  43        avg->internal = 0;
  44}
  45EXPORT_SYMBOL(ewma_init);
  46
  47/**
  48 * ewma_add() - Exponentially weighted moving average (EWMA)
  49 * @avg: Average structure
  50 * @val: Current value
  51 *
  52 * Add a sample to the average.
  53 */
  54struct ewma *ewma_add(struct ewma *avg, unsigned long val)
  55{
  56        avg->internal = avg->internal  ?
  57                (((avg->internal << avg->weight) - avg->internal) +
  58                        (val << avg->factor)) >> avg->weight :
  59                (val << avg->factor);
  60        return avg;
  61}
  62EXPORT_SYMBOL(ewma_add);
  63