/** * 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 */ static void *coalesce(void *bp) { size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(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: Neighbors both allocated */ return bp; } else if (prev_alloc && !next_alloc) { /* Case 2: Only the previous is allocated*/ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); /* If only the previous block is allocated, remove the next block */ tree_root = mm_remove(tree_root, NEXT_BLKP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size,0)); return(bp); } else if (!prev_alloc && next_alloc) { /* Case 3: Only the next is allocated */ size += GET_SIZE(HDRP(PREV_BLKP(bp))); /* If only the next block is allocated, remove the previous block */ tree_root = mm_remove(tree_root, PREV_BLKP(bp)); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); return(PREV_BLKP(bp)); } else { /* Case 4: Neither are allocated */ size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); /* If neither blocks are allocated, remove them both */ tree_root = mm_remove(tree_root, NEXT_BLKP(bp)); tree_root = mm_remove(tree_root, PREV_BLKP(bp)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); return(PREV_BLKP(bp)); } }
/* * mm_remove_children - Remove the node from the Binary Tree as long as it has two children */ void *mm_remove_children(void *root, void *bp) { void *parent_node = mm_parent(root, bp); void *replacement = mm_replace(LEFT(bp)); void *new_bp; /* Remove the replacement and store the new bp */ new_bp = mm_remove(LEFT(bp), replacement); SETLEFT(replacement, new_bp); SETRIGHT(replacement, RIGHT(bp)); if(parent_node != NULL) { if(LEFT(parent_node) == bp) SETLEFT(parent_node, replacement); else SETRIGHT(parent_node, replacement); return root; } else { return replacement; } }
/* $begin mmmalloc */ void *mm_malloc(size_t size) { size_t asize; /* adjusted block size */ size_t extendsize; /* amount to extend heap if no fit */ char *bp; /* Ignore spurious requests */ if (size <= 0) return NULL; /* Adjust block size to include overhead and alignment reqs. */ if (size <= DSIZE) asize = DSIZE + OVERHEAD; else asize = DSIZE * ((size + (OVERHEAD) + (DSIZE-1)) / DSIZE); /* Search the free list for a fit */ if ((bp = mm_ceiling(tree_root,asize)) != NULL) { tree_root = mm_remove(tree_root,bp); bp = place(bp, asize); return bp; } /* No fit found. Get more memory and place the block */ extendsize = MAX(asize,CHUNKSIZE); if ((bp = extend_heap(extendsize/WSIZE)) == NULL) return NULL; bp = place(bp, asize); return bp; }
/** * Place block of asize bytes at start of free block bp * and split if remainder would be at least minimum block size * @param - bp - pointer to a free block, not on the tree of free blocks * @param - asize - the requested size of free block */ static void place(void *bp, size_t asize){ size_t csize = GET_HSIZE(bp); if ((csize - asize) >= BLKSIZE) { SET_HDRP(bp, PACK(asize, 1)); SET_FTRP(bp, PACK(asize, 1)); mm_remove(bp); bp = NEXT_BLK(bp); SET_HDRP(bp, PACK(csize-asize, 0)); SET_FTRP(bp, PACK(csize-asize, 0)); coalesce(bp); } else { SET_HDRP(bp, PACK(csize, 1)); SET_FTRP(bp, PACK(csize, 1)); mm_remove(bp); } }
static void place(void *bp, size_t size){ size_t totalsize = GET_SIZE(HDRP(bp)); if((totalsize - size) >= OVERHEAD){ PUT(HDRP(bp), PACK(size, 1)); PUT(FTRP(bp), PACK(size, 1)); mm_remove(bp); bp = NEXT_BLKP(bp); PUT(HDRP(bp), PACK(totalsize - size, 0)); PUT(FTRP(bp), PACK(totalsize - size, 0)); coalesce(bp); } else{ PUT(HDRP(bp), PACK(totalsize, 1)); PUT(FTRP(bp), PACK(totalsize, 1)); mm_remove(bp); } }
/** * Return a block of size >= newsize * that preserves all the data from the * payload of the block bp. * @param - a pointer to an allocated block * @param - size - a new size requested * @return - pointer to a block size >= newsize */ void *mm_realloc(void *bp, size_t size){ if(size <= 0){ mm_free(bp); return NULL; }else if(bp == NULL){ bp = mm_malloc(size); return bp; } if(size > 0){ size_t currentsize = GET_HSIZE(bp); size_t newsize = ALIGN(size + OVERHEAD); /* newsize is less than currentsize just return bp */ if(newsize <= currentsize){ return bp; } /* newsize is greater than currentsize */ else { size_t next_alloc = GET_HALLOC(NEXT_BLK(bp)); size_t csize; size_t asize; /* next block is free and the size of the two blocks is greater than or equal the new size */ if(!next_alloc && ((csize = currentsize + GET_HSIZE(NEXT_BLK(bp)))) >= newsize){ mm_remove(NEXT_BLK(bp)); SET_HDRP(bp, PACK(csize, 1)); SET_FTRP(bp, PACK(csize, 1)); return bp; } /* next block is free and the block is the last block before the epilogue */ else if(!next_alloc && ((GET_HSIZE(NEXT_BLK(NEXT_BLK(bp)))) == 0)){ csize = newsize - currentsize + GET_HSIZE(NEXT_BLK(bp)); void *temp = extend_heap(csize); asize = currentsize + GET_HSIZE(temp); SET_HDRP(bp, PACK(asize, 1)); SET_FTRP(bp, PACK(asize, 1)); return bp; } /* if bp is the last block before epilogue */ else if(GET_HSIZE(NEXT_BLK(bp)) == 0){ csize = newsize - currentsize; void *temp = extend_heap(csize); asize = currentsize + GET_HSIZE(temp); SET_HDRP(bp, PACK(asize, 1)); SET_FTRP(bp, PACK(asize, 1)); return bp; } /* last ditch attemp try to extend heap for additional size */ else { void *newbp = mm_malloc(newsize); place(newbp, newsize); memcpy(newbp, bp, newsize); mm_free(bp); return newbp; } } /* return NULL */ }else{ return NULL; } }
/* 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; }