132f753f2SBjoern A. Zeeb /*- 232f753f2SBjoern A. Zeeb * SPDX-License-Identifier: BSD-2-Clause 332f753f2SBjoern A. Zeeb * 432f753f2SBjoern A. Zeeb * Copyright (c) 2020-2021 The FreeBSD Foundation 532f753f2SBjoern A. Zeeb * 632f753f2SBjoern A. Zeeb * This software was developed by Björn Zeeb under sponsorship from 732f753f2SBjoern A. Zeeb * the FreeBSD Foundation. 832f753f2SBjoern A. Zeeb * 932f753f2SBjoern A. Zeeb * Redistribution and use in source and binary forms, with or without 1032f753f2SBjoern A. Zeeb * modification, are permitted provided that the following conditions 1132f753f2SBjoern A. Zeeb * are met: 1232f753f2SBjoern A. Zeeb * 1. Redistributions of source code must retain the above copyright 1332f753f2SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer. 1432f753f2SBjoern A. Zeeb * 2. Redistributions in binary form must reproduce the above copyright 1532f753f2SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer in the 1632f753f2SBjoern A. Zeeb * documentation and/or other materials provided with the distribution. 1732f753f2SBjoern A. Zeeb * 1832f753f2SBjoern A. Zeeb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1932f753f2SBjoern A. Zeeb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2032f753f2SBjoern A. Zeeb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2132f753f2SBjoern A. Zeeb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2232f753f2SBjoern A. Zeeb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2332f753f2SBjoern A. Zeeb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2432f753f2SBjoern A. Zeeb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2532f753f2SBjoern A. Zeeb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2632f753f2SBjoern A. Zeeb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2732f753f2SBjoern A. Zeeb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2832f753f2SBjoern A. Zeeb * SUCH DAMAGE. 2932f753f2SBjoern A. Zeeb */ 3032f753f2SBjoern A. Zeeb 31*307f78f3SVladimir Kondratyev #ifndef _LINUXKPI_LINUX_AVERAGE_H 32*307f78f3SVladimir Kondratyev #define _LINUXKPI_LINUX_AVERAGE_H 3332f753f2SBjoern A. Zeeb 3432f753f2SBjoern A. Zeeb #include <sys/param.h> 3532f753f2SBjoern A. Zeeb #include <sys/systm.h> 3632f753f2SBjoern A. Zeeb #include <sys/types.h> 3732f753f2SBjoern A. Zeeb #include <linux/log2.h> 3832f753f2SBjoern A. Zeeb 3932f753f2SBjoern A. Zeeb /* EWMA stands for Exponentially Weighted Moving Average. */ 4032f753f2SBjoern A. Zeeb /* 4132f753f2SBjoern A. Zeeb * Z_t = d X_t + (1 - d) * Z_(t-1); 0 < d <= 1, t >= 1; Roberts (1959). 4232f753f2SBjoern A. Zeeb * t : observation number in time. 4332f753f2SBjoern A. Zeeb * d : weight for current observation. 4432f753f2SBjoern A. Zeeb * Xt : observations over time. 4532f753f2SBjoern A. Zeeb * Zt : EWMA value after observation t. 4632f753f2SBjoern A. Zeeb * 4732f753f2SBjoern A. Zeeb * wmba_*_read seems to return up-to [u]long values; have to deal with 32/64bit. 4832f753f2SBjoern A. Zeeb * According to the ath5k.h change log this seems to be a fix-(_p)recision impl. 4932f753f2SBjoern A. Zeeb * assert 2/4 bits for frac. 5032f753f2SBjoern A. Zeeb * Also all (_d) values seem to be pow2 which simplifies maths (shift by 5132f753f2SBjoern A. Zeeb * d = ilog2(_d) instead of doing division (d = 1/_d)). Keep it this way until 5232f753f2SBjoern A. Zeeb * we hit the CTASSERT. 5332f753f2SBjoern A. Zeeb */ 5432f753f2SBjoern A. Zeeb 5532f753f2SBjoern A. Zeeb #define DECLARE_EWMA(_name, _p, _d) \ 5632f753f2SBjoern A. Zeeb \ 5732f753f2SBjoern A. Zeeb CTASSERT((sizeof(unsigned long) <= 4) ? (_p < 30) : (_p < 60)); \ 5832f753f2SBjoern A. Zeeb CTASSERT(_d > 0 && powerof2(_d)); \ 5932f753f2SBjoern A. Zeeb \ 6032f753f2SBjoern A. Zeeb struct ewma_ ## _name { \ 6132f753f2SBjoern A. Zeeb unsigned long zt; \ 6232f753f2SBjoern A. Zeeb }; \ 6332f753f2SBjoern A. Zeeb \ 6432f753f2SBjoern A. Zeeb static __inline void \ 6532f753f2SBjoern A. Zeeb ewma_ ## _name ## _init(struct ewma_ ## _name *ewma) \ 6632f753f2SBjoern A. Zeeb { \ 6732f753f2SBjoern A. Zeeb /* No target (no historical data). */ \ 6832f753f2SBjoern A. Zeeb ewma->zt = 0; \ 6932f753f2SBjoern A. Zeeb } \ 7032f753f2SBjoern A. Zeeb \ 7132f753f2SBjoern A. Zeeb static __inline void \ 7232f753f2SBjoern A. Zeeb ewma_ ## _name ## _add(struct ewma_ ## _name *ewma, unsigned long x) \ 7332f753f2SBjoern A. Zeeb { \ 7432f753f2SBjoern A. Zeeb unsigned long ztm1 = ewma->zt; /* Z_(t-1). */ \ 7532f753f2SBjoern A. Zeeb int d = ilog2(_d); \ 7632f753f2SBjoern A. Zeeb \ 7732f753f2SBjoern A. Zeeb if (ewma->zt == 0) \ 7832f753f2SBjoern A. Zeeb ewma->zt = x << (_p); \ 7932f753f2SBjoern A. Zeeb else \ 8032f753f2SBjoern A. Zeeb ewma->zt = ((x << (_p)) >> d) + \ 8132f753f2SBjoern A. Zeeb (((ztm1 << d) - ztm1) >> d); \ 8232f753f2SBjoern A. Zeeb } \ 8332f753f2SBjoern A. Zeeb \ 8432f753f2SBjoern A. Zeeb static __inline unsigned long \ 8532f753f2SBjoern A. Zeeb ewma_ ## _name ## _read(struct ewma_ ## _name *ewma) \ 8632f753f2SBjoern A. Zeeb { \ 8732f753f2SBjoern A. Zeeb return (ewma->zt >> (_p)); \ 8832f753f2SBjoern A. Zeeb } \ 8932f753f2SBjoern A. Zeeb 90*307f78f3SVladimir Kondratyev #endif /* _LINUXKPI_LINUX_AVERAGE_H */ 91