/*
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1