heap_static_alloc.c 2.6 KB

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