From 44cff01e5bbe04ff991ede843e96f0c2d83d20c6 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 19 Sep 2024 18:03:17 +0200 Subject: Split into multiple C files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- avg.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 avg.c (limited to 'avg.c') diff --git a/avg.c b/avg.c new file mode 100644 index 0000000..4078c50 --- /dev/null +++ b/avg.c @@ -0,0 +1,94 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +/* TODO deal with machine and process suspension */ + + +static struct timespec write_average_begin_times[5]; +static off_t write_average_amounts[ELEMSOF(write_average_begin_times)] = {0}; +static int write_average_i = 0; + + +static int +was_write_average_overrun(int i, const struct timespec *now, int seconds) +{ + struct timespec diff; + libsimple_difftimespec(&diff, now, &write_average_begin_times[i]); + if (diff.tv_sec >= seconds) + return 1; + if (diff.tv_sec == seconds - 1 && diff.tv_nsec >= DECISECONDS(9)) + return 1; + return 0; +} + + +static void +shift_write_average(void) +{ + write_average_i--; + memmove(&write_average_begin_times[0], &write_average_begin_times[1], + (size_t)write_average_i * sizeof(*write_average_begin_times)); + memmove(&write_average_amounts[0], &write_average_amounts[1], + (size_t)write_average_i * sizeof(*write_average_amounts)); +} + + +void +wravg_init(const struct timespec *start_time) +{ + write_average_begin_times[0] = *start_time; +} + + +void +wravg_update_write(ssize_t amount) +{ + if (amount > 0) + write_average_amounts[write_average_i] += (off_t)amount; +} + + +void +wravg_update_time(const struct timespec *now) +{ + if (was_write_average_overrun(write_average_i, now, 1)) { + write_average_i++; + if (write_average_i == ELEMSOF(write_average_amounts)) + shift_write_average(); + write_average_begin_times[write_average_i] = *now; + write_average_amounts[write_average_i] = 0; + } + while (write_average_i && was_write_average_overrun(0, now, (int)ELEMSOF(write_average_amounts))) + shift_write_average(); +} + + +const char * +wravg_get(const struct timespec *now) +{ + static char buf[512]; + + struct timespec write_average_time; + off_t write_average_sum = 0; + double write_average; + int i; + + for (i = 0; i <= write_average_i; i++) + write_average_sum += write_average_amounts[i]; + + libsimple_difftimespec(&write_average_time, now, &write_average_begin_times[0]); + + if (write_average_time.tv_sec < 0) + return "-"; + if (write_average_time.tv_sec == 0 && write_average_time.tv_nsec < CENTISECONDS(10)) + return "-"; + if (write_average_sum == 0) + return "0"; + + write_average = (double)write_average_time.tv_nsec; + write_average /= WHOLE_SECOND; + write_average += (double)write_average_time.tv_sec; + write_average = (double)write_average_sum / write_average; + return humanbytespersecond(write_average, buf); +} -- cgit v1.2.3-70-g09d2