diff options
author | truelight <truelight@openttd.org> | 2005-02-01 18:30:11 +0000 |
---|---|---|
committer | truelight <truelight@openttd.org> | 2005-02-01 18:30:11 +0000 |
commit | 567224e94089f26e0c64aa37c7c40937285fb8fa (patch) | |
tree | 35f04fe054bc30ef92e351bf9b71b916a1236a55 /pool.c | |
parent | 45beed1c99fb4cd8fb3cb1c893a1ea56a7284759 (diff) | |
download | openttd-567224e94089f26e0c64aa37c7c40937285fb8fa.tar.xz |
(svn r1763) -Add: pool.c / pool.h: generalized routines for dynamic arrays (MemoryPools)
Diffstat (limited to 'pool.c')
-rw-r--r-- | pool.c | 79 |
1 files changed, 79 insertions, 0 deletions
@@ -0,0 +1,79 @@ +#include "stdafx.h" +#include "ttd.h" +#include "pool.h" + +/** + * Clean a pool in a safe way (does free all blocks) + */ +void CleanPool(MemoryPool *pool) +{ + uint i; + + DEBUG(misc, 4)("[Pool] (%s) Cleaing pool..", pool->name); + + /* Free all blocks */ + for (i = 0; i < pool->current_blocks; i++) + free(pool->blocks[i]); + + /* Free the block itself */ + free(pool->blocks); + + /* Clear up some critical data */ + pool->total_items = 0; + pool->current_blocks = 0; + pool->blocks = NULL; +} + +/** + * This function tries to increase the size of array by adding + * 1 block too it + * + * @return Returns false if the pool could not be increased + */ +bool AddBlockToPool(MemoryPool *pool) +{ + /* Is the pool at his max? */ + if (pool->max_blocks == pool->current_blocks) + return false; + + pool->total_items = (pool->current_blocks + 1) * (1 << pool->block_size_bits); + + DEBUG(misc, 4)("[Pool] (%s) Increasing size of pool to %d items (%d bytes)", pool->name, pool->total_items, pool->total_items * pool->item_size); + + /* Increase the poolsize */ + pool->blocks = realloc(pool->blocks, sizeof(pool->blocks[0]) * (pool->current_blocks + 1)); + if (pool->blocks == NULL) + error("Pool: (%s) could not allocate memory for blocks", pool->name); + + /* Allocate memory to the new block item */ + pool->blocks[pool->current_blocks] = malloc(pool->item_size * (1 << pool->block_size_bits)); + if (pool->blocks[pool->current_blocks] == NULL) + error("Pool: (%s) could not allocate memory for blocks", pool->name); + + /* Clean the content of the new block */ + memset(pool->blocks[pool->current_blocks], 0, pool->item_size * (1 << pool->block_size_bits)); + + /* Call a custom function if defined (e.g. to fill indexes) */ + if (pool->new_block_proc != NULL) + pool->new_block_proc(pool->current_blocks * (1 << pool->block_size_bits)); + + /* We have a new block */ + pool->current_blocks++; + + return true; +} + +/** + * Adds blocks to the pool if needed (and possible) till index fits inside the pool + * + * @return Returns false if adding failed + */ +bool AddBlockIfNeeded(MemoryPool *pool, uint index) +{ + while (index >= pool->total_items) { + if (!AddBlockToPool(pool)) + return false; + } + + return true; +} |