free_heap_block *free_list::find_free_block(cell size)
{
/* Check small free lists */
- if(size / block_granularity < free_list_count)
+ for(cell i = size / block_granularity; i < free_list_count; i++)
{
- std::vector<free_heap_block *> &blocks = small_blocks[size / block_granularity];
- if(blocks.size() == 0)
+ std::vector<free_heap_block *> &blocks = small_blocks[i];
+ if(blocks.size())
{
- /* Round up to a multiple of 'size' */
- cell large_block_size = ((allocation_page_size + size - 1) / size) * size;
-
- /* Allocate a block this big */
- free_heap_block *large_block = find_free_block(large_block_size);
- if(!large_block) return NULL;
-
- large_block = split_free_block(large_block,large_block_size);
-
- /* Split it up into pieces and add each piece back to the free list */
- for(cell offset = 0; offset < large_block_size; offset += size)
- {
- free_heap_block *small_block = large_block;
- large_block = (free_heap_block *)((cell)large_block + size);
- small_block->make_free(size);
- add_to_free_list(small_block);
- }
+ free_heap_block *block = blocks.back();
+ blocks.pop_back();
+
+ free_block_count--;
+ free_space -= block->size();
+
+ return block;
}
+ }
+
+ /* Check large free lists */
+ free_heap_block key;
+ key.make_free(size);
+ large_block_set::iterator iter = large_blocks.lower_bound(&key);
+ large_block_set::iterator end = large_blocks.end();
- free_heap_block *block = blocks.back();
- blocks.pop_back();
+ if(iter != end)
+ {
+ free_heap_block *block = *iter;
+ large_blocks.erase(iter);
free_block_count--;
free_space -= block->size();
return block;
}
- else
- {
- /* Check large free list */
- free_heap_block key;
- key.make_free(size);
- large_block_set::iterator iter = large_blocks.lower_bound(&key);
- large_block_set::iterator end = large_blocks.end();
- if(iter != end)
- {
- free_heap_block *block = *iter;
- large_blocks.erase(iter);
-
- free_block_count--;
- free_space -= block->size();
-
- return block;
- }
-
- return NULL;
- }
+ return NULL;
}
free_heap_block *free_list::split_free_block(free_heap_block *block, cell size)
bool free_list::can_allot_p(cell size)
{
- return largest_free_block() >= std::max(size,allocation_page_size);
+ /* Check small free lists */
+ for(cell i = size / block_granularity; i < free_list_count; i++)
+ {
+ if(small_blocks[i].size()) return true;
+ }
+
+ /* Check large free lists */
+ large_block_set::const_iterator iter = large_blocks.begin();
+ large_block_set::const_iterator end = large_blocks.end();
+
+ for(; iter != end; iter++)
+ {
+ if((*iter)->size() >= size) return true;
+ }
+
+ return false;
}
cell free_list::largest_free_block()