1341434Svmaffione#ifndef CTRS_H_
2341434Svmaffione#define CTRS_H_
3341434Svmaffione
4341434Svmaffione/* $FreeBSD: stable/11/tools/tools/netmap/ctrs.h 341434 2018-12-03 17:51:22Z vmaffione $ */
5341434Svmaffione
6341434Svmaffione#include <sys/time.h>
7341434Svmaffione
8341434Svmaffione/* counters to accumulate statistics */
9341434Svmaffionestruct my_ctrs {
10341434Svmaffione	uint64_t pkts, bytes, events;
11341434Svmaffione	uint64_t drop, drop_bytes;
12341434Svmaffione	uint64_t min_space;
13341434Svmaffione	struct timeval t;
14341434Svmaffione	uint32_t oq_n; /* number of elements in overflow queue (used in lb) */
15341434Svmaffione};
16341434Svmaffione
17341434Svmaffione/* very crude code to print a number in normalized form.
18341434Svmaffione * Caller has to make sure that the buffer is large enough.
19341434Svmaffione */
20341434Svmaffionestatic const char *
21341434Svmaffionenorm2(char *buf, double val, char *fmt, int normalize)
22341434Svmaffione{
23341434Svmaffione	char *units[] = { "", "K", "M", "G", "T" };
24341434Svmaffione	u_int i;
25341434Svmaffione	if (normalize)
26341434Svmaffione		for (i = 0; val >=1000 && i < sizeof(units)/sizeof(char *) - 1; i++)
27341434Svmaffione			val /= 1000;
28341434Svmaffione	else
29341434Svmaffione		i=0;
30341434Svmaffione	sprintf(buf, fmt, val, units[i]);
31341434Svmaffione	return buf;
32341434Svmaffione}
33341434Svmaffione
34341434Svmaffionestatic __inline const char *
35341434Svmaffionenorm(char *buf, double val, int normalize)
36341434Svmaffione{
37341434Svmaffione	if (normalize)
38341434Svmaffione		return norm2(buf, val, "%.3f %s", normalize);
39341434Svmaffione	else
40341434Svmaffione		return norm2(buf, val, "%.0f %s", normalize);
41341434Svmaffione}
42341434Svmaffione
43341434Svmaffionestatic __inline int
44341434Svmaffionetimespec_ge(const struct timespec *a, const struct timespec *b)
45341434Svmaffione{
46341434Svmaffione
47341434Svmaffione	if (a->tv_sec > b->tv_sec)
48341434Svmaffione		return (1);
49341434Svmaffione	if (a->tv_sec < b->tv_sec)
50341434Svmaffione		return (0);
51341434Svmaffione	if (a->tv_nsec >= b->tv_nsec)
52341434Svmaffione		return (1);
53341434Svmaffione	return (0);
54341434Svmaffione}
55341434Svmaffione
56341434Svmaffionestatic __inline struct timespec
57341434Svmaffionetimeval2spec(const struct timeval *a)
58341434Svmaffione{
59341434Svmaffione	struct timespec ts = {
60341434Svmaffione		.tv_sec = a->tv_sec,
61341434Svmaffione		.tv_nsec = a->tv_usec * 1000
62341434Svmaffione	};
63341434Svmaffione	return ts;
64341434Svmaffione}
65341434Svmaffione
66341434Svmaffionestatic __inline struct timeval
67341434Svmaffionetimespec2val(const struct timespec *a)
68341434Svmaffione{
69341434Svmaffione	struct timeval tv = {
70341434Svmaffione		.tv_sec = a->tv_sec,
71341434Svmaffione		.tv_usec = a->tv_nsec / 1000
72341434Svmaffione	};
73341434Svmaffione	return tv;
74341434Svmaffione}
75341434Svmaffione
76341434Svmaffione
77341434Svmaffionestatic __inline struct timespec
78341434Svmaffionetimespec_add(struct timespec a, struct timespec b)
79341434Svmaffione{
80341434Svmaffione	struct timespec ret = { a.tv_sec + b.tv_sec, a.tv_nsec + b.tv_nsec };
81341434Svmaffione	if (ret.tv_nsec >= 1000000000) {
82341434Svmaffione		ret.tv_sec++;
83341434Svmaffione		ret.tv_nsec -= 1000000000;
84341434Svmaffione	}
85341434Svmaffione	return ret;
86341434Svmaffione}
87341434Svmaffione
88341434Svmaffionestatic __inline struct timespec
89341434Svmaffionetimespec_sub(struct timespec a, struct timespec b)
90341434Svmaffione{
91341434Svmaffione	struct timespec ret = { a.tv_sec - b.tv_sec, a.tv_nsec - b.tv_nsec };
92341434Svmaffione	if (ret.tv_nsec < 0) {
93341434Svmaffione		ret.tv_sec--;
94341434Svmaffione		ret.tv_nsec += 1000000000;
95341434Svmaffione	}
96341434Svmaffione	return ret;
97341434Svmaffione}
98341434Svmaffione
99341434Svmaffionestatic __inline uint64_t
100341434Svmaffionewait_for_next_report(struct timeval *prev, struct timeval *cur,
101341434Svmaffione		int report_interval)
102341434Svmaffione{
103341434Svmaffione	struct timeval delta;
104341434Svmaffione
105341434Svmaffione	delta.tv_sec = report_interval/1000;
106341434Svmaffione	delta.tv_usec = (report_interval%1000)*1000;
107341434Svmaffione	if (select(0, NULL, NULL, NULL, &delta) < 0 && errno != EINTR) {
108341434Svmaffione		perror("select");
109341434Svmaffione		abort();
110341434Svmaffione	}
111341434Svmaffione	gettimeofday(cur, NULL);
112341434Svmaffione	timersub(cur, prev, &delta);
113341434Svmaffione	return delta.tv_sec* 1000000 + delta.tv_usec;
114341434Svmaffione}
115341434Svmaffione#endif /* CTRS_H_ */
116341434Svmaffione
117