Unify process_alloc() and process_realloc() with PROCESS_ALLOC_MODE_REALLOC bit
[moveable_pool.git] / pool_test_run.c
1 #include <assert.h>
2 #include <stdbool.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "pool.h"
7 #include "rassert.h"
8
9 int *mem;
10
11 void move(struct pool_item *item, int new_base) {
12   int base = item->base;
13   int size = item->limit - base;
14   printf(
15     "move [%d,%d) to [%d,%d)\n",
16     base,
17     base + size,
18     new_base,
19     new_base + size
20   );
21   assert(new_base < base || new_base >= base + size);
22   for (int i = 0; i < size; ++i) {
23     mem[new_base + i] = mem[base + i];
24     mem[base + i] = 0xaaaaaaaa;
25   }
26 }
27
28 void move_up(struct pool_item *item, int new_limit) {
29   int limit = item->limit;
30   int neg_size = item->base - limit;
31   printf(
32     "move_up [%d,%d) to [%d,%d)\n",
33     limit + neg_size,
34     limit,
35     new_limit + neg_size,
36     new_limit
37   );
38   assert(new_limit > limit || new_limit <= limit + neg_size);
39   for (int i = -1; i >= neg_size; --i) {
40     mem[new_limit + i] = mem[limit + i];
41     mem[limit + i] = 0xaaaaaaaa;
42   }
43 }
44
45 void hash_init(int item, int base, int size, int offset) {
46   for (int i = 0; i < size; ++i) {
47     rassert(mem[base + i] == 0xaaaaaaaa);
48     mem[base + i] = item * 17 + (i + offset) * 29;
49   }
50 }
51
52 void hash_verify(int item, int base, int size, int offset) {
53   for (int i = 0; i < size; ++i) {
54     rassert(mem[base + i] == item * 17 + (i + offset) * 29);
55     mem[base + i] = 0xaaaaaaaa;
56   }
57 }
58
59 int main(int argc, char **argv) {
60   if (argc < 3) {
61     printf("usage: %s n_items pool_size [moveable]\n", argv[0]);
62     exit(EXIT_FAILURE);
63   }
64   int n_items = atoi(argv[1]);
65   int pool_size = atoi(argv[2]);
66   int mode = 0;
67   if (argc >= 4 && strcmp(argv[3], "false") != 0)
68     mode |= POOL_ALLOC_MODE_LAST_FIT;
69   if (argc >= 5 && strcmp(argv[4], "false") != 0)
70     mode |= POOL_ALLOC_MODE_MOVEABLE;
71
72   struct pool_head head;
73   pool_init(&head, 0, pool_size, move, move_up);
74
75   struct pool_item *items = malloc(n_items * sizeof(struct pool_item));
76   rassert(items);
77   memset(items, 0, n_items * sizeof(struct pool_item));
78
79   mem = malloc(pool_size * sizeof(int));
80   memset(mem, 0xaa, pool_size * sizeof(int));
81
82   while (true) {
83  //printf("avail %d\n", head.avail);
84     char buf[256];
85     switch (scanf("%s", buf)) {
86     case -1:
87       goto done;
88     case 1:
89       break;
90     default:
91       rassert(false);
92     }
93     if (strcmp(buf, "alloc") == 0) {
94       int item, size;
95       rassert(scanf("%d %d %s", &item, &size, buf) == 3);
96       rassert(item >= 0 && item < n_items);
97       rassert(size >= 0);
98       bool success;
99       if (strcmp(buf, "false") == 0)
100         success = false;
101       else if (strcmp(buf, "true") == 0)
102         success = true;
103       else
104         rassert(false);
105       printf(
106         "alloc %d %d %s\n",
107         item,
108         size,
109         success ? "true" : "false"
110       );
111       rassert(items[item].prev == NULL);
112       bool result = pool_alloc(&head, items + item, size, mode);
113       printf(
114         "... %s\n",
115         result == success ?
116           "ok" :
117           result ? "succeeded, should fail" : "failed, should succeed"
118       );
119       if (result) {
120         if (!success) {
121           printf("... undo\n");
122           pool_free(&head, items + item);
123           items[item].prev = NULL;
124         }
125         else {
126           int base = items[item].base;
127           rassert(items[item].limit == base + size); 
128  //printf("new region [%d,%d)\n", base, base + size);
129           hash_init(item, base, size, 0);
130         }
131       }
132     }
133     else if (strcmp(buf, "realloc") == 0) {
134       int item, old_size, size;
135       rassert(scanf("%d %d %d %s", &item, &old_size, &size, buf) == 4);
136       rassert(item >= 0 && item < n_items);
137       rassert(old_size >= 0);
138       rassert(size >= 0);
139       bool success;
140       if (strcmp(buf, "false") == 0)
141         success = false;
142       else if (strcmp(buf, "true") == 0)
143         success = true;
144       else
145         rassert(false);
146       printf(
147         "realloc %d %d %d %s\n",
148         item,
149         old_size,
150         size,
151         success ? "true" : "false"
152       );
153       if (items[item].prev == NULL)
154         printf("... not allocated, ignore\n");
155       else {
156         int base = items[item].base;
157         int actual_old_size = items[item].limit - items[item].base;
158         if (actual_old_size != old_size) {
159           printf(
160             "... old size %d, should be %d\n",
161             actual_old_size,
162             old_size
163           );
164           rassert(actual_old_size <= old_size);
165         }
166  //printf("old region [%d,%d)\n", base, base + actual_old_size);
167         hash_verify(
168           item,
169           base + size,
170           actual_old_size - size,
171           size
172         );
173         bool result = pool_alloc(
174           &head,
175           items + item,
176           size,
177           mode | POOL_ALLOC_MODE_REALLOC,
178           0
179         );
180         printf(
181           "... %s\n",
182           result == success ?
183             "ok" :
184             result ? "succeeded, should fail" : "failed, should succeed"
185         );
186         if (result) {
187           if (!success) {
188             printf("... undo\n");
189             rassert(
190               pool_alloc(
191                 &head,
192                 items + item,
193                 actual_old_size,
194                 mode | POOL_ALLOC_MODE_REALLOC,
195                 0
196               )
197             );
198           }
199           else {
200             base = items[item].base;
201             rassert(items[item].limit == base + size);
202  //printf("new region [%d,%d)\n", base, base + size);
203             hash_init(
204               item,
205               base + actual_old_size,
206               size - actual_old_size,
207               actual_old_size
208             );
209           }
210         }
211       }
212     }
213     else if (strcmp(buf, "realloc_base") == 0) {
214       int item, old_size, size;
215       rassert(scanf("%d %d %d %s", &item, &old_size, &size, buf) == 4);
216       rassert(item >= 0 && item < n_items);
217       rassert(old_size >= 0);
218       rassert(size >= 0);
219       bool success;
220       if (strcmp(buf, "false") == 0)
221         success = false;
222       else if (strcmp(buf, "true") == 0)
223         success = true;
224       else
225         rassert(false);
226       printf(
227         "realloc_base %d %d %d %s\n",
228         item,
229         old_size,
230         size,
231         success ? "true" : "false"
232       );
233       if (items[item].prev == NULL)
234         printf("... not allocated, ignore\n");
235       else {
236         int base = items[item].base;
237         int actual_old_size = items[item].limit - items[item].base;
238         if (actual_old_size != old_size) {
239           printf(
240             "... old size %d, should be %d\n",
241             actual_old_size,
242             old_size
243           );
244           rassert(actual_old_size <= old_size);
245         }
246  //printf("old region [%d,%d)\n", base, base + actual_old_size);
247         hash_verify(item, base, actual_old_size - size, 0);
248         bool result = pool_alloc(
249           &head,
250           items + item,
251           size,
252           mode ^ (
253             POOL_ALLOC_MODE_LAST_FIT |
254             POOL_ALLOC_MODE_REALLOC
255           ),
256           size - actual_old_size
257         );
258         printf(
259           "... %s\n",
260           result == success ?
261             "ok" :
262             result ? "succeeded, should fail" : "failed, should succeed"
263         );
264         if (result) {
265           if (!success) {
266             printf("... undo\n");
267             rassert(
268               pool_alloc(
269                 &head,
270                 items + item,
271                 actual_old_size,
272                 mode ^ (
273                   POOL_ALLOC_MODE_LAST_FIT |
274                   POOL_ALLOC_MODE_REALLOC
275                 ),
276                 actual_old_size - size
277               )
278             );
279           }
280           else {
281             base = items[item].base;
282             rassert(items[item].limit == base + size);
283  //printf("new region [%d,%d)\n", base, base + size);
284             if (size >= actual_old_size)
285               hash_verify(
286                 item,
287                 base + size - actual_old_size,
288                 actual_old_size,
289                 0
290               );
291             else
292               hash_verify(
293                 item,
294                 base,
295                 size,
296                 actual_old_size - size
297               );
298             hash_init(item, base, size, 0);
299           }
300         }
301       }
302     }
303     else if (strcmp(buf, "free") == 0) {
304       int item, old_size;
305       rassert(scanf("%d %d", &item, &old_size) == 2);
306       rassert(item >= 0 && item < n_items);
307       rassert(old_size >= 0);
308       printf(
309         "free %d %d\n",
310         item,
311         old_size
312       );
313       if (items[item].prev == NULL)
314         printf("... not allocated, ignore\n");
315       else {
316         int base = items[item].base;
317         int actual_old_size = items[item].limit - base;
318         if (actual_old_size != old_size) {
319           printf(
320             "... old size %d, should be %d\n",
321             actual_old_size,
322             old_size
323           );
324           rassert(actual_old_size <= old_size);
325         }
326  //printf("old region [%d,%d)\n", base, base + actual_old_size);
327         hash_verify(item, base, actual_old_size, 0);
328         pool_free(&head, items + item);
329         items[item].prev = NULL;
330         printf("... ok\n");
331       }
332     }
333     else
334       rassert(false);
335   }
336
337 done:
338   printf("final state:\n");
339   for (int i = 0; i < n_items; ++i) {
340     if (items[i].prev == NULL)
341       printf("item %d: not allocated\n", i);
342     else {
343       int base = items[i].base;
344       int size = items[i].limit - base;
345       printf("item %d: region [%d,%d)\n", i, base, base + size);
346       hash_verify(i, base, size, 0);
347     }
348   }
349
350   for (int i = 0; i < pool_size; ++i)
351     rassert(mem[i] == 0xaaaaaaaa);
352
353   return 0;
354 }