/*
 * QEMU timed average computation
 *
 * Copyright (C) Nodalink, EURL. 2014
 * Copyright (C) Igalia, S.L. 2015
 *
 * Authors:
 *   Benoît Canet <benoit.canet@nodalink.com>
 *   Alberto Garcia <berto@igalia.com>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"

#include "qemu/timed-average.h"

/* This module computes an average of a set of values within a time
 * window.
 *
 * Algorithm:
 *
 * - Create two windows with a certain expiration period, and
 *   offsetted by period / 2.
 * - Each time you want to account a new value, do it in both windows.
 * - The minimum / maximum / average values are always returned from
 *   the oldest window.
 *
 * Example:
 *
 *        t=0          |t=0.5           |t=1          |t=1.5            |t=2
 *        wnd0: [0,0.5)|wnd0: [0.5,1.5) |             |wnd0: [1.5,2.5)  |
 *        wnd1: [0,1)  |                |wnd1: [1,2)  |                 |
 *
 * Values are returned from:
 *
 *        wnd0---------|wnd1------------|wnd0---------|wnd1-------------|
 */

/* Update the expiration of a time window
 *
 * @w:      the window used
 * @now:    the current time in nanoseconds
 * @period: the expiration period in nanoseconds
 */
static void update_expiration(TimedAverageWindow *w, int64_t now,
                              int64_t period)
{
    /* time elapsed since the last theoretical expiration */
    int64_t elapsed = (now - w->expiration) % period;
    /* time remaininging until the next expiration */
    int64_t remaining = period - elapsed;
    /* compute expiration */
    w->expiration = now + remaining;
}

/* Reset a window
 *
 * @w: the window to reset
 */
static void window_reset(TimedAverageWindow *w)
{
    w->min = UINT64_MAX;
    w->max = 0;
    w->sum = 0;
    w->count = 0;
}

/* Get the current window (that is, the one with the earliest
 * expiration time).
 *
 * @ta:  the TimedAverage structure
 * @ret: a pointer to the current window
 */
static TimedAverageWindow *current_window(TimedAverage *ta)
{
     return &ta->windows[ta->current];
}

/* Initialize a TimedAverage structure
 *
 * @ta:         the TimedAverage structure
 * @clock_type: the type of clock to use
 * @period:     the time window period in nanoseconds
 */
void timed_average_init(TimedAverage *ta, QEMUClockType clock_type,
                        uint64_t period)
{
    int64_t now = qemu_clock_get_ns(clock_type);

    /* Returned values are from the oldest window, so they belong to
     * the interval [ta->period/2,ta->period). By adjusting the
     * requested period by 4/3, we guarantee that they're in the
     * interval [2/3 period,4/3 period), closer to the requested
     * period on average */
    ta->period = (uint64_t) period * 4 / 3;
    ta->clock_type = clock_type;
    ta->current = 0;

    window_reset(&ta->windows[0]);
    window_reset(&ta->windows[1]);

    /* Both windows are offsetted by half a period */
    ta->windows[0].expiration = now + ta->period / 2;
    ta->windows[1].expiration = now + ta->period;
}

/* Check if the time windows have expired, updating their counters and
 * expiration time if that's the case.
 *
 * @ta: the TimedAverage structure
 * @elapsed: if non-NULL, the elapsed time (in ns) within the current
 *           window will be stored here
 */
static void check_expirations(TimedAverage *ta, uint64_t *elapsed)
{
    int64_t now = qemu_clock_get_ns(ta->clock_type);
    int i;

    assert(ta->period != 0);

    /* Check if the windows have expired */
    for (i = 0; i < 2; i++) {
        TimedAverageWindow *w = &ta->windows[i];
        if (w->expiration <= now) {
            window_reset(w);
            update_expiration(w, now, ta->period);
        }
    }

    /* Make ta->current point to the oldest window */
    if (ta->windows[0].expiration < ta->windows[1].expiration) {
        ta->current = 0;
    } else {
        ta->current = 1;
    }

    /* Calculate the elapsed time within the current window */
    if (elapsed) {
        int64_t remaining = ta->windows[ta->current].expiration - now;
        *elapsed = ta->period - remaining;
    }
}

/* Account a value
 *
 * @ta:    the TimedAverage structure
 * @value: the value to account
 */
void timed_average_account(TimedAverage *ta, uint64_t value)
{
    int i;
    check_expirations(ta, NULL);

    /* Do the accounting in both windows at the same time */
    for (i = 0; i < 2; i++) {
        TimedAverageWindow *w = &ta->windows[i];

        w->sum += value;
        w->count++;

        if (value < w->min) {
            w->min = value;
        }

        if (value > w->max) {
            w->max = value;
        }
    }
}

/* Get the minimum value
 *
 * @ta:  the TimedAverage structure
 * @ret: the minimum value
 */
uint64_t timed_average_min(TimedAverage *ta)
{
    TimedAverageWindow *w;
    check_expirations(ta, NULL);
    w = current_window(ta);
    return w->min < UINT64_MAX ? w->min : 0;
}

/* Get the average value
 *
 * @ta:  the TimedAverage structure
 * @ret: the average value
 */
uint64_t timed_average_avg(TimedAverage *ta)
{
    TimedAverageWindow *w;
    check_expirations(ta, NULL);
    w = current_window(ta);
    return w->count > 0 ? w->sum / w->count : 0;
}

/* Get the maximum value
 *
 * @ta:  the TimedAverage structure
 * @ret: the maximum value
 */
uint64_t timed_average_max(TimedAverage *ta)
{
    check_expirations(ta, NULL);
    return current_window(ta)->max;
}

/* Get the sum of all accounted values
 * @ta:      the TimedAverage structure
 * @elapsed: if non-NULL, the elapsed time (in ns) will be stored here
 * @ret:     the sum of all accounted values
 */
uint64_t timed_average_sum(TimedAverage *ta, uint64_t *elapsed)
{
    TimedAverageWindow *w;
    check_expirations(ta, elapsed);
    w = current_window(ta);
    return w->sum;
}
