mempool-alloconly.c revision 1bb6586a424225406d55f9fc52a1f11579563073
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* @UNSAFE: whole file */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen char name[MEM_ALIGN_SIZE]; /* variable size */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#define SIZEOF_ALLOCONLYPOOL (sizeof(struct alloconly_pool)-MEM_ALIGN_SIZE)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* unsigned char data[]; */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen#define SIZEOF_POOLBLOCK (MEM_ALIGN(sizeof(struct pool_block)))
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic const char *pool_alloconly_get_name(pool_t pool);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void *pool_alloconly_malloc(pool_t pool, size_t size);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void pool_alloconly_free(pool_t pool, void *mem);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void *pool_alloconly_realloc(pool_t pool, void *mem,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void block_alloc(struct alloconly_pool *pool, size_t size);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenpool_t pool_alloconly_create(const char *name, size_t size)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen apool = calloc(SIZEOF_ALLOCONLYPOOL + len, 1);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen apool = GC_malloc(SIZEOF_ALLOCONLYPOOL + len);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_panic("pool_alloconly_create(): Out of memory");
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void pool_alloconly_destroy(struct alloconly_pool *apool)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* destroy all but the last block */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* destroy the last block */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen memset(apool->block, 0xde, SIZEOF_POOLBLOCK + apool->block->size);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic const char *pool_alloconly_get_name(pool_t pool)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct alloconly_pool *apool = (struct alloconly_pool *) pool;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct alloconly_pool *apool = (struct alloconly_pool *) pool;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct alloconly_pool *apool = (struct alloconly_pool *) pool;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void block_alloc(struct alloconly_pool *apool, size_t size)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* each block is at least twice the size of the previous one */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (apool->block != NULL && size <= apool->block->size)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen size = nearest_power(size + SIZEOF_POOLBLOCK);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_warning("Growing pool '%s' with: %"PRIuSIZE_T,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void *pool_alloconly_malloc(pool_t pool, size_t size)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct alloconly_pool *apool = (struct alloconly_pool *) pool;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we need a new block */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void pool_alloconly_free(pool_t pool, void *mem)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct alloconly_pool *apool = (struct alloconly_pool *) pool;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we can free only the last allocation */
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen memset(mem, 0, apool->block->last_alloc_size);
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen apool->block->left += apool->block->last_alloc_size;
cbf7138b49d32fce0645dc6523fbb42cc07cb2faTimo Sirainenstatic int pool_try_grow(struct alloconly_pool *apool, void *mem, size_t size)
b9b48aaaebf6f72dfab567cda073cde8a7b26598Timo Sirainen /* see if we want to grow the memory we allocated last */
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen /* yeah, see if we can grow */
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen if (apool->block->left >= size-apool->block->last_alloc_size) {
ae9365d3de0cefae6f2a5d3e9ab79bc11c37b3d5Timo Sirainen /* just shrink the available size */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void *pool_alloconly_realloc(pool_t pool, void *mem,
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen struct alloconly_pool *apool = (struct alloconly_pool *) pool;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen unsigned char *new_mem;
1582b4d531679849bba299c17b6ec9402b7df67dTimo Sirainen i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen /* see if we can directly grow it */
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen /* slow way - allocate + copy */
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen new_mem = pool_alloconly_malloc(pool, new_size);
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen struct alloconly_pool *apool = (struct alloconly_pool *) pool;
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen /* destroy all blocks but the first, which is the largest */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memset(block, 0xde, SIZEOF_POOLBLOCK + block->size);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* clear the block */