mempool-alloconly.c revision aec53c0bccddc338722bd466dcd93b329c4e5295
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mempool-alloconly.c : Memory pool for fast allocation of memory without
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw need to free it in small blocks
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw Copyright (c) 2002 Timo Sirainen
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw Permission is hereby granted, free of charge, to any person obtaining
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw a copy of this software and associated documentation files (the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw "Software"), to deal in the Software without restriction, including
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw without limitation the rights to use, copy, modify, merge, publish,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw distribute, sublicense, and/or sell copies of the Software, and to
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw permit persons to whom the Software is furnished to do so, subject to
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw the following conditions:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw The above copyright notice and this permission notice shall be
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw included in all copies or substantial portions of the Software.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* @UNSAFE: whole file */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwtypedef struct {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define SIZEOF_ALLOCONLYPOOL (sizeof(AlloconlyPool)-MEM_ALIGN_SIZE)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* unsigned char data[]; */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwtypedef struct {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define SIZEOF_POOLALLOC (sizeof(PoolAlloc)-MEM_ALIGN_SIZE)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void *pool_alloconly_malloc(Pool pool, size_t size);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void *pool_alloconly_realloc(Pool pool, void *mem, size_t size);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void *pool_alloconly_realloc_min(Pool pool, void *mem, size_t size);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void block_alloc(AlloconlyPool *pool, size_t size);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* destroy all but the last block */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* destroy the last block */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void block_alloc(AlloconlyPool *apool, size_t size)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* each block is at least twice the size of the previous one */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void *pool_alloconly_malloc(Pool pool, size_t size)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* we need a new block */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void pool_alloconly_free(Pool pool __attr_unused__,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* ignore */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void *pool_alloconly_realloc(Pool pool, void *mem, size_t size)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* there's no point in shrinking the memory usage,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw so just do the same as realloc_min() */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pool_try_grow(AlloconlyPool *apool, void *mem, size_t size)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* see if we want to grow the memory we allocated last */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (POOL_BLOCK_DATA(apool->block) + (apool->block->size -
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* yeah, see if we can grow */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* just shrink the available size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void *pool_alloconly_realloc_min(Pool pool, void *mem, size_t size)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned char *new_mem;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* get old size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* see if we can directly grow it */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* slow way - allocate + copy */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* clear new data */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* destroy all blocks but the last, which is the largest */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* clear the last block */