]> git.ozlabs.org Git - ccan/blob - alloc/test/run.c
b0fbe81ccbf3d609ca99ee9a879a84403906090a
[ccan] / alloc / test / run.c
1 #include "alloc/alloc.h"
2 #include "tap.h"
3 #include "alloc/alloc.c"
4 #include <stdlib.h>
5
6 #define POOL_ORD 16
7 #define POOL_SIZE (1 << POOL_ORD)
8
9 #define sort(p, num, cmp) \
10         qsort((p), (num), sizeof(*p), (int(*)(const void *, const void *))cmp)
11
12 static int addr_cmp(void **a, void **b)
13 {
14         return (*a) - (*b);
15 }
16
17 static bool unique(void *p[], unsigned int num)
18 {
19         unsigned int i;
20
21         for (i = 1; i < num; i++)
22                 if (p[i] == p[i-1])
23                         return false;
24         return true;
25 }       
26
27 int main(int argc, char *argv[])
28 {
29         void *mem;
30         unsigned int i, num, max_size;
31         void *p[POOL_SIZE];
32
33         plan_tests(141);
34
35         /* FIXME: Needs to be page aligned for now. */
36         posix_memalign(&mem, getpagesize(), POOL_SIZE);
37
38         /* Small pool, all allocs fail, even 0-length. */
39         alloc_init(mem, 0);
40         ok1(alloc_check(mem, 0));
41         ok1(alloc_get(mem, 0, 1, 1) == NULL);
42         ok1(alloc_get(mem, 0, 128, 1) == NULL);
43         ok1(alloc_get(mem, 0, 0, 1) == NULL);
44
45         /* Free of NULL should work. */
46         alloc_free(mem, 0, NULL);
47
48         alloc_init(mem, POOL_SIZE);
49         ok1(alloc_check(mem, POOL_SIZE));
50         /* Find largest allocation which works. */
51         for (max_size = POOL_SIZE * 2; max_size; max_size--) {
52                 p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
53                 if (p[0])
54                         break;
55         }
56         ok1(max_size < POOL_SIZE);
57         ok1(max_size > 0);
58         ok1(alloc_check(mem, POOL_SIZE));
59
60         /* Free it, should be able to reallocate it. */
61         alloc_free(mem, POOL_SIZE, p[0]);
62         ok1(alloc_check(mem, POOL_SIZE));
63
64         p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
65         ok1(p[0]);
66         ok1(alloc_check(mem, POOL_SIZE));
67         alloc_free(mem, POOL_SIZE, p[0]);
68         ok1(alloc_check(mem, POOL_SIZE));
69
70         /* Allocate a whole heap. */
71         for (i = 0; i < POOL_SIZE; i++) {
72                 p[i] = alloc_get(mem, POOL_SIZE, 1, 1);
73                 if (!p[i])
74                         break;
75         }
76
77         num = i;
78         /* Can't allocate this many. */
79         ok1(num != POOL_SIZE);
80         ok1(alloc_check(mem, POOL_SIZE));
81
82         /* Sort them. */
83         sort(p, num, addr_cmp);
84
85         /* Uniqueness check */
86         ok1(unique(p, num));
87
88         /* Free every second one. */
89         for (i = 0; i < num; i += 2) {
90                 alloc_free(mem, POOL_SIZE, p[i]);
91                 ok1(alloc_check(mem, POOL_SIZE));
92         }
93         for (i = 1; i < num; i += 2) {
94                 alloc_free(mem, POOL_SIZE, p[i]);
95                 ok1(alloc_check(mem, POOL_SIZE));
96         }
97         ok1(alloc_check(mem, POOL_SIZE));
98
99         /* Should be able to reallocate max size. */
100         p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
101         ok1(p[0]);
102         ok1(alloc_check(mem, POOL_SIZE));
103
104         /* Re-initializing should be the same as freeing everything */
105         alloc_init(mem, POOL_SIZE);
106         ok1(alloc_check(mem, POOL_SIZE));
107         p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
108         ok1(p[0]);
109         ok1(alloc_check(mem, POOL_SIZE));
110         alloc_free(mem, POOL_SIZE, p[0]);
111         ok1(alloc_check(mem, POOL_SIZE));
112
113         /* Alignment constraints should be met, as long as powers of two */
114         for (i = 0; i < POOL_ORD-2 /* FIXME: Should be -1 */; i++) {
115                 p[i] = alloc_get(mem, POOL_SIZE, i, 1 << i);
116                 ok1(p[i]);
117                 ok1(((unsigned long)p[i] % (1 << i)) == 0);
118                 ok1(alloc_check(mem, POOL_SIZE));
119         }
120
121         for (i = 0; i < POOL_ORD-2 /* FIXME: Should be -1 */; i++) {
122                 alloc_free(mem, POOL_SIZE, p[i]);
123                 ok1(alloc_check(mem, POOL_SIZE));
124         }
125
126         /* Alignment constraints for a single-byte allocation. */
127         for (i = 0; i < POOL_ORD; i++) {
128                 p[0] = alloc_get(mem, POOL_SIZE, 1, 1 << i);
129                 ok1(p[0]);
130                 ok1(alloc_check(mem, POOL_SIZE));
131                 alloc_free(mem, POOL_SIZE, p[0]);
132                 ok1(alloc_check(mem, POOL_SIZE));
133         }
134
135         return exit_status();
136 }