heap_static_alloc.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "cache.h"
  2. /*--------------------------------------------------------- */
  3. size_t
  4. lub_heap__get_block_overhead(lub_heap_t *this,
  5. const void *block)
  6. {
  7. size_t overhead;
  8. lub_heap_cache_bucket_t *bucket = 0;
  9. if(this->cache)
  10. {
  11. bucket = lub_heap_cache_find_bucket_from_address(this->cache,block);
  12. }
  13. if(bucket)
  14. {
  15. overhead = lub_heap_cache_bucket__get_block_overhead(bucket,block);
  16. }
  17. else
  18. {
  19. overhead = sizeof(lub_heap_alloc_block_t);
  20. }
  21. return overhead;
  22. }
  23. /*--------------------------------------------------------- */
  24. size_t
  25. lub_heap__get_block_size(lub_heap_t *this,
  26. const void *block)
  27. {
  28. size_t bytes = 0;
  29. lub_heap_cache_bucket_t *bucket = 0;
  30. if(this->cache)
  31. {
  32. bucket = lub_heap_cache_find_bucket_from_address(this->cache,block);
  33. }
  34. if(bucket)
  35. {
  36. bytes = lub_heap_cache_bucket__get_block_size(bucket,block);
  37. }
  38. else
  39. {
  40. const lub_heap_tag_t *header = block;
  41. --header;
  42. bytes = (header->words << 2);
  43. bytes -= sizeof(lub_heap_alloc_block_t);
  44. }
  45. return bytes;
  46. }
  47. /*--------------------------------------------------------- */
  48. void *
  49. lub_heap_static_alloc(lub_heap_t *this,
  50. size_t requested_size)
  51. {
  52. void *result = NULL;
  53. lub_heap_free_block_t *free_block;
  54. /* round up to native alignment */
  55. words_t words;
  56. lub_heap_key_t key;
  57. size_t size = requested_size;
  58. size = (size + (LUB_HEAP_ALIGN_NATIVE-1))/LUB_HEAP_ALIGN_NATIVE;
  59. size *= LUB_HEAP_ALIGN_NATIVE;
  60. words = (size >> 2);
  61. /* initialise the search key */
  62. key.words = words;
  63. key.block = 0;
  64. /* search for the start of a segment which is large enough for the request */
  65. while( (free_block = lub_bintree_findnext(&this->free_tree,&key)) )
  66. {
  67. lub_heap_tag_t *tail = lub_heap_block__get_tail((lub_heap_block_t*)free_block);
  68. /* is this free block at the start of a segment? */
  69. if(1 == tail->segment)
  70. {
  71. /* yes this is the end of a segment */
  72. break;
  73. }
  74. /* update the search key */
  75. lub_heap_block_getkey(free_block,(lub_bintree_key_t*)&key);
  76. }
  77. if(NULL != free_block)
  78. {
  79. /* remove this block from the free tree */
  80. lub_bintree_remove(&this->free_tree,free_block);
  81. /*
  82. * get some memory from the bottom of this free block
  83. */
  84. result = lub_heap_slice_from_top(this,
  85. &free_block,
  86. &words,
  87. BOOL_TRUE);
  88. if(NULL != free_block)
  89. {
  90. /* put the free block back into the tree */
  91. lub_bintree_insert(&this->free_tree,free_block);
  92. }
  93. if(NULL != result)
  94. {
  95. size_t allocated_size = (words << 2);
  96. /* update the stats */
  97. ++this->stats.static_blocks;
  98. this->stats.static_bytes += size;
  99. this->stats.static_overhead += (allocated_size - size);
  100. }
  101. }
  102. return result;
  103. }
  104. /*--------------------------------------------------------- */