Document switch fall-through cases
[fio.git] / t / lfsr-test.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5
6 #include "../lib/lfsr.h"
7 #include "../gettime.h"
8 #include "../fio_time.h"
9
10 static void usage(void)
11 {
12         printf("Usage: lfsr-test 0x<numbers> [seed] [spin] [verify]\n");
13         printf("-------------------------------------------------------------\n");
14         printf("*numbers: how many random numbers to produce (in hex)\n"
15                    "seed:     initial value\n"
16                    "spin:     how many iterations before we produce a number\n"
17                    "verify:   check if LFSR has iterated correctly\n\n"
18                    "Only <numbers> is required. The rest are evaluated to 0 or false\n"
19                    "Elapsed/mean time and verification results are printed at the"
20                "end of the test\n");
21 }
22
23 int main(int argc, char *argv[])
24 {
25         int r;
26         struct timespec start, end;
27         struct fio_lfsr *fl;
28         int verify = 0;
29         unsigned int spin = 0;
30         uint64_t seed = 0;
31         uint64_t numbers;
32         uint64_t v_size;
33         uint64_t i;
34         void *v = NULL, *v_start;
35         double total, mean;
36
37         arch_init(argv);
38
39         /* Read arguments */
40         switch (argc) {
41                 case 5: if (strncmp(argv[4], "verify", 7) == 0)
42                                 verify = 1;
43                         /* fall through */
44                 case 4: spin = atoi(argv[3]);
45                         /* fall through */
46                 case 3: seed = atol(argv[2]);
47                         /* fall through */
48                 case 2: numbers = strtol(argv[1], NULL, 16);
49                                 break;
50                 default: usage();
51                                  return 1;
52         }
53
54         /* Initialize LFSR */
55         fl = malloc(sizeof(struct fio_lfsr));
56         if (!fl) {
57                 perror("malloc");
58                 return 1;
59         }
60
61         r = lfsr_init(fl, numbers, seed, spin);
62         if (r) {
63                 printf("Initialization failed.\n");
64                 return r;
65         }
66
67         /* Print specs */
68         printf("LFSR specs\n");
69         printf("==========================\n");
70         printf("Size is         %u\n", 64 - __builtin_clzl(fl->cached_bit));
71         printf("Max val is      %lu\n", (unsigned long) fl->max_val);
72         printf("XOR-mask is     0x%lX\n", (unsigned long) fl->xormask);
73         printf("Seed is         %lu\n", (unsigned long) fl->last_val);
74         printf("Spin is         %u\n", fl->spin);
75         printf("Cycle length is %lu\n", (unsigned long) fl->cycle_length);
76
77         /* Create verification table */
78         if (verify) {
79                 v_size = numbers * sizeof(uint8_t);
80                 v = malloc(v_size);
81                 memset(v, 0, v_size);
82                 printf("\nVerification table is %lf KiB\n", (double)(v_size) / 1024);
83         }
84         v_start = v;
85
86         /*
87          * Iterate over a tight loop until we have produced all the requested
88          * numbers. Verifying the results should introduce some small yet not
89          * negligible overhead.
90          */
91         fprintf(stderr, "\nTest initiated... ");
92         fio_gettime(&start, NULL);
93         while (!lfsr_next(fl, &i)) {
94                 if (verify)
95                         *(uint8_t *)(v + i) += 1;
96         }
97         fio_gettime(&end, NULL);
98         fprintf(stderr, "finished.\n");
99
100
101         /* Check if all expected numbers within range have been calculated */
102         r = 0;
103         if (verify) {
104                 fprintf(stderr, "Verifying results... ");
105                 for (i = 0; i < numbers; i++) {
106                         if (*(uint8_t *)(v + i) != 1) {
107                                 fprintf(stderr, "failed (%lu = %d).\n",
108                                                 (unsigned long) i,
109                                                 *(uint8_t *)(v + i));
110                                 r = 1;
111                                 break;
112                         }
113                 }
114                 if (!r)
115                         fprintf(stderr, "OK!\n");
116         }
117
118         /* Calculate elapsed time and mean time per number */
119         total = utime_since(&start, &end);
120         mean = total / fl->num_vals;
121
122         printf("\nTime results ");
123         if (verify)
124                 printf("(slower due to verification)");
125         printf("\n==============================\n");
126         printf("Elapsed: %lf s\n", total / pow(10,6));
127         printf("Mean:    %lf us\n", mean);
128
129         free(v_start);
130         free(fl);
131         return r;
132 }