/* * mm_free - Free a block by adding it to the appropriate list and coalescing * it. */ void mm_free(void *ptr) { size_t size = GET_SIZE(HEAD(ptr)); /* Size of block */ /* Unset the reallocation tag on the next block */ UNSET_TAG(HEAD(NEXT(ptr))); /* Adjust the allocation status in boundary tags */ PUT(HEAD(ptr), PACK(size, 0)); PUT(FOOT(ptr), PACK(size, 0)); /* Insert new block into appropriate list */ insert_node(ptr, size); /* Coalesce free block */ coalesce(ptr); /* // Check heap for consistency line_count++; if (CHECK && CHECK_FREE) { mm_check('f', ptr, size); } */ return; }
/* * coalesce - Implements boundary-tag coalescing to merge the input block * with any adjacent free blocks in constant time. */ static void *coalesce(void *bp) { size_t prev_alloc = GET_PREV_ALLOC(HDRP(bp)); size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); if (prev_alloc && next_alloc) { /* Case 1 */ UNSET_TAG(HDRP(NEXT_BLKP(bp))); add_to_list(find_list(GET_SIZE(HDRP(bp))), bp); return bp; } else if (prev_alloc && !next_alloc) { /* Case 2 */ remove_from_list(find_list(GET_SIZE(HDRP(NEXT_BLKP(bp)))), NEXT_BLKP(bp)); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size,0)); SET_TAG(HDRP(bp)); SET_TAG(FTRP(bp)); } else if (!prev_alloc && next_alloc) { /* Case 3 */ remove_from_list(find_list(GET_SIZE(HDRP(PREV_BLKP(bp)))), PREV_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))); SET_SIZE(FTRP(bp), size); SET_SIZE(HDRP(PREV_BLKP(bp)), size); bp = PREV_BLKP(bp); } else { /* Case 4 */ remove_from_list(find_list(GET_SIZE(HDRP(PREV_BLKP(bp)))), PREV_BLKP(bp)); remove_from_list(find_list(GET_SIZE(HDRP(NEXT_BLKP(bp)))), NEXT_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); SET_SIZE(HDRP(PREV_BLKP(bp)), size); SET_SIZE(FTRP(NEXT_BLKP(bp)), size); bp = PREV_BLKP(bp); } UNSET_TAG(HDRP(NEXT_BLKP(bp))); add_to_list(find_list(GET_SIZE(HDRP(bp))), bp); return bp; }