/* Allocates one element from the pool specified. */ void * pool_alloc (alloc_pool pool) { alloc_pool_list header; char *block; #ifdef GATHER_STATISTICS struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name); desc->allocated+=pool->elt_size; #endif gcc_assert (pool); /* If there are no more free elements, make some more!. */ if (!pool->free_list) { size_t i; alloc_pool_list block_header; /* Make the block. */ block = XNEWVEC (char, pool->block_size); block_header = (alloc_pool_list) block; block += align_eight (sizeof (struct alloc_pool_list_def)); #ifdef GATHER_STATISTICS desc->current += pool->block_size; if (desc->peak < desc->current) desc->peak = desc->current; #endif /* Throw it on the block list. */ block_header->next = pool->block_list; pool->block_list = block_header; /* Now put the actual block pieces onto the free list. */ for (i = 0; i < pool->elts_per_block; i++, block += pool->elt_size) { #ifdef ENABLE_CHECKING /* Mark the element to be free. */ ((allocation_object *) block)->id = 0; #endif header = (alloc_pool_list) USER_PTR_FROM_ALLOCATION_OBJECT_PTR (block); header->next = pool->free_list; pool->free_list = header; } /* Also update the number of elements we have free/allocated, and increment the allocated block count. */ pool->elts_allocated += pool->elts_per_block; pool->elts_free += pool->elts_per_block; pool->blocks_allocated += 1; }
/* Make the block available for allocation. */ pool->virgin_free_list = block; pool->virgin_elts_remaining = pool->elts_per_block; /* Also update the number of elements we have free/allocated, and increment the allocated block count. */ pool->elts_allocated += pool->elts_per_block; pool->elts_free += pool->elts_per_block; pool->blocks_allocated += 1; } /* We now know that we can take the first elt off the virgin list and put it on the returned list. */ block = pool->virgin_free_list; header = (alloc_pool_list) USER_PTR_FROM_ALLOCATION_OBJECT_PTR (block); header->next = NULL; #ifdef ENABLE_CHECKING /* Mark the element to be free. */ ((allocation_object *) block)->id = 0; #endif VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (header,size)); pool->returned_free_list = header; pool->virgin_free_list += pool->elt_size; pool->virgin_elts_remaining--; } /* Pull the first free element from the free list, and return it. */ header = pool->returned_free_list; VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (header, sizeof (*header)));