/** * 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; }
/* Puts block of size asize at loc bp */ void place(void *bp, size_t asize){ size_t csize = GET_SIZE(HDRP(bp)); size_t leftover = csize - asize; delete_node(bp); if ((leftover) >= 2 * DSIZE) { //make new block PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); //remove free from list //removeFromFree(bp); //create new block and add it to the list //bp = NEXT_BLK(bp); //PUT(HDRP(bp), PACK(csize-asize, 0)); //PUT(FTRP(bp), PACK(csize-asize, 0)); //coalesce(bp); insert_node(NEXT_BLK(bp), leftover); } else { PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); //removeFromFree(bp); } return; }
/** * 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; } }
/** * 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); } }
/** * extend_heap - Extend heap with free block and return its block pointer * Allocates a new free block of size which is a multiple of 8 immediately after * the last block. Merges this new block with the last block if that block is free. * Rewrites an epilog block after the new block. * @param - words - extend head by size of words(4) * @return - bp - pointer to the new free block (not yet in the tree of free blocks) */ static void *extend_heap(size_t words) { char *bp; size_t size; /* Allocate an even number of words to maintain alignment */ size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; if (size < BLKSIZE){ size = BLKSIZE; } /* call for more memory space */ if ((int)(bp = mem_sbrk(size)) == -1){ return NULL; } /* Initialize free block header/footer and the epilogue header */ SET_HDRP(bp, PACK(size, 0)); /* free block header */ SET_FTRP(bp, PACK(size, 0)); /* free block footer */ SET_HDRP(NEXT_BLK(bp), PACK(0, 1)); /* new epilogue header */ /* coalesce bp with next and previous blocks */ return coalesce(bp); }
static void *extend_heap(size_t words) { char *bp; size_t size; /* Allocate an even number of words to maintain alignment */ size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; if ((long)(bp = mem_sbrk(size)) == -1){ return NULL; } /* Initialize free block header/footer and the epilogue header */ PUT(HDRP(bp), PACK(size, 0)); /* free block header */ PUT(FTRP(bp), PACK(size, 0)); /* free block footer */ PUT(HDRP(NEXT_BLK(bp)), PACK(0, 1)); /* new epilogue header */ /* Coalesce if the previous block was free */ /*insert block into appropriate list*/ insert_node(bp, size); return coalesce(bp); }
/* * coalesce - Boundary tag coalescing. Return ptr to coalesced block */ static void *coalesce(void *bp){ size_t NEXT_ALLOC = GET_ALLOC( HDRP(NEXT_BLK(bp)) ); size_t PREV_ALLOC = GET_ALLOC( HDRP(PREV_BLK(bp)) ); //size_t PREV_ALLOC = GET_ALLOC( FTRP(PREV_BLK(bp)) ) || PREV_BLK(bp) == bp; size_t size = GET_SIZE(HDRP(bp)); /*return if the previous and next blocks are both allocated */ if (PREV_ALLOC && NEXT_ALLOC) { return bp; } /*Remove old block from list*/ delete_node(bp); if (PREV_ALLOC && !NEXT_ALLOC) { delete_node(NEXT_BLK(bp)); size += GET_SIZE(HDRP(NEXT_BLK(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } else if (!PREV_ALLOC && NEXT_ALLOC) { delete_node(PREV_BLK(bp)); size += GET_SIZE(HDRP(PREV_BLK(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLK(bp)), PACK(size, 0)); bp = PREV(bp); } else { delete_node(PREV_BLK(bp)); delete_node(NEXT_BLK(bp)); size += GET_SIZE(HDRP(PREV_BLK(bp))) + GET_SIZE(HDRP(NEXT_BLK(bp))); PUT(HDRP(PREV_BLK(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLK(bp)), PACK(size, 0)); bp = PREV_BLK(bp); } insert_node(bp, size); return bp; }