8 /* FIXME: Doesn't handle non-page-aligned poolsize. */
9 /* FIXME: Doesn't handle sub-page allocations. */
11 #define MIN_SIZE (getpagesize() * 2)
20 void alloc_init(void *pool, unsigned long poolsize)
23 unsigned int pages = poolsize / getpagesize();
25 if (poolsize < MIN_SIZE)
28 memset(bits, 0, (pages * 2 + CHAR_BIT - 1)/ CHAR_BIT);
31 static enum page_state get_page_state(const uint8_t *bits, unsigned long page)
33 return bits[page * 2 / CHAR_BIT] >> (page * 2 % CHAR_BIT) & 3;
36 static void set_page_state(uint8_t *bits, unsigned long page, enum page_state s)
38 bits[page * 2 / CHAR_BIT] &= ~(3 << (page * 2 % CHAR_BIT));
39 bits[page * 2 / CHAR_BIT] |= ((uint8_t)s << (page * 2 % CHAR_BIT));
42 static unsigned long metadata_length(void *pool, unsigned long poolsize)
44 return ((poolsize / getpagesize() * 2 / CHAR_BIT) + getpagesize() - 1)
45 & ~(getpagesize() - 1);
48 void *alloc_get(void *pool, unsigned long poolsize,
49 unsigned long size, unsigned long align)
51 unsigned long i, free, want, metalen;
53 if (poolsize < MIN_SIZE)
56 /* FIXME: Necessary for this. */
60 want = (size + getpagesize() - 1) / getpagesize();
61 metalen = metadata_length(pool, poolsize);
64 for (i = 0; i < (poolsize - metalen) / getpagesize(); i++) {
65 switch (get_page_state(pool, i)) {
69 char *ret = (char *)pool + metalen
70 + (i - want + 1) * getpagesize();
72 if ((unsigned long)ret % align)
75 for (j = i; j > i - want + 1; j--)
76 set_page_state(pool, j, TAKEN);
77 set_page_state(pool, i - want + 1, TAKEN_START);
91 void alloc_free(void *pool, unsigned long poolsize, void *free)
93 unsigned long pagenum, metalen;
95 if (poolsize < MIN_SIZE)
101 metalen = metadata_length(pool, poolsize);
103 assert(free > pool && (char *)pool + poolsize > (char *)free);
104 assert((unsigned long)free % getpagesize() == 0);
106 pagenum = ((char *)free - (char *)pool - metalen) / getpagesize();
108 assert(get_page_state(pool, pagenum) == TAKEN_START);
109 set_page_state(pool, pagenum, FREE);
110 while (get_page_state(pool, ++pagenum) == TAKEN)
111 set_page_state(pool, pagenum, FREE);
114 bool alloc_check(void *pool, unsigned long poolsize)
116 unsigned int i, metalen;
117 enum page_state last_state = FREE;
119 if (poolsize < MIN_SIZE)
122 metalen = metadata_length(pool, poolsize);
123 for (i = 0; i < (poolsize - metalen) / getpagesize(); i++) {
124 enum page_state state = get_page_state(pool, i);
130 if (last_state == FREE)