Merge branch 'fio-c++-engine' of https://github.com/tchaikov/fio
[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  = 0,
121                         .nr     = 0,
122                         .ret    = 0,
123                 },
124                 {
125                         .start  = 16,
126                         .nr     = 16,
127                         .ret    = 16,
128                 },
129                 {
130                         .start  = 16,
131                         .nr     = 0,
132                         .ret    = 0,
133                 },
134                 {
135                         .start  = 0,
136                         .nr     = 32,
137                         .ret    = 16,
138                 },
139                 {
140                         .start  = 48,
141                         .nr     = 32,
142                         .ret    = 32,
143                 },
144                 {
145                         .start  = 32,
146                         .nr     = 32,
147                         .ret    = 16,
148                 },
149                 {
150                         .start  = 79,
151                         .nr     = 1,
152                         .ret    = 0,
153                 },
154                 {
155                         .start  = 80,
156                         .nr     = 21,
157                         .ret    = 21,
158                 },
159                 {
160                         .start  = 102,
161                         .nr     = 1,
162                         .ret    = 1,
163                 },
164                 {
165                         .start  = 101,
166                         .nr     = 3,
167                         .ret    = 1,
168                 },
169                 {
170                         .start  = 106,
171                         .nr     = 4,
172                         .ret    = 4,
173                 },
174                 {
175                         .start  = 105,
176                         .nr     = 3,
177                         .ret    = 1,
178                 },
179                 {
180                         .start  = 120,
181                         .nr     = 4,
182                         .ret    = 4,
183                 },
184                 {
185                         .start  = 118,
186                         .nr     = 2,
187                         .ret    = 2,
188                 },
189                 {
190                         .start  = 118,
191                         .nr     = 2,
192                         .ret    = 0,
193                 },
194                 {
195                         .start  = 1100,
196                         .nr     = 1,
197                         .ret    = 1,
198                 },
199                 {
200                         .start  = 1000,
201                         .nr     = 256,
202                         .ret    = 100,
203                 },
204                 {
205                         .start  = 22684,
206                         .nr     = 1,
207                         .ret    = 1,
208                 },
209                 {
210                         .start  = 22670,
211                         .nr     = 60,
212                         .ret    = 14,
213                 },
214                 {
215                         .start  = -1U,
216                 },
217         };
218         struct axmap *map;
219         int entries, i, ret, err = 0;
220
221         entries = 0;
222         for (i = 0; tests[i].start != -1U; i++) {
223                 unsigned int this = tests[i].start + tests[i].nr;
224
225                 if (this > entries)
226                         entries = this;
227         }
228
229         printf("Test overlaps...");
230         fflush(stdout);
231
232         map = axmap_new(entries);
233
234         for (i = 0; tests[i].start != -1U; i++) {
235                 struct overlap_test *t = &tests[i];
236
237                 ret = axmap_set_nr(map, t->start, t->nr);
238                 if (ret != t->ret) {
239                         printf("fail\n");
240                         printf("start=%u, nr=%d, ret=%d: %d\n", t->start, t->nr,
241                                                                 t->ret, ret);
242                         err = 1;
243                         break;
244                 }
245         }
246
247         if (!err)
248                 printf("pass!\n");
249         axmap_free(map);
250         return err;
251 }
252
253 int main(int argc, char *argv[])
254 {
255         size_t size = (1UL << 23) - 200;
256         int seed = 1;
257
258         if (argc > 1) {
259                 size = strtoul(argv[1], NULL, 10);
260                 if (argc > 2)
261                         seed = strtoul(argv[2], NULL, 10);
262         }
263
264         if (test_regular(size, seed))
265                 return 1;
266         if (test_multi(size, 0))
267                 return 2;
268         if (test_multi(size, 17))
269                 return 3;
270         if (test_overlap())
271                 return 4;
272
273         return 0;
274 }