1 /* 2 * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com> 3 * SPDX-License-Identifier: MIT 4 */ 5 6 #include "memory_pool.h" 7 8 #include <assert.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #define POOL_LARGE_ALLOC 4096 13 #define POOL_ALIGN 8 14 15 struct memory_block { 16 struct memory_block *next; 17 }; 18 19 void memory_pool_init(struct memory_pool * pool)20memory_pool_init(struct memory_pool *pool) 21 { 22 memset(pool, 0, sizeof(struct memory_pool)); 23 } 24 25 void memory_pool_destroy(struct memory_pool * pool)26memory_pool_destroy(struct memory_pool *pool) 27 { 28 while (pool->blocks) { 29 struct memory_block *block = pool->blocks; 30 pool->blocks = block->next; 31 free(block); 32 } 33 } 34 35 static void refill_pool(struct memory_pool * pool)36refill_pool(struct memory_pool *pool) 37 { 38 unsigned int blocksize = pool->total_allocated; 39 struct memory_block *newblock; 40 41 if (!blocksize) 42 blocksize = 2 * POOL_LARGE_ALLOC; 43 44 newblock = malloc(blocksize); 45 newblock->next = pool->blocks; 46 pool->blocks = newblock; 47 48 pool->head = (unsigned char *)(newblock + 1); 49 pool->end = ((unsigned char *)newblock) + blocksize; 50 pool->total_allocated += blocksize; 51 } 52 53 void * memory_pool_malloc(struct memory_pool * pool,unsigned int bytes)54memory_pool_malloc(struct memory_pool *pool, unsigned int bytes) 55 { 56 if (bytes < POOL_LARGE_ALLOC) { 57 void *ptr; 58 59 if (pool->head + bytes > pool->end) 60 refill_pool(pool); 61 62 assert(pool->head + bytes <= pool->end); 63 64 ptr = pool->head; 65 66 pool->head += bytes; 67 pool->head = 68 (unsigned char *)(((unsigned long)pool->head + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1)); 69 70 return ptr; 71 } else { 72 struct memory_block *block = malloc(bytes + sizeof(struct memory_block)); 73 74 block->next = pool->blocks; 75 pool->blocks = block; 76 77 return (block + 1); 78 } 79 } 80