heap_extend_downwards.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "private.h"
  2. /*--------------------------------------------------------- */
  3. bool_t
  4. lub_heap_extend_downwards(lub_heap_t * this,
  5. lub_heap_block_t ** ptr_block, const words_t words)
  6. {
  7. lub_heap_block_t *block = *ptr_block;
  8. lub_heap_free_block_t *prev_block =
  9. (lub_heap_free_block_t *) lub_heap_block_getprevious(block);
  10. bool_t result = BOOL_FALSE;
  11. if (NULL != prev_block) {
  12. /* Do we have a free block below us? */
  13. if (1 == prev_block->tag.free) {
  14. int segment;
  15. void *tmp;
  16. /* work out how many extra words we need */
  17. words_t delta = words - block->alloc.tag.words;
  18. /* remove the block from the tree */
  19. lub_bintree_remove(&this->free_tree, prev_block);
  20. /* remember the segment status */
  21. segment = prev_block->tag.segment;
  22. /* try and slice off a chunk of memory */
  23. tmp =
  24. lub_heap_slice_from_top(this, &prev_block, &delta,
  25. BOOL_FALSE);
  26. if (NULL != prev_block) {
  27. /* put the modified free block back into the tree */
  28. lub_bintree_insert(&this->free_tree,
  29. prev_block);
  30. /* there is still a block below us */
  31. segment = 0;
  32. }
  33. if (NULL != tmp) {
  34. /* we managed to extend downwards */
  35. lub_heap_tag_t *tail =
  36. lub_heap_block__get_tail(block);
  37. lub_heap_block_t *new_block = tmp;
  38. /* get ready to copy the data down accounts for the header */
  39. words_t old_words = tail->words;
  40. const unsigned int *src = (unsigned int *)block;
  41. unsigned int *dst = (unsigned int *)new_block;
  42. /* copy the old data to the new location */
  43. while (old_words--) {
  44. *dst++ = *src++;
  45. }
  46. /* taint the extra memory */
  47. lub_heap_taint_memory(((char *)tail) -
  48. (delta << 2),
  49. LUB_HEAP_TAINT_ALLOC,
  50. (delta << 2));
  51. /* fill out the new block details */
  52. tail->words += delta;
  53. this->stats.alloc_bytes += (delta << 2);
  54. this->stats.alloc_total_bytes += (delta << 2);
  55. new_block->alloc.tag.segment = segment;
  56. new_block->alloc.tag.free = 0;
  57. new_block->alloc.tag.words = tail->words;
  58. /* update the clients pointer */
  59. *ptr_block = new_block;
  60. result = BOOL_TRUE;
  61. }
  62. }
  63. }
  64. return result;
  65. }
  66. /*--------------------------------------------------------- */