heap_slice_from_bottom.c 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include <assert.h>
  2. #include "private.h"
  3. /*--------------------------------------------------------- */
  4. void *
  5. lub_heap_slice_from_bottom(lub_heap_t *this,
  6. lub_heap_free_block_t **ptr_block,
  7. words_t *words,
  8. bool_t seg_start)
  9. {
  10. void *result = NULL;
  11. lub_heap_free_block_t *block = *ptr_block;
  12. /* check this is a free block */
  13. assert(1 == block->tag.free);
  14. if(BOOL_TRUE == lub_heap_block_check((lub_heap_block_t*)block)
  15. && (*words <= block->tag.words))
  16. {
  17. words_t new_words = (block->tag.words - *words);
  18. /* get the tag at the end of the current free block */
  19. lub_heap_tag_t *tail = lub_heap_block__get_tail((lub_heap_block_t*)block);
  20. /*
  21. * Is there sufficient memory to perform the task?
  22. * we must leave enough space for the free block to work
  23. */
  24. if(new_words > (sizeof(lub_heap_free_block_t) >> 2))
  25. {
  26. lub_heap_free_block_t *new_block;
  27. /* adjust the free block size */
  28. tail->words -= *words;
  29. /* create a new free block header */
  30. new_block = (lub_heap_free_block_t *)(&block->tag + *words);
  31. new_block->tag.segment = seg_start;
  32. new_block->tag.free = 1; /* this is a free block */
  33. new_block->tag.words = tail->words;
  34. /* update the stats */
  35. this->stats.free_bytes -= (*words << 2);
  36. /* set up the tree node */
  37. lub_bintree_node_init(&new_block->bt_node);
  38. result = block;
  39. *ptr_block = new_block;
  40. }
  41. else
  42. {
  43. /*
  44. * there is only just enough space for the request
  45. * so we also throw in the memory used for the tags
  46. */
  47. --this->stats.free_blocks;
  48. this->stats.free_bytes -= (block->tag.words << 2);
  49. this->stats.free_bytes += sizeof(lub_heap_alloc_block_t);
  50. this->stats.free_overhead -= sizeof(lub_heap_alloc_block_t);
  51. /* update the client's word count */
  52. *words = block->tag.words;
  53. /* there is no free block left!!! */
  54. result = block;
  55. *ptr_block = NULL;
  56. }
  57. if(NULL != result)
  58. {
  59. /* taint the memory */
  60. lub_heap_taint_memory(result,LUB_HEAP_TAINT_ALLOC,(*words << 2));
  61. }
  62. }
  63. return result;
  64. }
  65. /*--------------------------------------------------------- */