Checksumming updates
[fio.git] / crc / test.c
CommitLineData
fec0f21c
JA
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "../fio.h"
6#include "../gettime.h"
9e52966e 7#include "../fio_time.h"
fec0f21c
JA
8#include "../verify.h"
9
10#include "../crc/md5.h"
11#include "../crc/crc64.h"
12#include "../crc/crc32.h"
13#include "../crc/crc32c.h"
14#include "../crc/crc16.h"
15#include "../crc/crc7.h"
16#include "../crc/sha1.h"
17#include "../crc/sha256.h"
18#include "../crc/sha512.h"
844ea602 19#include "../crc/xxhash.h"
fec0f21c 20
ea1f1da3
JA
21#include "test.h"
22
f7540869
JA
23#define CHUNK 131072U
24#define NR_CHUNKS 2048U
fec0f21c
JA
25
26struct test_type {
27 const char *name;
28 unsigned int mask;
ae7e055f 29 void (*fn)(void *, size_t);
fec0f21c
JA
30};
31
32enum {
33 T_MD5 = 1U << 0,
34 T_CRC64 = 1U << 1,
35 T_CRC32 = 1U << 2,
36 T_CRC32C = 1U << 3,
37 T_CRC16 = 1U << 4,
38 T_CRC7 = 1U << 5,
39 T_SHA1 = 1U << 6,
40 T_SHA256 = 1U << 7,
41 T_SHA512 = 1U << 8,
844ea602 42 T_XXHASH = 1U << 9,
fec0f21c
JA
43};
44
ae7e055f 45static void t_md5(void *buf, size_t size)
fec0f21c
JA
46{
47 uint32_t digest[4];
48 struct fio_md5_ctx ctx = { .hash = digest };
fec0f21c
JA
49 int i;
50
51 fio_md5_init(&ctx);
52
fec0f21c 53 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 54 fio_md5_update(&ctx, buf, size);
f99d67f9
JA
55
56 fio_md5_final(&ctx);
fec0f21c
JA
57}
58
ae7e055f 59static void t_crc64(void *buf, size_t size)
fec0f21c 60{
fec0f21c
JA
61 int i;
62
fec0f21c 63 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 64 fio_crc64(buf, size);
fec0f21c
JA
65}
66
ae7e055f 67static void t_crc32(void *buf, size_t size)
fec0f21c 68{
fec0f21c
JA
69 int i;
70
fec0f21c 71 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 72 fio_crc32(buf, size);
fec0f21c
JA
73}
74
ae7e055f 75static void t_crc32c(void *buf, size_t size)
fec0f21c 76{
fec0f21c
JA
77 int i;
78
fec0f21c 79 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 80 fio_crc32c(buf, size);
fec0f21c
JA
81}
82
ae7e055f 83static void t_crc16(void *buf, size_t size)
fec0f21c 84{
fec0f21c
JA
85 int i;
86
fec0f21c 87 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 88 fio_crc16(buf, size);
fec0f21c
JA
89}
90
ae7e055f 91static void t_crc7(void *buf, size_t size)
fec0f21c 92{
fec0f21c
JA
93 int i;
94
fec0f21c 95 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 96 fio_crc7(buf, size);
fec0f21c
JA
97}
98
ae7e055f 99static void t_sha1(void *buf, size_t size)
fec0f21c
JA
100{
101 uint32_t sha[5];
102 struct fio_sha1_ctx ctx = { .H = sha };
fec0f21c
JA
103 int i;
104
105 fio_sha1_init(&ctx);
106
fec0f21c 107 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 108 fio_sha1_update(&ctx, buf, size);
fec0f21c
JA
109}
110
ae7e055f 111static void t_sha256(void *buf, size_t size)
fec0f21c
JA
112{
113 uint8_t sha[64];
114 struct fio_sha256_ctx ctx = { .buf = sha };
fec0f21c
JA
115 int i;
116
117 fio_sha256_init(&ctx);
118
fec0f21c 119 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 120 fio_sha256_update(&ctx, buf, size);
f99d67f9
JA
121
122 fio_sha256_final(&ctx);
fec0f21c
JA
123}
124
ae7e055f 125static void t_sha512(void *buf, size_t size)
fec0f21c
JA
126{
127 uint8_t sha[128];
128 struct fio_sha512_ctx ctx = { .buf = sha };
fec0f21c
JA
129 int i;
130
131 fio_sha512_init(&ctx);
132
fec0f21c 133 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 134 fio_sha512_update(&ctx, buf, size);
fec0f21c
JA
135}
136
ae7e055f 137static void t_xxhash(void *buf, size_t size)
844ea602
JA
138{
139 void *state;
844ea602
JA
140 int i;
141
142 state = XXH32_init(0x8989);
143
844ea602 144 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 145 XXH32_update(state, buf, size);
844ea602
JA
146
147 XXH32_digest(state);
844ea602
JA
148}
149
fec0f21c
JA
150static struct test_type t[] = {
151 {
152 .name = "md5",
153 .mask = T_MD5,
154 .fn = t_md5,
155 },
156 {
157 .name = "crc64",
158 .mask = T_CRC64,
159 .fn = t_crc64,
160 },
161 {
162 .name = "crc32",
163 .mask = T_CRC32,
164 .fn = t_crc32,
165 },
166 {
167 .name = "crc32c",
168 .mask = T_CRC32C,
169 .fn = t_crc32c,
170 },
171 {
172 .name = "crc16",
173 .mask = T_CRC16,
174 .fn = t_crc16,
175 },
176 {
177 .name = "crc7",
178 .mask = T_CRC7,
179 .fn = t_crc7,
180 },
181 {
182 .name = "sha1",
183 .mask = T_SHA1,
184 .fn = t_sha1,
185 },
186 {
187 .name = "sha256",
188 .mask = T_SHA256,
189 .fn = t_sha256,
190 },
191 {
192 .name = "sha512",
193 .mask = T_SHA512,
194 .fn = t_sha512,
195 },
844ea602
JA
196 {
197 .name = "xxhash",
198 .mask = T_XXHASH,
199 .fn = t_xxhash,
200 },
fec0f21c
JA
201 {
202 .name = NULL,
203 },
204};
205
206static unsigned int get_test_mask(const char *type)
207{
208 char *ostr, *str = strdup(type);
209 unsigned int mask;
210 char *name;
211 int i;
212
213 ostr = str;
214 mask = 0;
215 while ((name = strsep(&str, ",")) != NULL) {
216 for (i = 0; t[i].name; i++) {
f7540869 217 if (!strcmp(t[i].name, name)) {
fec0f21c
JA
218 mask |= t[i].mask;
219 break;
220 }
221 }
222 }
223
224 free(ostr);
225 return mask;
226}
227
782744ef
JA
228static int list_types(void)
229{
230 int i;
231
232 for (i = 0; t[i].name; i++)
233 printf("%s\n", t[i].name);
234
24ef7a61 235 return 1;
782744ef
JA
236}
237
fec0f21c
JA
238int fio_crctest(const char *type)
239{
240 unsigned int test_mask = 0;
241 uint64_t mb = CHUNK * NR_CHUNKS;
ae7e055f 242 struct frand_state state;
24ef7a61
JA
243 int i, first = 1;
244 void *buf;
fec0f21c
JA
245
246 crc32c_intel_probe();
247
248 if (!type)
249 test_mask = ~0U;
782744ef
JA
250 else if (!strcmp(type, "help") || !strcmp(type, "list"))
251 return list_types();
fec0f21c
JA
252 else
253 test_mask = get_test_mask(type);
254
24ef7a61
JA
255 if (!test_mask) {
256 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
257 return list_types();
258 }
259
260 buf = malloc(CHUNK);
ae7e055f
JA
261 init_rand_seed(&state, 0x8989);
262 fill_random_buf(&state, buf, CHUNK);
24ef7a61 263
fec0f21c 264 for (i = 0; t[i].name; i++) {
ae7e055f 265 struct timeval tv;
fec0f21c
JA
266 double mb_sec;
267 uint64_t usec;
268
269 if (!(t[i].mask & test_mask))
270 continue;
271
ae7e055f
JA
272 /*
273 * For first run, make sure CPUs are spun up and that
274 * we've touched the data.
275 */
276 if (first) {
277 usec_spin(100000);
278 t[i].fn(buf, CHUNK);
279 }
280
281 fio_gettime(&tv, NULL);
282 t[i].fn(buf, CHUNK);
283 usec = utime_since_now(&tv);
24ef7a61 284
fec0f21c
JA
285 mb_sec = (double) mb / (double) usec;
286 mb_sec /= (1.024 * 1.024);
31538d87 287 printf("%s:\t%8.2f MB/sec\n", t[i].name, mb_sec);
24ef7a61 288 first = 0;
fec0f21c 289 }
782744ef 290
24ef7a61 291 free(buf);
fec0f21c
JA
292 return 0;
293}