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