heap_append_free.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * libc/stdlib/malloc-zarg/heap_append_free.c -- append to heap free area
  3. *
  4. * Copyright (C) 2002 NEC Corporation
  5. * Copyright (C) 2002 Miles Bader <miles@gnu.org>
  6. *
  7. * This file is subject to the terms and conditions of the GNU Lesser
  8. * General Public License. See the file COPYING.LIB in the main
  9. * directory of this archive for more details.
  10. *
  11. * Written by Miles Bader <miles@gnu.org>
  12. */
  13. #include <stdlib.h>
  14. #include "heap.h"
  15. /* If the block MEM, of size SIZE, immediately follows an existing free-area
  16. in HEAP, use it to extend that free-area, and return true; otherwise return
  17. false. */
  18. int
  19. __heap_append_free (struct heap *heap, void *mem, size_t size)
  20. {
  21. int success = 0;
  22. struct heap_free_area *fa;
  23. mutex_lock (heap->lock);
  24. HEAP_DEBUG (heap, "before __heap_append_free");
  25. /* Find an adjacent free-list entry. */
  26. for (fa = heap->free_areas; fa; fa = fa->next)
  27. if (HEAP_FREE_AREA_END (fa) == mem)
  28. /* MEM follows FA, extend FA to include it. Since the descriptor for FA
  29. is located at the end, we must actually write a new descriptor. Note
  30. that we _don't_ handle the case where the extended FA can be merged
  31. with a following free area; this is because this function is
  32. generally only used in cases were we believe that usually won't
  33. happen (it doesn't cause any incorrectness, and the two blocks can be
  34. merged by __heap_free later). */
  35. {
  36. struct heap_free_area *next_fa = fa->next;
  37. struct heap_free_area *prev_fa = fa->prev;
  38. size_t fa_size = fa->size;
  39. struct heap_free_area *new_fa =
  40. (struct heap_free_area *)((char *)fa + size);
  41. /* Update surrounding free-areas to point to FA's new address. */
  42. if (prev_fa)
  43. prev_fa->next = new_fa;
  44. else
  45. heap->free_areas = new_fa;
  46. if (next_fa)
  47. next_fa->prev = new_fa;
  48. /* Fill in the moved descriptor. */
  49. new_fa->prev = prev_fa;
  50. new_fa->next = next_fa;
  51. new_fa->size = fa_size + size;
  52. success = 1;
  53. break;
  54. }
  55. HEAP_DEBUG (heap, "after __heap_append_free");
  56. mutex_unlock (heap->lock);
  57. return success;
  58. }