11 void move(struct pool_item *item, int new_base) {
12 int base = item->base;
13 int size = item->limit - base;
15 "move [%d,%d) to [%d,%d)\n",
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;
28 void move_up(struct pool_item *item, int new_limit) {
29 int limit = item->limit;
30 int neg_size = item->base - limit;
32 "move_up [%d,%d) to [%d,%d)\n",
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;
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;
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;
59 int main(int argc, char **argv) {
61 printf("usage: %s n_items pool_size [moveable]\n", argv[0]);
64 int n_items = atoi(argv[1]);
65 int pool_size = atoi(argv[2]);
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;
72 struct pool_head head;
73 pool_init(&head, 0, pool_size, move, move_up);
75 struct pool_item *items = malloc(n_items * sizeof(struct pool_item));
77 memset(items, 0, n_items * sizeof(struct pool_item));
79 mem = malloc(pool_size * sizeof(int));
80 memset(mem, 0xaa, pool_size * sizeof(int));
83 //printf("avail %d\n", head.avail);
85 switch (scanf("%s", buf)) {
93 if (strcmp(buf, "alloc") == 0) {
95 rassert(scanf("%d %d %s", &item, &size, buf) == 3);
96 rassert(item >= 0 && item < n_items);
99 if (strcmp(buf, "false") == 0)
101 else if (strcmp(buf, "true") == 0)
109 success ? "true" : "false"
111 rassert(items[item].prev == NULL);
112 bool result = pool_alloc(&head, items + item, size, mode);
117 result ? "succeeded, should fail" : "failed, should succeed"
121 printf("... undo\n");
122 pool_free(&head, items + item);
123 items[item].prev = NULL;
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);
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);
140 if (strcmp(buf, "false") == 0)
142 else if (strcmp(buf, "true") == 0)
147 "realloc %d %d %d %s\n",
151 success ? "true" : "false"
153 if (items[item].prev == NULL)
154 printf("... not allocated, ignore\n");
156 int base = items[item].base;
157 int actual_old_size = items[item].limit - items[item].base;
158 if (actual_old_size != old_size) {
160 "... old size %d, should be %d\n",
164 rassert(actual_old_size <= old_size);
166 //printf("old region [%d,%d)\n", base, base + actual_old_size);
170 actual_old_size - size,
173 bool result = pool_alloc(
177 mode | POOL_ALLOC_MODE_REALLOC,
184 result ? "succeeded, should fail" : "failed, should succeed"
188 printf("... undo\n");
194 mode | POOL_ALLOC_MODE_REALLOC,
200 base = items[item].base;
201 rassert(items[item].limit == base + size);
202 //printf("new region [%d,%d)\n", base, base + size);
205 base + actual_old_size,
206 size - actual_old_size,
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);
220 if (strcmp(buf, "false") == 0)
222 else if (strcmp(buf, "true") == 0)
227 "realloc_base %d %d %d %s\n",
231 success ? "true" : "false"
233 if (items[item].prev == NULL)
234 printf("... not allocated, ignore\n");
236 int base = items[item].base;
237 int actual_old_size = items[item].limit - items[item].base;
238 if (actual_old_size != old_size) {
240 "... old size %d, should be %d\n",
244 rassert(actual_old_size <= old_size);
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(
253 POOL_ALLOC_MODE_LAST_FIT |
254 POOL_ALLOC_MODE_REALLOC
256 size - actual_old_size
262 result ? "succeeded, should fail" : "failed, should succeed"
266 printf("... undo\n");
273 POOL_ALLOC_MODE_LAST_FIT |
274 POOL_ALLOC_MODE_REALLOC
276 actual_old_size - size
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)
287 base + size - actual_old_size,
296 actual_old_size - size
298 hash_init(item, base, size, 0);
303 else if (strcmp(buf, "free") == 0) {
305 rassert(scanf("%d %d", &item, &old_size) == 2);
306 rassert(item >= 0 && item < n_items);
307 rassert(old_size >= 0);
313 if (items[item].prev == NULL)
314 printf("... not allocated, ignore\n");
316 int base = items[item].base;
317 int actual_old_size = items[item].limit - base;
318 if (actual_old_size != old_size) {
320 "... old size %d, should be %d\n",
324 rassert(actual_old_size <= old_size);
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;
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);
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);
350 for (int i = 0; i < pool_size; ++i)
351 rassert(mem[i] == 0xaaaaaaaa);