| 16 | }; |
| 17 | |
| 18 | static PoolHeader *make_pool(Allocator &backing, u32 num_blocks, u32 block_size, u32 block_align) |
| 19 | { |
| 20 | const u32 actual_block_size = block_size + block_align - (block_size & (block_align - 1)); |
| 21 | const u32 total_pool_size = sizeof(PoolHeader) |
| 22 | + block_align |
| 23 | + num_blocks * actual_block_size |
| 24 | ; |
| 25 | |
| 26 | PoolHeader *h = (PoolHeader *)backing.allocate(total_pool_size, alignof(PoolHeader)); |
| 27 | h->next = NULL; |
| 28 | h->first_block = (char *)memory::align_top((char *)&h[1], block_align); |
| 29 | |
| 30 | // Initialize freelist. |
| 31 | char *cur = h->first_block; |
| 32 | for (u32 bb = 0; bb < num_blocks - 1; bb++) { |
| 33 | uintptr_t *next = (uintptr_t *)cur; |
| 34 | *next = (uintptr_t)cur + actual_block_size; |
| 35 | cur += actual_block_size; |
| 36 | } |
| 37 | *(uintptr_t *)cur = (uintptr_t)NULL; |
| 38 | |
| 39 | return h; |
| 40 | } |
| 41 | |
| 42 | PoolAllocator::PoolAllocator(Allocator &backing, u32 num_blocks, u32 block_size, u32 block_align) |
| 43 | : _backing(backing) |