/* * stats.c * Statistics gathering and printing. * * Copyright (c) 2002 Christoph Pfisterer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "netstrain.h" /* settings */ #define QUANTUM (2) /* internal functions */ static void stats_hook(counter_t sendcount, counter_t recvcount); static void stats_line(const char *prefix, counter_t total_b, counter_t last_b, counter_t total_us, counter_t last_us); static void print_count(counter_t count); static void print_rate(counter_t rate); static counter_t timestamp(void); /* internal data */ static time_t next_time; static counter_t start_stamp; static counter_t last_stamp; static counter_t last_sendcount = 0; static counter_t last_recvcount = 0; void stats_init(void) { next_time = time(NULL) + QUANTUM; last_stamp = start_stamp = timestamp(); transfer_hook(stats_hook); printf("sent: please wait...\nrecv'd:\n"); } static void stats_hook(counter_t sendcount, counter_t recvcount) { time_t now; counter_t now_stamp; counter_t total_b, last_b, total_us, last_us; now = time(NULL); if (now < next_time) return; next_time = now + QUANTUM; now_stamp = timestamp(); total_us = now_stamp - start_stamp; last_us = now_stamp - last_stamp; last_stamp = now_stamp; printf("\033[A\033[K\033[A\033[K"); total_b = sendcount; last_b = total_b - last_sendcount; last_sendcount = total_b; stats_line("sent: ", total_b, last_b, total_us, last_us); total_b = recvcount; last_b = total_b - last_recvcount; last_recvcount = total_b; stats_line("recv'd: ", total_b, last_b, total_us, last_us); } static void stats_line(const char *prefix, counter_t total_b, counter_t last_b, counter_t total_us, counter_t last_us) { counter_t total_bps, last_bps; total_bps = (total_b * 1000000 + (total_us >> 1)) / total_us; last_bps = (last_b * 1000000 + (last_us >> 1)) / last_us; printf("%s", prefix); print_count(total_b); printf(", "); print_rate(total_bps); printf(" total, "); print_rate(last_bps); printf(" current\n"); } static void print_count(counter_t count) { int card; if (count < 100000) { card = (int)count; printf("%7dB", card); } else { count >>= 10; if (count < 100000) { card = (int)count; printf("%7dK", card); } else { count >>= 10; card = (int)count; printf("%7dM", card); } } } static void print_rate(counter_t rate) { counter_t card_c; int card; int frac; if (rate > 10240) { card_c = rate >> 10; if (card_c >= 10000000) { printf(" \"huge\""); } else { card = (int)card_c; frac = (int)(((rate * 10) >> 10) % 10); printf("%7d.%01dK/s", card, frac); } } else { card = (int)rate; printf("%9dB/s", card); } } static counter_t timestamp(void) { struct timeval tv; gettimeofday(&tv, NULL); return (counter_t)tv.tv_sec * 1000000 + (counter_t)tv.tv_usec; }