]> git.ipfire.org Git - thirdparty/rng-tools.git/blob - stats.c
Change the default device from /dev/hw_random to /dev/hwrng
[thirdparty/rng-tools.git] / stats.c
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.
10 *
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
40 static char stat_prefix[20] = "";
41
42 void 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
48 static void scale_mult_unit(char *unit, int unitsize,
49 const char *baseunit,
50 double *value_min,
51 double *value_avg,
52 double *value_max)
53 {
54 int mult = 0;
55 char multchar[] = "KMGTPE";
56
57 while ((*value_min >= 1024.0) && (*value_avg >= 1024.0) &&
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 */
72 uint64_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 */
90 void 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
104 char *dump_stat_counter(char *buf, int size,
105 const char *msg, uint64_t value)
106 {
107 buf[size-1] = 0;
108 snprintf(buf, size-1, "%s%s: %llu", stat_prefix, msg,
109 (unsigned long long) value);
110
111 return buf;
112 }
113
114 char *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",
124 stat_prefix, msg, (unsigned long long) stat->min, avg,
125 (unsigned long long) stat->max, unit);
126
127 return buf;
128 }
129
130 char *dump_stat_bw(char *buf, int size,
131 const char *msg, const char *unit,
132 struct rng_stat *stat,
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