heap_slice_from_top.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <assert.h>
  2. #include "private.h"
  3. /*--------------------------------------------------------- */
  4. void *lub_heap_slice_from_top(lub_heap_t * this,
  5. lub_heap_free_block_t ** ptr_block,
  6. words_t * words, bool_t seg_end)
  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. lub_heap_tag_t *tail;
  16. /* Is there sufficient memory to perform the task? */
  17. if (new_words > (sizeof(lub_heap_free_block_t) >> 2)) {
  18. /* update the free block */
  19. block->tag.words -= *words;
  20. /* get the new tail tag */
  21. tail =
  22. lub_heap_block__get_tail((lub_heap_block_t *)
  23. block);
  24. /* set up the tag */
  25. tail->segment = seg_end;
  26. tail->free = 1;
  27. tail->words = block->tag.words;
  28. /* update the stats */
  29. this->stats.free_bytes -= (*words << 2);
  30. result = &tail[1];
  31. } else {
  32. /*
  33. * there is only just enough space for the request
  34. * so we also throw in the memory used for the tags
  35. */
  36. --this->stats.free_blocks;
  37. this->stats.free_bytes -= (block->tag.words << 2);
  38. this->stats.free_bytes +=
  39. sizeof(lub_heap_alloc_block_t);
  40. this->stats.free_overhead -=
  41. sizeof(lub_heap_alloc_block_t);
  42. /* update the client's word count */
  43. *words = block->tag.words;
  44. /* there is no free block left!!! */
  45. result = block;
  46. *ptr_block = NULL;
  47. }
  48. if (NULL != result) {
  49. /* taint the memory */
  50. lub_heap_taint_memory(result, LUB_HEAP_TAINT_ALLOC,
  51. (*words << 2));
  52. }
  53. }
  54. return result;
  55. }
  56. /*--------------------------------------------------------- */