1 /*
2 * stats.c
3 * Statistics gathering and printing.
4 *
5 * Copyright (c) 2002 Christoph Pfisterer
6 *
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use, copy,
11 * modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28 #include "netstrain.h"
29
30 /* settings */
31 #define QUANTUM (2)
32
33 /* internal functions */
34 static void stats_hook(counter_t sendcount, counter_t recvcount);
35 static void stats_line(const char *prefix,
36 counter_t total_b, counter_t last_b,
37 counter_t total_us, counter_t last_us);
38 static void print_count(counter_t count);
39 static void print_rate(counter_t rate);
40 static counter_t timestamp(void);
41
42 /* internal data */
43 static time_t next_time;
44 static counter_t start_stamp;
45 static counter_t last_stamp;
46 static counter_t last_sendcount = 0;
47 static counter_t last_recvcount = 0;
48
49
stats_init(void)50 void stats_init(void)
51 {
52 next_time = time(NULL) + QUANTUM;
53 last_stamp = start_stamp = timestamp();
54
55 transfer_hook(stats_hook);
56
57 printf("sent: please wait...\nrecv'd:\n");
58 }
59
stats_hook(counter_t sendcount,counter_t recvcount)60 static void stats_hook(counter_t sendcount, counter_t recvcount)
61 {
62 time_t now;
63 counter_t now_stamp;
64 counter_t total_b, last_b, total_us, last_us;
65
66 now = time(NULL);
67 if (now < next_time)
68 return;
69 next_time = now + QUANTUM;
70
71 now_stamp = timestamp();
72 total_us = now_stamp - start_stamp;
73 last_us = now_stamp - last_stamp;
74 last_stamp = now_stamp;
75
76 printf("\033[A\033[K\033[A\033[K");
77
78 total_b = sendcount;
79 last_b = total_b - last_sendcount;
80 last_sendcount = total_b;
81 stats_line("sent: ", total_b, last_b, total_us, last_us);
82
83 total_b = recvcount;
84 last_b = total_b - last_recvcount;
85 last_recvcount = total_b;
86 stats_line("recv'd: ", total_b, last_b, total_us, last_us);
87 }
88
stats_line(const char * prefix,counter_t total_b,counter_t last_b,counter_t total_us,counter_t last_us)89 static void stats_line(const char *prefix,
90 counter_t total_b, counter_t last_b,
91 counter_t total_us, counter_t last_us)
92 {
93 counter_t total_bps, last_bps;
94
95 total_bps = (total_b * 1000000 + (total_us >> 1)) / total_us;
96 last_bps = (last_b * 1000000 + (last_us >> 1)) / last_us;
97
98 printf("%s", prefix);
99 print_count(total_b);
100 printf(", ");
101 print_rate(total_bps);
102 printf(" total, ");
103 print_rate(last_bps);
104 printf(" current\n");
105 }
106
print_count(counter_t count)107 static void print_count(counter_t count)
108 {
109 int card;
110
111 if (count < 100000) {
112 card = (int)count;
113 printf("%7dB", card);
114 } else {
115 count >>= 10;
116 if (count < 100000) {
117 card = (int)count;
118 printf("%7dK", card);
119 } else {
120 count >>= 10;
121 card = (int)count;
122 printf("%7dM", card);
123 }
124 }
125 }
126
print_rate(counter_t rate)127 static void print_rate(counter_t rate)
128 {
129 counter_t card_c;
130 int card;
131 int frac;
132
133 if (rate > 10240) {
134 card_c = rate >> 10;
135 if (card_c >= 10000000) {
136 printf(" \"huge\"");
137 } else {
138 card = (int)card_c;
139 frac = (int)(((rate * 10) >> 10) % 10);
140 printf("%7d.%01dK/s", card, frac);
141 }
142 } else {
143 card = (int)rate;
144 printf("%9dB/s", card);
145 }
146 }
147
timestamp(void)148 static counter_t timestamp(void)
149 {
150 struct timeval tv;
151
152 gettimeofday(&tv, NULL);
153 return (counter_t)tv.tv_sec * 1000000 + (counter_t)tv.tv_usec;
154 }
155