heap_extend_downwards.c 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "private.h"
  2. /*--------------------------------------------------------- */
  3. bool_t
  4. lub_heap_extend_downwards(lub_heap_t *this,
  5. lub_heap_block_t **ptr_block,
  6. const words_t words)
  7. {
  8. lub_heap_block_t *block = *ptr_block;
  9. lub_heap_free_block_t *prev_block = (lub_heap_free_block_t*)lub_heap_block_getprevious(block);
  10. bool_t result = BOOL_FALSE;
  11. if(NULL != prev_block)
  12. {
  13. /* Do we have a free block below us? */
  14. if(1 == prev_block->tag.free)
  15. {
  16. int segment;
  17. void *tmp;
  18. /* work out how many extra words we need */
  19. words_t delta = words - block->alloc.tag.words;
  20. /* remove the block from the tree */
  21. lub_bintree_remove(&this->free_tree,prev_block);
  22. /* remember the segment status */
  23. segment = prev_block->tag.segment;
  24. /* try and slice off a chunk of memory */
  25. tmp = lub_heap_slice_from_top(this,&prev_block,&delta,BOOL_FALSE);
  26. if(NULL != prev_block)
  27. {
  28. /* put the modified free block back into the tree */
  29. lub_bintree_insert(&this->free_tree,prev_block);
  30. /* there is still a block below us */
  31. segment = 0;
  32. }
  33. if(NULL != tmp)
  34. {
  35. /* we managed to extend downwards */
  36. lub_heap_tag_t *tail = 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. {
  45. *dst++ = *src++;
  46. }
  47. /* taint the extra memory */
  48. lub_heap_taint_memory(((char*)tail) - (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. /*--------------------------------------------------------- */