/* * mm_insert - Insert a free block into the Binary Tree and return bp */ void *mm_insert(void *root, void* bp) { /* Determine if the tree is empty and initiate all nodes to NULL */ if(root == NULL) { SETLEFT(bp, NULL); SETRIGHT(bp, NULL); return bp; } else if(GETSIZE(bp) <= GETSIZE(root)) { SETLEFT(root, mm_insert(LEFT(root),bp)); return root; } else if(GETSIZE(bp) > GETSIZE(root)) { SETRIGHT(root, mm_insert(RIGHT(root),bp)); return root; } /* If there's an error, return -1 */ return -1; }
/* $begin mminit */ int mm_init(void) { void *bp; tree_root = NULL; /* Create the initial empty heap */ if ((heap_listp = mem_sbrk(PROLOGSIZE)) == NULL) return -1; PUT(heap_listp, 0); /* alignment padding */ PUT(heap_listp+WSIZE, PACK(OVERHEAD, 1)); /* prologue header */ PUT(heap_listp+DSIZE, PACK(OVERHEAD, 1)); /* prologue footer */ PUT(heap_listp+WSIZE+DSIZE, PACK(0, 1)); /* epilogue header */ heap_listp += DSIZE; /* Extend the empty heap with a free block of CHUNKSIZE bytes */ bp = extend_heap(CHUNKSIZE/WSIZE); if (bp == NULL) return -1; tree_root = mm_insert(tree_root, bp); return 0; }
/** * coalesce - boundary tag coalescing. Return ptr to coalesced block * Removes adjacent blocks from the free list if either one or both are free. * Merges block bp with these free adjacent blocks and inserts it onto list. * @return - bp - pointer to the merged block */ static void *coalesce(void *bp){ size_t prev_alloc; prev_alloc = GET_FALLOC(PREV_BLK(bp)) || PREV_BLK(bp) == bp; size_t next_alloc = GET_HALLOC(NEXT_BLK(bp)); size_t size = GET_HSIZE(bp); /* Case 1 next block is free */ if (prev_alloc && !next_alloc) { size += GET_HSIZE(NEXT_BLK(bp)); mm_remove(NEXT_BLK(bp)); SET_HDRP(bp, PACK(size, 0)); SET_FTRP(bp, PACK(size, 0)); }/* Case 2 prev block is free */ else if (!prev_alloc && next_alloc) { size += GET_HSIZE(PREV_BLK(bp)); bp = PREV_BLK(bp); mm_remove(bp); SET_HDRP(bp, PACK(size, 0)); SET_FTRP(bp, PACK(size, 0)); }/* Case 3 both blocks are free */ else if (!prev_alloc && !next_alloc) { size += GET_HSIZE(PREV_BLK(bp)) + GET_HSIZE(NEXT_BLK(bp)); mm_remove(PREV_BLK(bp)); mm_remove(NEXT_BLK(bp)); bp = PREV_BLK(bp); SET_HDRP(bp, PACK(size, 0)); SET_FTRP(bp, PACK(size, 0)); }/* lastly insert bp into free list and return bp */ mm_insert(bp); return bp; }
static void *coalesce(void *bp){ size_t previous_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))) || PREV_BLKP(bp) == bp; size_t next__alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); if(previous_alloc && !next__alloc){ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); mm_remove(NEXT_BLKP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } else if(!previous_alloc && next__alloc){ size += GET_SIZE(HDRP(PREV_BLKP(bp))); bp = PREV_BLKP(bp); mm_remove(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } else if(!previous_alloc && !next__alloc){ size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp))); mm_remove(PREV_BLKP(bp)); mm_remove(NEXT_BLKP(bp)); bp = PREV_BLKP(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } mm_insert(bp); return bp; }
/* $begin mmfree */ void mm_free(void *bp) { size_t size = GET_SIZE(HDRP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); tree_root = mm_insert(tree_root,coalesce(bp)); }
/* $begin mmplace-proto */ static void *place(void *bp, size_t asize) /* $end mmplace-proto */ { size_t csize = GET_SIZE(HDRP(bp)); size_t split_size = (csize - asize); if (split_size >= (DSIZE + OVERHEAD)) { size_t avg = (GETSIZE(NEXT_BLKP(bp)) + GETSIZE(PREV_BLKP(bp)))/2; void* large; void* small; int split_side; /* Which side should we split on? Let split_side = 0 or 1 0 = Let's split the end 1 = Let's split the front */ if(GETSIZE(NEXT_BLKP(bp)) > GETSIZE(PREV_BLKP(bp))) { large = NEXT_BLKP(bp); small = PREV_BLKP(bp); } else { large = PREV_BLKP(bp); small = NEXT_BLKP(bp); } if(asize > avg) { if(PREV_BLKP(bp) == large) split_side = 0; else split_side = 1; } else { if(PREV_BLKP(bp) == large) split_side = 1; else split_side = 0; } if(split_side != 1) { PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); void* split = NEXT_BLKP(bp); PUT(HDRP(split), PACK(csize-asize, 0)); PUT(FTRP(split), PACK(csize-asize, 0)); tree_root = mm_insert(tree_root,split); return bp; } else { PUT(HDRP(bp), PACK(split_size,0)); PUT(FTRP(bp), PACK(split_size,0)); void *blk = NEXT_BLKP(bp); PUT(HDRP(blk), PACK(asize, 1)); PUT(FTRP(blk), PACK(asize, 1)); tree_root = mm_insert(tree_root,bp); return blk; } } else { PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); return bp; } }
/* Not implemented. For consistency with 15-213 malloc driver */ void *mm_realloc(void *ptr, size_t size) { void *bp; size_t asize = ADJUSTSIZE(size); if(!GETSIZE(NEXT_BLKP(ptr))) { size_t extendsize = MAX(asize, CHUNKSIZE); bp = extend_heap(extendsize/4); size_t nsize = extendsize + GETSIZE(ptr) - asize; PUT(HDRP(ptr), PACK(asize,1)); PUT(FTRP(ptr), PACK(asize,1)); void *blk = NEXT_BLKP(ptr); PUT(HDRP(blk), PACK(nsize,0)); PUT(FTRP(blk), PACK(nsize, 0)); tree_root = mm_insert(tree_root, blk); return ptr; } if(!(GET_ALLOC(HDRP(NEXT_BLKP(ptr))))) { bp = NEXT_BLKP(ptr); size_t total = GETSIZE(ptr) + GETSIZE(bp); if(total >= asize) { size_t nsize = total - asize; tree_root = mm_remove(tree_root,bp); if(nsize < 16) { PUT(HDRP(ptr), PACK(total, 1)); PUT(FTRP(ptr), PACK(total, 1)); return ptr; } else { PUT(HDRP(ptr), PACK(asize, 1)); PUT(FTRP(ptr), PACK(asize, 1)); void *blk = NEXT_BLKP(ptr); PUT(HDRP(blk), PACK(nsize,0)); PUT(FTRP(blk), PACK(nsize,0)); tree_root = mm_insert(tree_root, blk); return ptr; } } else if(!GETSIZE(NEXT_BLKP(bp))) { size_t extendsize = MAX(asize, CHUNKSIZE); extend_heap(extendsize/4); size_t nsize = extendsize + total - asize; PUT(HDRP(ptr), PACK(asize,1)); PUT(FTRP(ptr), PACK(asize,1)); void *blk = NEXT_BLKP(ptr); PUT(HDRP(blk), PACK(nsize,0)); PUT(FTRP(blk), PACK(nsize,0)); tree_root = mm_insert(tree_root, blk); return ptr; } } bp = mm_malloc(size); memcpy(bp, ptr, (GETSIZE(ptr) - DSIZE)); mm_free(ptr); return bp; }