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