backend: make it clear that we passed 'fd' to the new thread
[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"
82e3f7c4 19#include "../crc/sha3.h"
844ea602 20#include "../crc/xxhash.h"
f83ffd02 21#include "../crc/murmur3.h"
951984d8 22#include "../crc/fnv.h"
140dda40 23#include "../hash.h"
fec0f21c 24
ea1f1da3
JA
25#include "test.h"
26
f7540869
JA
27#define CHUNK 131072U
28#define NR_CHUNKS 2048U
fec0f21c
JA
29
30struct test_type {
31 const char *name;
32 unsigned int mask;
140dda40
JA
33 void (*fn)(struct test_type *, void *, size_t);
34 uint32_t output;
fec0f21c
JA
35};
36
37enum {
38 T_MD5 = 1U << 0,
39 T_CRC64 = 1U << 1,
40 T_CRC32 = 1U << 2,
41 T_CRC32C = 1U << 3,
42 T_CRC16 = 1U << 4,
43 T_CRC7 = 1U << 5,
44 T_SHA1 = 1U << 6,
45 T_SHA256 = 1U << 7,
46 T_SHA512 = 1U << 8,
844ea602 47 T_XXHASH = 1U << 9,
9f0e365d 48 T_MURMUR3 = 1U << 10,
140dda40 49 T_JHASH = 1U << 11,
951984d8 50 T_FNV = 1U << 12,
82e3f7c4
JA
51 T_SHA3_224 = 1U << 13,
52 T_SHA3_256 = 1U << 14,
53 T_SHA3_384 = 1U << 15,
54 T_SHA3_512 = 1U << 16,
fec0f21c
JA
55};
56
140dda40 57static void t_md5(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
58{
59 uint32_t digest[4];
60 struct fio_md5_ctx ctx = { .hash = digest };
fec0f21c
JA
61 int i;
62
63 fio_md5_init(&ctx);
64
9c8566f5 65 for (i = 0; i < NR_CHUNKS; i++) {
24ef7a61 66 fio_md5_update(&ctx, buf, size);
9c8566f5
JA
67 fio_md5_final(&ctx);
68 }
fec0f21c
JA
69}
70
140dda40 71static void t_crc64(struct test_type *t, void *buf, size_t size)
fec0f21c 72{
fec0f21c
JA
73 int i;
74
fec0f21c 75 for (i = 0; i < NR_CHUNKS; i++)
674c8f2f 76 t->output += fio_crc64(buf, size);
fec0f21c
JA
77}
78
140dda40 79static void t_crc32(struct test_type *t, void *buf, size_t size)
fec0f21c 80{
fec0f21c
JA
81 int i;
82
fec0f21c 83 for (i = 0; i < NR_CHUNKS; i++)
674c8f2f 84 t->output += fio_crc32(buf, size);
fec0f21c
JA
85}
86
140dda40 87static void t_crc32c(struct test_type *t, void *buf, size_t size)
fec0f21c 88{
fec0f21c
JA
89 int i;
90
fec0f21c 91 for (i = 0; i < NR_CHUNKS; i++)
674c8f2f 92 t->output += fio_crc32c(buf, size);
fec0f21c
JA
93}
94
140dda40 95static void t_crc16(struct test_type *t, void *buf, size_t size)
fec0f21c 96{
fec0f21c
JA
97 int i;
98
fec0f21c 99 for (i = 0; i < NR_CHUNKS; i++)
674c8f2f 100 t->output += fio_crc16(buf, size);
fec0f21c
JA
101}
102
140dda40 103static void t_crc7(struct test_type *t, void *buf, size_t size)
fec0f21c 104{
fec0f21c
JA
105 int i;
106
fec0f21c 107 for (i = 0; i < NR_CHUNKS; i++)
674c8f2f 108 t->output += fio_crc7(buf, size);
fec0f21c
JA
109}
110
140dda40 111static void t_sha1(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
112{
113 uint32_t sha[5];
114 struct fio_sha1_ctx ctx = { .H = sha };
fec0f21c
JA
115 int i;
116
117 fio_sha1_init(&ctx);
118
cbe00046 119 for (i = 0; i < NR_CHUNKS; i++) {
24ef7a61 120 fio_sha1_update(&ctx, buf, size);
cbe00046
JA
121 fio_sha1_final(&ctx);
122 }
fec0f21c
JA
123}
124
140dda40 125static void t_sha256(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
126{
127 uint8_t sha[64];
128 struct fio_sha256_ctx ctx = { .buf = sha };
fec0f21c
JA
129 int i;
130
131 fio_sha256_init(&ctx);
132
9c8566f5 133 for (i = 0; i < NR_CHUNKS; i++) {
24ef7a61 134 fio_sha256_update(&ctx, buf, size);
9c8566f5
JA
135 fio_sha256_final(&ctx);
136 }
fec0f21c
JA
137}
138
140dda40 139static void t_sha512(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
140{
141 uint8_t sha[128];
142 struct fio_sha512_ctx ctx = { .buf = sha };
fec0f21c
JA
143 int i;
144
145 fio_sha512_init(&ctx);
146
fec0f21c 147 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 148 fio_sha512_update(&ctx, buf, size);
fec0f21c
JA
149}
150
82e3f7c4
JA
151static void t_sha3_224(struct test_type *t, void *buf, size_t size)
152{
153 uint8_t sha[SHA3_224_DIGEST_SIZE];
154 struct fio_sha3_ctx ctx = { .sha = sha };
155 int i;
156
157 fio_sha3_224_init(&ctx);
158
159 for (i = 0; i < NR_CHUNKS; i++) {
160 fio_sha3_update(&ctx, buf, size);
161 fio_sha3_final(&ctx);
162 }
163}
164
165static void t_sha3_256(struct test_type *t, void *buf, size_t size)
166{
167 uint8_t sha[SHA3_256_DIGEST_SIZE];
168 struct fio_sha3_ctx ctx = { .sha = sha };
169 int i;
170
171 fio_sha3_256_init(&ctx);
172
173 for (i = 0; i < NR_CHUNKS; i++) {
174 fio_sha3_update(&ctx, buf, size);
175 fio_sha3_final(&ctx);
176 }
177}
178
179static void t_sha3_384(struct test_type *t, void *buf, size_t size)
180{
181 uint8_t sha[SHA3_384_DIGEST_SIZE];
182 struct fio_sha3_ctx ctx = { .sha = sha };
183 int i;
184
185 fio_sha3_384_init(&ctx);
186
187 for (i = 0; i < NR_CHUNKS; i++) {
188 fio_sha3_update(&ctx, buf, size);
189 fio_sha3_final(&ctx);
190 }
191}
192
193static void t_sha3_512(struct test_type *t, void *buf, size_t size)
194{
195 uint8_t sha[SHA3_512_DIGEST_SIZE];
196 struct fio_sha3_ctx ctx = { .sha = sha };
197 int i;
198
199 fio_sha3_512_init(&ctx);
200
201 for (i = 0; i < NR_CHUNKS; i++) {
202 fio_sha3_update(&ctx, buf, size);
203 fio_sha3_final(&ctx);
204 }
205}
206
140dda40 207static void t_murmur3(struct test_type *t, void *buf, size_t size)
9f0e365d
JA
208{
209 int i;
210
211 for (i = 0; i < NR_CHUNKS; i++)
674c8f2f 212 t->output += murmurhash3(buf, size, 0x8989);
9f0e365d
JA
213}
214
140dda40
JA
215static void t_jhash(struct test_type *t, void *buf, size_t size)
216{
217 int i;
218
219 for (i = 0; i < NR_CHUNKS; i++)
220 t->output += jhash(buf, size, 0x8989);
221}
222
951984d8
JA
223static void t_fnv(struct test_type *t, void *buf, size_t size)
224{
225 int i;
226
227 for (i = 0; i < NR_CHUNKS; i++)
228 t->output += fnv(buf, size, 0x8989);
229}
230
140dda40 231static void t_xxhash(struct test_type *t, void *buf, size_t size)
844ea602
JA
232{
233 void *state;
844ea602
JA
234 int i;
235
236 state = XXH32_init(0x8989);
237
844ea602 238 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 239 XXH32_update(state, buf, size);
844ea602 240
140dda40 241 t->output = XXH32_digest(state);
844ea602
JA
242}
243
fec0f21c
JA
244static struct test_type t[] = {
245 {
246 .name = "md5",
247 .mask = T_MD5,
248 .fn = t_md5,
249 },
250 {
251 .name = "crc64",
252 .mask = T_CRC64,
253 .fn = t_crc64,
254 },
255 {
256 .name = "crc32",
257 .mask = T_CRC32,
258 .fn = t_crc32,
259 },
260 {
261 .name = "crc32c",
262 .mask = T_CRC32C,
263 .fn = t_crc32c,
264 },
265 {
266 .name = "crc16",
267 .mask = T_CRC16,
268 .fn = t_crc16,
269 },
270 {
271 .name = "crc7",
272 .mask = T_CRC7,
273 .fn = t_crc7,
274 },
275 {
276 .name = "sha1",
277 .mask = T_SHA1,
278 .fn = t_sha1,
279 },
280 {
281 .name = "sha256",
282 .mask = T_SHA256,
283 .fn = t_sha256,
284 },
285 {
286 .name = "sha512",
287 .mask = T_SHA512,
288 .fn = t_sha512,
289 },
844ea602
JA
290 {
291 .name = "xxhash",
292 .mask = T_XXHASH,
293 .fn = t_xxhash,
294 },
9f0e365d
JA
295 {
296 .name = "murmur3",
297 .mask = T_MURMUR3,
298 .fn = t_murmur3,
299 },
140dda40
JA
300 {
301 .name = "jhash",
302 .mask = T_JHASH,
303 .fn = t_jhash,
304 },
951984d8
JA
305 {
306 .name = "fnv",
307 .mask = T_FNV,
308 .fn = t_fnv,
309 },
82e3f7c4
JA
310 {
311 .name = "sha3-224",
312 .mask = T_SHA3_224,
313 .fn = t_sha3_224,
314 },
315 {
316 .name = "sha3-256",
317 .mask = T_SHA3_256,
318 .fn = t_sha3_256,
319 },
320 {
321 .name = "sha3-384",
322 .mask = T_SHA3_384,
323 .fn = t_sha3_384,
324 },
325 {
326 .name = "sha3-512",
327 .mask = T_SHA3_512,
328 .fn = t_sha3_512,
329 },
fec0f21c
JA
330 {
331 .name = NULL,
332 },
333};
334
335static unsigned int get_test_mask(const char *type)
336{
337 char *ostr, *str = strdup(type);
338 unsigned int mask;
339 char *name;
340 int i;
341
342 ostr = str;
343 mask = 0;
344 while ((name = strsep(&str, ",")) != NULL) {
345 for (i = 0; t[i].name; i++) {
f7540869 346 if (!strcmp(t[i].name, name)) {
fec0f21c
JA
347 mask |= t[i].mask;
348 break;
349 }
350 }
351 }
352
353 free(ostr);
354 return mask;
355}
356
782744ef
JA
357static int list_types(void)
358{
359 int i;
360
361 for (i = 0; t[i].name; i++)
362 printf("%s\n", t[i].name);
363
24ef7a61 364 return 1;
782744ef
JA
365}
366
fec0f21c
JA
367int fio_crctest(const char *type)
368{
369 unsigned int test_mask = 0;
370 uint64_t mb = CHUNK * NR_CHUNKS;
ae7e055f 371 struct frand_state state;
24ef7a61
JA
372 int i, first = 1;
373 void *buf;
fec0f21c 374
214e2d56 375 crc32c_arm64_probe();
fec0f21c
JA
376 crc32c_intel_probe();
377
378 if (!type)
379 test_mask = ~0U;
782744ef
JA
380 else if (!strcmp(type, "help") || !strcmp(type, "list"))
381 return list_types();
fec0f21c
JA
382 else
383 test_mask = get_test_mask(type);
384
24ef7a61
JA
385 if (!test_mask) {
386 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
387 return list_types();
388 }
389
390 buf = malloc(CHUNK);
c3546b53 391 init_rand_seed(&state, 0x8989, 0);
ae7e055f 392 fill_random_buf(&state, buf, CHUNK);
24ef7a61 393
fec0f21c 394 for (i = 0; t[i].name; i++) {
8b6a404c 395 struct timespec ts;
fec0f21c
JA
396 double mb_sec;
397 uint64_t usec;
d78bbd4c 398 char pre[3];
fec0f21c
JA
399
400 if (!(t[i].mask & test_mask))
401 continue;
402
ae7e055f
JA
403 /*
404 * For first run, make sure CPUs are spun up and that
405 * we've touched the data.
406 */
407 if (first) {
408 usec_spin(100000);
140dda40 409 t[i].fn(&t[i], buf, CHUNK);
ae7e055f
JA
410 }
411
8b6a404c 412 fio_gettime(&ts, NULL);
140dda40 413 t[i].fn(&t[i], buf, CHUNK);
8b6a404c 414 usec = utime_since_now(&ts);
24ef7a61 415
e5607fe5
JA
416 if (usec) {
417 mb_sec = (double) mb / (double) usec;
418 mb_sec /= (1.024 * 1.024);
419 if (strlen(t[i].name) >= 7)
420 sprintf(pre, "\t");
421 else
422 sprintf(pre, "\t\t");
4870138d 423 printf("%s:%s%8.2f MiB/sec\n", t[i].name, pre, mb_sec);
e5607fe5 424 } else
4870138d 425 printf("%s:inf MiB/sec\n", t[i].name);
24ef7a61 426 first = 0;
fec0f21c 427 }
782744ef 428
24ef7a61 429 free(buf);
fec0f21c
JA
430 return 0;
431}