t/axmap: clean up overlap tests
[fio.git] / t / axmap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <inttypes.h>
4
5 #include "../lib/lfsr.h"
6 #include "../lib/axmap.h"
7
8 static int test_regular(size_t size, int seed)
9 {
10         struct fio_lfsr lfsr;
11         struct axmap *map;
12         size_t osize;
13         uint64_t ff;
14         int err;
15
16         printf("Using %llu entries...", (unsigned long long) size);
17         fflush(stdout);
18
19         lfsr_init(&lfsr, size, seed, seed & 0xF);
20         map = axmap_new(size);
21         osize = size;
22         err = 0;
23
24         while (size--) {
25                 uint64_t val;
26
27                 if (lfsr_next(&lfsr, &val)) {
28                         printf("lfsr: short loop\n");
29                         err = 1;
30                         break;
31                 }
32                 if (axmap_isset(map, val)) {
33                         printf("bit already set\n");
34                         err = 1;
35                         break;
36                 }
37                 axmap_set(map, val);
38                 if (!axmap_isset(map, val)) {
39                         printf("bit not set\n");
40                         err = 1;
41                         break;
42                 }
43         }
44
45         if (err)
46                 return err;
47
48         ff = axmap_next_free(map, osize);
49         if (ff != (uint64_t) -1ULL) {
50                 printf("axmap_next_free broken: got %llu\n", (unsigned long long) ff);
51                 return 1;
52         }
53
54         printf("pass!\n");
55         axmap_free(map);
56         return 0;
57 }
58
59 static int test_multi(size_t size, unsigned int bit_off)
60 {
61         unsigned int map_size = size;
62         struct axmap *map;
63         uint64_t val = bit_off;
64         int i, err;
65
66         printf("Test multi %llu entries %u offset...", (unsigned long long) size, bit_off);
67         fflush(stdout);
68
69         map = axmap_new(map_size);
70         while (val + 128 <= map_size) {
71                 err = 0;
72                 for (i = val; i < val + 128; i++) {
73                         if (axmap_isset(map, val + i)) {
74                                 printf("bit already set\n");
75                                 err = 1;
76                                 break;
77                         }
78                 }
79
80                 if (err)
81                         break;
82
83                 err = axmap_set_nr(map, val, 128);
84                 if (err != 128) {
85                         printf("only set %u bits\n", err);
86                         break;
87                 }
88
89                 err = 0;
90                 for (i = 0; i < 128; i++) {
91                         if (!axmap_isset(map, val + i)) {
92                                 printf("bit not set: %llu\n", (unsigned long long) val + i);
93                                 err = 1;
94                                 break;
95                         }
96                 }
97
98                 val += 128;
99                 if (err)
100                         break;
101         }
102
103         if (!err)
104                 printf("pass!\n");
105
106         axmap_free(map);
107         return err;
108 }
109
110 struct overlap_test {
111         unsigned int start;
112         unsigned int nr;
113         unsigned int ret;
114 };
115
116 static int test_overlap(void)
117 {
118         struct overlap_test tests[] = {
119                 {
120                         .start  = 16,
121                         .nr     = 16,
122                         .ret    = 16,
123                 },
124                 {
125                         .start  = 0,
126                         .nr     = 32,
127                         .ret    = 16,
128                 },
129                 {
130                         .start  = 48,
131                         .nr     = 32,
132                         .ret    = 32,
133                 },
134                 {
135                         .start  = 32,
136                         .nr     = 32,
137                         .ret    = 16,
138                 },
139                 {
140                         .start  = 102,
141                         .nr     = 1,
142                         .ret    = 1,
143                 },
144                 {
145                         .start  = 101,
146                         .nr     = 3,
147                         .ret    = 1,
148                 },
149                 {
150                         .start  = 106,
151                         .nr     = 4,
152                         .ret    = 4,
153                 },
154                 {
155                         .start  = 105,
156                         .nr     = 3,
157                         .ret    = 1,
158                 },
159                 {
160                         .start  = 120,
161                         .nr     = 4,
162                         .ret    = 4,
163                 },
164                 {
165                         .start  = 118,
166                         .nr     = 2,
167                         .ret    = 2,
168                 },
169                 {
170                         .start  = 118,
171                         .nr     = 2,
172                         .ret    = 0,
173                 },
174                 {
175                         .start  = -1U,
176                 },
177         };
178         struct axmap *map;
179         int entries, i, ret, err = 0;
180
181         entries = 0;
182         for (i = 0; tests[i].start != 1U; i++) {
183                 unsigned int this = tests[i].start + tests[i].nr;
184
185                 if (this > entries)
186                         entries = this;
187         }
188
189         printf("Test overlaps...");
190         fflush(stdout);
191
192         map = axmap_new(entries);
193
194         for (i = 0; tests[i].start != -1U; i++) {
195                 struct overlap_test *t = &tests[i];
196
197                 ret = axmap_set_nr(map, t->start, t->nr);
198                 if (ret != t->ret) {
199                         printf("fail\n");
200                         printf("start=%u, nr=%d, ret=%d: %d\n", t->start, t->nr,
201                                                                 t->ret, ret);
202                         err = 1;
203                         break;
204                 }
205         }
206
207         printf("pass!\n");
208         axmap_free(map);
209         return err;
210 }
211
212 int main(int argc, char *argv[])
213 {
214         size_t size = (1UL << 23) - 200;
215         int seed = 1;
216
217         if (argc > 1) {
218                 size = strtoul(argv[1], NULL, 10);
219                 if (argc > 2)
220                         seed = strtoul(argv[2], NULL, 10);
221         }
222
223         if (test_regular(size, seed))
224                 return 1;
225         if (test_multi(size, 0))
226                 return 2;
227         if (test_multi(size, 17))
228                 return 3;
229         if (test_overlap())
230                 return 4;
231
232         return 0;
233 }