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