]> git.ipfire.org Git - thirdparty/rng-tools.git/blame - stats.c
s/list_add/src_list_add/
[thirdparty/rng-tools.git] / stats.c
CommitLineData
61af3de3
JG
1/*
2 * stats.c -- Statistics helpers
3 *
4 * Copyright (C) 2004 Henrique de Moraes Holschuh <hmh@debian.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
d1b4c504 10 *
61af3de3
JG
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define _GNU_SOURCE
22
23#ifndef HAVE_CONFIG_H
24#error Invalid or missing autoconf build environment
25#endif
26
27#include "rng-tools-config.h"
28
29#include <unistd.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <sys/time.h>
33#include <time.h>
34#include <string.h>
35
36#include "fips.h"
37#include "stats.h"
38
39
40static char stat_prefix[20] = "";
41
42void set_stat_prefix(const char* prefix)
43{
44 stat_prefix[sizeof(stat_prefix)-1] = 0;
45 strncpy(stat_prefix, prefix, sizeof(stat_prefix)-1);
46}
47
d1b4c504
JG
48static void scale_mult_unit(char *unit, int unitsize,
49 const char *baseunit,
61af3de3
JG
50 double *value_min,
51 double *value_avg,
52 double *value_max)
53{
54 int mult = 0;
55 char multchar[] = "KMGTPE";
56
d1b4c504 57 while ((*value_min >= 1024.0) && (*value_avg >= 1024.0) &&
61af3de3
JG
58 (*value_max >= 1024.0) && (mult < sizeof(multchar))) {
59 mult++;
60 *value_min = *value_min / 1024.0;
61 *value_max = *value_max / 1024.0;
62 *value_avg = *value_avg / 1024.0;
63 }
64 unit[unitsize-1] = 0;
65 if (mult)
66 snprintf(unit, unitsize, "%ci%s", multchar[mult-1], baseunit);
67 else
68 strncpy(unit, baseunit, unitsize);
69}
70
71/* Computes elapsed time in microseconds */
72uint64_t elapsed_time(struct timeval *start,
73 struct timeval *stop)
74{
75 uint64_t diff;
76
77 if (stop->tv_sec < start->tv_sec) return 0;
78
79 diff = (stop->tv_sec - start->tv_sec) * 1000000ULL;
80 if (stop->tv_usec > start->tv_usec) {
81 diff += stop->tv_usec - start->tv_usec;
82 } else {
83 diff -= start->tv_usec - stop->tv_usec;
84 }
85
86 return diff;
87}
88
89/* Updates min-max stat */
90void update_stat(struct rng_stat *stat, uint64_t value)
91{
92 uint64_t overflow = stat->num_samples;
93
94 if ((stat->min == 0 ) || (value < stat->min)) stat->min = value;
95 if (value > stat->max) stat->max = value;
96 if (++stat->num_samples > overflow) {
97 stat->sum += value;
98 } else {
99 stat->sum = value;
100 stat->num_samples = 1;
101 }
102}
103
104char *dump_stat_counter(char *buf, int size,
105 const char *msg, uint64_t value)
106{
107 buf[size-1] = 0;
92ee2129
JG
108 snprintf(buf, size-1, "%s%s: %llu", stat_prefix, msg,
109 (unsigned long long) value);
61af3de3
JG
110
111 return buf;
112}
113
114char *dump_stat_stat(char *buf, int size,
115 const char *msg, const char *unit, struct rng_stat *stat)
116{
117 double avg = 0.0;
118
119 if (stat->num_samples > 0)
120 avg = (double)stat->sum / stat->num_samples;
121
122 buf[size-1] = 0;
123 snprintf(buf, size-1, "%s%s: (min=%llu; avg=%.3f; max=%llu)%s",
92ee2129
JG
124 stat_prefix, msg, (unsigned long long) stat->min, avg,
125 (unsigned long long) stat->max, unit);
61af3de3
JG
126
127 return buf;
128}
129
130char *dump_stat_bw(char *buf, int size,
d1b4c504
JG
131 const char *msg, const char *unit,
132 struct rng_stat *stat,
61af3de3
JG
133 uint64_t blocksize)
134{
135 char unitscaled[20];
136 double bw_avg = 0.0, bw_min = 0.0, bw_max = 0.0;
137
138 if (stat->max > 0)
139 bw_min = (1000000.0 * blocksize) / stat->max;
140 if (stat->min > 0)
141 bw_max = (1000000.0 * blocksize) / stat->min;
142 if (stat->num_samples > 0)
143 bw_avg = (1000000.0 * blocksize * stat->num_samples) / stat->sum;
144
145 scale_mult_unit(unitscaled, sizeof(unitscaled), unit,
146 &bw_min, &bw_avg, &bw_max);
147
148 buf[size-1] = 0;
149 snprintf(buf, size-1, "%s%s: (min=%.3f; avg=%.3f; max=%.3f)%s/s",
150 stat_prefix, msg, bw_min, bw_avg, bw_max, unitscaled);
151
152 return buf;
153}
154