heap_slice_from_bottom.c 2.1 KB

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