#include "cache.h" /*--------------------------------------------------------- */ size_t lub_heap__get_block_overhead(lub_heap_t * this, const void *block) { size_t overhead; lub_heap_cache_bucket_t *bucket = 0; if (this->cache) { bucket = lub_heap_cache_find_bucket_from_address(this->cache, block); } if (bucket) { overhead = lub_heap_cache_bucket__get_block_overhead(bucket, block); } else { overhead = sizeof(lub_heap_alloc_block_t); } return overhead; } /*--------------------------------------------------------- */ size_t lub_heap__get_block_size(lub_heap_t * this, const void *block) { size_t bytes = 0; lub_heap_cache_bucket_t *bucket = 0; if (this->cache) { bucket = lub_heap_cache_find_bucket_from_address(this->cache, block); } if (bucket) { bytes = lub_heap_cache_bucket__get_block_size(bucket, block); } else { const lub_heap_tag_t *header = block; --header; bytes = (header->words << 2); bytes -= sizeof(lub_heap_alloc_block_t); } return bytes; } /*--------------------------------------------------------- */ void *lub_heap_static_alloc(lub_heap_t * this, size_t requested_size) { void *result = NULL; lub_heap_free_block_t *free_block; /* round up to native alignment */ words_t words; lub_heap_key_t key; size_t size = requested_size; size = (size + (LUB_HEAP_ALIGN_NATIVE - 1)) / LUB_HEAP_ALIGN_NATIVE; size *= LUB_HEAP_ALIGN_NATIVE; words = (size >> 2); /* initialise the search key */ key.words = words; key.block = 0; /* search for the start of a segment which is large enough for the request */ while ((free_block = lub_bintree_findnext(&this->free_tree, &key))) { lub_heap_tag_t *tail = lub_heap_block__get_tail((lub_heap_block_t *) free_block); /* is this free block at the start of a segment? */ if (1 == tail->segment) { /* yes this is the end of a segment */ break; } /* update the search key */ lub_heap_block_getkey(free_block, (lub_bintree_key_t *) & key); } if (NULL != free_block) { /* remove this block from the free tree */ lub_bintree_remove(&this->free_tree, free_block); /* * get some memory from the bottom of this free block */ result = lub_heap_slice_from_top(this, &free_block, &words, BOOL_TRUE); if (NULL != free_block) { /* put the free block back into the tree */ lub_bintree_insert(&this->free_tree, free_block); } if (NULL != result) { size_t allocated_size = (words << 2); /* update the stats */ ++this->stats.static_blocks; this->stats.static_bytes += size; this->stats.static_overhead += (allocated_size - size); } } return result; } /*--------------------------------------------------------- */