1 /* 2 * Copyright 2009 Nicolai Hhnle <nhaehnle (at) gmail.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23 #include "memory_pool.h" 24 25 #include <assert.h> 26 #include <stdlib.h> 27 #include <string.h> 28 29 30 #define POOL_LARGE_ALLOC 4096 31 #define POOL_ALIGN 8 32 33 34 struct memory_block { 35 struct memory_block * next; 36 }; 37 38 void memory_pool_init(struct memory_pool * pool) 39 { 40 memset(pool, 0, sizeof(struct memory_pool)); 41 } 42 43 44 void memory_pool_destroy(struct memory_pool * pool) 45 { 46 while(pool->blocks) { 47 struct memory_block * block = pool->blocks; 48 pool->blocks = block->next; 49 free(block); 50 } 51 } 52 53 static void refill_pool(struct memory_pool * pool) 54 { 55 unsigned int blocksize = pool->total_allocated; 56 struct memory_block * newblock; 57 58 if (!blocksize) 59 blocksize = 2*POOL_LARGE_ALLOC; 60 61 newblock = (struct memory_block*)malloc(blocksize); 62 newblock->next = pool->blocks; 63 pool->blocks = newblock; 64 65 pool->head = (unsigned char*)(newblock + 1); 66 pool->end = ((unsigned char*)newblock) + blocksize; 67 pool->total_allocated += blocksize; 68 } 69 70 71 void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes) 72 { 73 if (bytes < POOL_LARGE_ALLOC) { 74 void * ptr; 75 76 if (pool->head + bytes > pool->end) 77 refill_pool(pool); 78 79 assert(pool->head + bytes <= pool->end); 80 81 ptr = pool->head; 82 83 pool->head += bytes; 84 pool->head = (unsigned char*)(((unsigned long)pool->head + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1)); 85 86 return ptr; 87 } else { 88 struct memory_block * block = (struct memory_block*)malloc(bytes + sizeof(struct memory_block)); 89 90 block->next = pool->blocks; 91 pool->blocks = block; 92 93 return (block + 1); 94 } 95 } 96 97 98