From 50765b70dbb60cbe15ae70b13ff0b547c2135488 Mon Sep 17 00:00:00 2001 From: DocQuantum <shchurgood@gmail.com> Date: Sun, 20 Oct 2019 23:04:54 -0500 Subject: [PATCH] Implemented coalescing when adding to list --- mm.c | 134 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 52 deletions(-) diff --git a/mm.c b/mm.c index 980a784..3e3a154 100644 --- a/mm.c +++ b/mm.c @@ -111,7 +111,6 @@ static void *extend_heap(size_t words); static void place(void *bp, size_t asize); static void *find_fit(size_t asize); static void printblock(void *bp); -static int mm_coalesce(void *bp); static void mm_memcpy(void * dest, void * src); static void add_to_list(void* bp); static void remove_from_list(void* bp); @@ -169,6 +168,7 @@ void *mm_malloc(size_t size) /* Search the free list for a fit */ if ((bp = find_fit(asize)) != NULL) { place(bp, asize); + //mm_checkheap(0); return bp; } @@ -181,6 +181,8 @@ void *mm_malloc(size_t size) place(bp, asize); + //mm_checkheap(0); + return bp; } /* $end mmmalloc */ @@ -200,15 +202,11 @@ void mm_free(void *bp) return; } - // If allocated... + // If allocated, free if(!GET_ALLOC(HDRP(bp))){ - // try to coalesce... - if(mm_coalesce(bp)){ - // else free - *HDRP(bp) |= 1; - *FTRP(bp) |= 1; - add_to_list(bp); - } + *HDRP(bp) |= 1; + *FTRP(bp) |= 1; + add_to_list(bp); } else { fprintf(stderr, "mm_free(): memory not alloced or corrupted"); return; @@ -218,42 +216,6 @@ void mm_free(void *bp) /* $end mmfree */ -/** - * mm_coalesce - Coalesce the freespace around a block - * - * Given a block pointer that has been freed, find empty - * blocks near it to be combined into a large free chunk. - * - * Returns 0 on success, 1 on failure - * - */ -static int mm_coalesce(void *bp) -{ - return 1; - - size_t nextBlock = GET_ALLOC(HDRP(NEXT_BLKP(bp))); - size_t prevBlock = GET_ALLOC(HDRP(PREV_BLKP(bp))); - size_t size = GET_SIZE(HDRP(bp)); - - if(prevBlock && nextBlock){ - size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp))); - PUT(HDRP(PREV_BLKP(bp)), PACK(size, 1)); - PUT(FTRP(PREV_BLKP(bp)), PACK(size, 1)); - return 0; - } else if(prevBlock && !nextBlock){ - size += GET_SIZE(HDRP(PREV_BLKP(bp))); - PUT(HDRP(PREV_BLKP(bp)), PACK(size, 1)); - PUT(FTRP(PREV_BLKP(bp)), PACK(size, 1)); - return 0; - } else if(!prevBlock && nextBlock){ - size += GET_SIZE(HDRP(NEXT_BLKP(bp))); - PUT(HDRP(bp), PACK(size, 1)); - PUT(FTRP(bp), PACK(size, 1)); - return 0; - } - return 1; -} - /* * mm_realloc - naive implementation of mm_realloc * @@ -313,7 +275,6 @@ void *mm_realloc(void *ptr, size_t size) PUT(FTRP(ptr), PACK(size, 0)); PUT(HDRP(NEXT_BLKP(ptr)), PACK(oldSize-size, 1)); PUT(FTRP(NEXT_BLKP(ptr)), PACK(oldSize-size, 1)); - mm_coalesce(NEXT_BLKP(ptr)); } else { PUT(HDRP(ptr), PACK(oldSize, 0)); @@ -331,7 +292,6 @@ void *mm_realloc(void *ptr, size_t size) PUT(FTRP(ptr), PACK(size, 0)); PUT(HDRP(NEXT_BLKP(ptr)), PACK(nextSize-size, 1)); PUT(FTRP(NEXT_BLKP(ptr)), PACK(nextSize-size, 1)); - mm_coalesce(NEXT_BLKP(ptr)); } else { PUT(HDRP(ptr), PACK(nextSize, 0)); @@ -437,9 +397,9 @@ void mm_checkheap(int verbose) } /** - * add_to_list - Adds free block to list + * add_to_list - Adds free block to list and coalesces * - * Will try to add block in address order + * Will try to add block in address order, or combine */ static void add_to_list(void* bp){ @@ -462,6 +422,21 @@ static void add_to_list(void* bp){ // case for 1 node in list. if(free_listp == GET_NEXT_FREE(free_listp)){ + //make sure they're not next to eachother + if((char *) NEXT_BLKP(bp) == free_listp){ + size_t size = GET_SIZE(HDRP(free_listp)) + GET_SIZE(HDRP(bp)); + PUT(HDRP(bp), PACK(size, 1)); + PUT(FTRP(bp), PACK(size, 1)); + free_listp = bp; + SET_NEXT_FREE(free_listp, free_listp); + SET_PREV_FREE(free_listp, free_listp); + return; + } else if((char *) PREV_BLKP(bp) == free_listp){ + size_t size = GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(bp)); + PUT(HDRP(free_listp), PACK(size, 1)); + PUT(FTRP(free_listp), PACK(size, 1)); + return; + } // Set head next to new SET_NEXT_FREE(free_listp, bp); // Set pre prev as new @@ -482,7 +457,33 @@ static void add_to_list(void* bp){ { if((char *) bp > node){ if((char *) bp < GET_NEXT_FREE(node) || node > GET_NEXT_FREE(node)){ - //printf("Adding %p between %p -> %p\n\n", bp, node, GET_NEXT_FREE(node)); + if((char *) PREV_BLKP(bp) == node && (char *) NEXT_BLKP(bp) == GET_NEXT_FREE(node)){ + size_t size = GET_SIZE(HDRP(node)) + GET_SIZE(HDRP(bp)) + GET_SIZE(HDRP(GET_NEXT_FREE(node))); + PUT(HDRP(node), PACK(size, 1)); + PUT(FTRP(node), PACK(size, 1)); + remove_from_list(GET_NEXT_FREE(node)); + free_listp = node; + return; + } else if((char *) PREV_BLKP(bp) == node && (char *) NEXT_BLKP(bp) != GET_NEXT_FREE(node) && GET_ALLOC(HDRP(NEXT_BLKP(bp)))){ + size_t size = GET_SIZE(HDRP(node)) + GET_SIZE(HDRP(bp)); + PUT(HDRP(node), PACK(size, 1)); + PUT(FTRP(node), PACK(size, 1)); + free_listp = node; + return; + } else if((char *) PREV_BLKP(bp) != node && (char *) NEXT_BLKP(bp) == GET_NEXT_FREE(node)){ + size_t size = GET_SIZE(HDRP(bp)) + GET_SIZE(HDRP(GET_NEXT_FREE(node))); + PUT(HDRP(bp), PACK(size, 1)); + PUT(FTRP(bp), PACK(size, 1)); + char * old = GET_NEXT_FREE(node); + // set next to the next of next-next + SET_NEXT_FREE(bp, GET_NEXT_FREE(old)); + // set the prev of next-next node to bp + SET_PREV_FREE(GET_NEXT_FREE(old), bp); + SET_PREV_FREE(bp, node); + SET_NEXT_FREE(node, bp); + free_listp = node; + return; + } /* bp inserted after node */ // Set new next as current next SET_NEXT_FREE(bp, GET_NEXT_FREE(node)); @@ -500,7 +501,36 @@ static void add_to_list(void* bp){ } else if((char *) bp < node){ if((char *) bp > GET_PREV_FREE(node) || node < GET_PREV_FREE(node)){ - //printf("Adding %p between %p -> %p\n\n", bp, GET_PREV_FREE(node), node); + if((char *) NEXT_BLKP(bp) == node && (char *) PREV_BLKP(bp) == GET_PREV_FREE(node)){ + node = GET_PREV_FREE(node); + size_t size = GET_SIZE(HDRP(node)) + GET_SIZE(HDRP(bp)) + GET_SIZE(HDRP(GET_NEXT_FREE(node))); + PUT(HDRP(node), PACK(size, 1)); + PUT(FTRP(node), PACK(size, 1)); + remove_from_list(GET_NEXT_FREE(node)); + free_listp = node; + return; + } else if((char *) PREV_BLKP(bp) == GET_PREV_FREE(node) && (char *) NEXT_BLKP(bp) != node){ + node = GET_PREV_FREE(node); + size_t size = GET_SIZE(HDRP(node)) + GET_SIZE(HDRP(bp)); + PUT(HDRP(node), PACK(size, 1)); + PUT(FTRP(node), PACK(size, 1)); + free_listp = node; + return; + } else if((char *) NEXT_BLKP(bp) == node && (char *) PREV_BLKP(bp) != GET_PREV_FREE(node)){ + node = GET_PREV_FREE(node); + size_t size = GET_SIZE(HDRP(bp)) + GET_SIZE(HDRP(GET_NEXT_FREE(node))); + PUT(HDRP(bp), PACK(size, 1)); + PUT(FTRP(bp), PACK(size, 1)); + char * old = GET_NEXT_FREE(node); + // set next to the next of next-next + SET_NEXT_FREE(bp, GET_NEXT_FREE(old)); + // set the prev of next-next node to bp + SET_PREV_FREE(GET_NEXT_FREE(old), bp); + SET_PREV_FREE(bp, node); + SET_NEXT_FREE(node, bp); + free_listp = node; + return; + } /* bp inserted before node */ // Set new next to node SET_NEXT_FREE(bp, node); @@ -570,8 +600,8 @@ static void *extend_heap(size_t words) /* Initialize free block and the epilogue header */ PUT(HDRP(bp), PACK(size, 1)); /* free block header */ PUT(FTRP(bp), PACK(size, 1)); /* free block footer */ + PUT(HDRP(NEXT_BLKP(bp)), PACK(8, 0)); /* new epilogue header */ add_to_list(bp); - PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 0)); /* new epilogue header */ return bp; } /* $end mmextendheap */ -- GitLab