/* See LICENSE file for copyright and license details. */ #include "common.h" /* TODO deal with machine and process suspension */ static int was_write_average_overrun(int i, int seconds, const struct status *s) { struct timespec diff; libsimple_difftimespec(&diff, &s->now, &s->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(struct status *s) { s->write_average_i -= 1; memmove(&s->write_average_begin_times[0], &s->write_average_begin_times[1], (size_t)s->write_average_i * sizeof(*s->write_average_begin_times)); memmove(&s->write_average_amounts[0], &s->write_average_amounts[1], (size_t)s->write_average_i * sizeof(*s->write_average_amounts)); } void wravg_init(const struct timespec *start_time, struct status *s) { s->write_average_begin_times[0] = *start_time; } void wravg_update_write(ssize_t amount, struct status *s) { if (amount > 0) s->write_average_amounts[s->write_average_i] += (off_t)amount; } void wravg_update_time(struct status *s) { if (was_write_average_overrun(s->write_average_i, 1, s)) { s->write_average_i += 1; if (s->write_average_i == WRAVG_STEPS) shift_write_average(s); s->write_average_begin_times[s->write_average_i] = s->now; s->write_average_amounts[s->write_average_i] = 0; } while (s->write_average_i && was_write_average_overrun(0, WRAVG_STEPS, s)) shift_write_average(s); } const char * wravg_get(struct status *s) { static char buf[512]; struct timespec write_average_time; off_t write_average_sum = 0; double write_average; int i; for (i = 0; i <= s->write_average_i; i++) write_average_sum += s->write_average_amounts[i]; libsimple_difftimespec(&write_average_time, &s->now, &s->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); }