/********************************************************** * Covers the 4 cases discussed in the text: * - both neighbours are allocated * - the next block is available for coalescing * - the previous block is available for coalescing * - both neighbours are available for coalescing * The coalesce has four conditions based on * the neighbours around it * basically if there is a free neighbour, * we need to modify the header and footer * of the left most neightbour to coalesce the new size. * But as well, since we need to remove the coalesced free * block from the free list and re add the new larger block * onto the free list. **********************************************************/ 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 (bp == NULL) return NULL; if (prev_alloc && next_alloc) { /* Case 1 */ insertFifoFreeBlock(bp); // Insert onto free list return bp; } else if (prev_alloc && !next_alloc) { /* Case 2 */ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); delete_from_free (NEXT_BLKP(bp)); // Remove the right block from the free list PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); insertFifoFreeBlock(bp); // Insert onto free list return (bp); } else if (!prev_alloc && next_alloc) { /* Case 3 */ size += GET_SIZE(HDRP(PREV_BLKP(bp))); delete_from_free (PREV_BLKP(bp)); // Remove the left block from the free list PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); insertFifoFreeBlock(bp); // Insert onto free list return (bp); } else { /* Case 4 */ size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))) ; delete_from_free (PREV_BLKP(bp)); // Remove the left block from the free list delete_from_free (NEXT_BLKP(bp)); // Remove the right block from the free list PUT(HDRP(PREV_BLKP(bp)), PACK(size,0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size,0)); bp = PREV_BLKP(bp); insertFifoFreeBlock(bp); // Insert onto free list 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; }
/* * coalesce * Boundary tag coalescing. Return ptr to coalesced block * delete or insert entry of free list. */ static void *coalesce(void *bp) { size_t prev_alloc = IS_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 */ /* nop */ } else if (prev_alloc && !next_alloc) { /* Case 2 */ if (heap_tailp == NEXT_BLKP(bp)) { heap_tailp = bp; } delete_node(get_level(GET_SIZE(HDRP(NEXT_BLKP(bp)))), NEXT_BLKP(bp)); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK3(size, 2, 0)); PUT(FTRP(bp), PACK3(size, 2, 0)); } else if (!prev_alloc && next_alloc) { /* Case 3 */ int t = (bp == heap_tailp); delete_node(get_level(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); if (t) { heap_tailp = bp; } } else { /* Case 4 */ int t = (NEXT_BLKP(bp) == heap_tailp); delete_node(get_level(GET_SIZE(HDRP(PREV_BLKP(bp)))), PREV_BLKP(bp)); delete_node(get_level(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); if (t) { heap_tailp = bp; } } UNFLAG(HDRP(NEXT_BLKP(bp))); insert_node(get_level(GET_SIZE(HDRP(bp))), bp); return bp; }
/* * Given a block pointer try to coalesce the previous and next * blocks if they are empty */ static void *coalesce(void *bp) { size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); if (next_alloc && prev_alloc) { return bp; } else if (!prev_alloc && next_alloc) { size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } else if (prev_alloc && !next_alloc) { size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } else { size += GET_SIZE(HDRP(PREV_BLKP(bp))); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } return bp; }
//合并空闲块儿 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){ return bp; //前后都被占用 case1 } else if(prev_alloc && !next_alloc){ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } //前一个块儿空闲 else if(!prev_alloc && next_alloc){ size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } //后一个块儿空闲 else{ size += GET_SIZE(HDRP(PREV_BLKP(bp)))+GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } //前后块儿都空闲 return bp; }
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) /* Both Adjacent Blocks Are Allocated */ return bp; else if(prev_alloc && !next_alloc){ /* Next is not allocated */ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size,0)); PUT(FTRP(bp), PACK(size,0)); } else if(!prev_alloc && next_alloc){ /* Prev is not allocated */ size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size,0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } else{ /* Both are not allocated */ size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } return bp; }
/* * Requires: * "bp" is the address of a newly freed block. * * Effects: * Perform boundary tag coalescing. */ static void * coalesce(void *bp) { size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))) || PREV_BLKP(bp) == bp; size_t size = GET_SIZE(HDRP(bp)); /* Next block is free */ if (prev_alloc && !next_alloc) { size += GET_SIZE(HDRP(NEXT_BLKP(bp))); remove_list(NEXT_BLKP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } /* Previous block is free */ else if (!prev_alloc && next_alloc) { size += GET_SIZE(HDRP(PREV_BLKP(bp))); bp = PREV_BLKP(bp); remove_list(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } /* Both blocks are free */ else if (!prev_alloc && !next_alloc) { size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp))); remove_list(PREV_BLKP(bp)); remove_list(NEXT_BLKP(bp)); bp = PREV_BLKP(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } /*insert bp,free block into free list*/ insert_list(bp); return bp; }
/* * Requires: * "bp" is the address of a newly freed block. * * Effects: * Perform boundary tag coalescing. Returns the address of the coalesced * block. */ static void * coalesce(void *bp) { size_t size = GET_SIZE(HDRP(bp)); bool prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); bool next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); if (prev_alloc && next_alloc) { /* Case 1 */ return (bp); } else if (prev_alloc && !next_alloc) { /* Case 2 */ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } else if (!prev_alloc && next_alloc) { /* Case 3 */ size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } else { /* Case 4 */ size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } return (bp); }
static void *coalescing(void *bp) // combining neighbouring free blocks { size_t prev_allocated = GET_ALLOC(FTRP(PREV_BLKP(bp))); // status of next block size_t next_allocated = GET_ALLOC(HDRP(NEXT_BLKP(bp))); // status of previous free block size_t size = GET_SIZE(HDRP(bp)); // size of the header if (prev_allocated && next_allocated) { return bp; } // both neighboring blocks are allocated else if (prev_allocated && !next_allocated) { // previous block is allocated & next block is free size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); PUT(HDRP(bp), PACK(size, 0)); } else if (!prev_allocated && next_allocated) { // previous block is free & next block is allocated size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } else if (!prev_allocated && !next_allocated) { // both neighboring blocks are free size += GET_SIZE(HDRP(PREV_BLKP(bp)))+GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } return bp; }
/* * coalesce the previous block-curent block-next block IF handled corrected, each free will call this method, and no two consecutive freed block would exsist. */ 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) return bp; else if(prev_alloc && !next_alloc){ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); }else if(!prev_alloc && next_alloc){ size += GET_SIZE(FTRP(PREV_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); bp = PREV_BLKP(bp); }else{ size += GET_SIZE(HDRP(NEXT_BLKP(bp))) + GET_SIZE(FTRP(PREV_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } if((rover > (char*)bp) && (rover < NEXT_BLKP(bp))) rover = bp; return bp; }
/* * coalesce - ser um ad smida/setja saman free lista sem eru hlid vid hlid * tryggir tad ad aldrei seu tveir samliggjandi free blockir */ static void *coalesce(void *bp) { size_t prev_alloc; if (PREV_BLKP(bp) == bp) { prev_alloc = 1; } else 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)); // CASE 1 : PREV fratekid og NEXT fratekid if (prev_alloc && next_alloc) { //printf("CASE 1\n"); // Baeta vidkomandi fremst i free list addBlckToFreeList(bp); return bp; // CASE 2 : PREV fratelod pg MEXT laust } else if (prev_alloc && !next_alloc) { //printf("CASE 2\n"); // Finna staerdina a nyju friu blokkini size += GET_SIZE(HDRP(NEXT_BLKP(bp))); // Fjarlaegja blokkina a eftir i burtu removeBlckFromFreeList(NEXT_BLKP(bp)); // Fria blokkina PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); // CASE 3 : PREV laust og PREV fratekid } else if (!prev_alloc && next_alloc) { //printf("CASE 3\n"); // Finna staerdina a nyju friu blokkini size += GET_SIZE(HDRP(PREV_BLKP(bp))); // Fria blokkina PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); // Fjarlaegja blokkina a undan i burtu removeBlckFromFreeList(bp); // CASE 4 : PREV laust og NEXT laust } else { //printf("CASE 4\n"); // Finna staerdina a nyju friu blokkini size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); // Fjarlaegja blokkirnar a undan og eftir i burtu. removeBlckFromFreeList(PREV_BLKP(bp)); removeBlckFromFreeList(NEXT_BLKP(bp)); // Fria bada blokkirnar PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); PUT(HDRP(bp), PACK(size, 0)); } // Baeta vidkomandi fremst i free list // A vid um CASE 2 , 3 og 4! addBlckToFreeList(bp); return bp; }
/* * Requires: * "bp" is the address of a newly freed block. * * Effects: * Perform boundary tag coalescing. Returns the address of the coalesced * block. */ static void *coalesce(void *bp) { bool prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); bool next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); if (PREV_BLKP(bp) == bp) { prev_alloc = true; } /* a-a-a */ /* insert self at beginning of free list */ if (prev_alloc && next_alloc) { /* Case 1 */ addToBeginningOfFreeList(bp); } /* a-a-f */ /* splice out next, coalesce self and next, and add to beginning of free list */ else if (prev_alloc && !next_alloc) /* Case 2 */ { size += GET_SIZE(HDRP(NEXT_BLKP(bp))); removeBlockFromList(NEXT_BLKP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); addToBeginningOfFreeList(bp); } /* f-a-a */ /* splice out prev, coalesce with self, and add to beginning of free list */ else if (!prev_alloc && next_alloc) /* Case 3 */ { size += GET_SIZE(HDRP(PREV_BLKP(bp))); bp = PREV_BLKP(bp); removeBlockFromList(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); addToBeginningOfFreeList(bp); } /* f-a-f */ /* splice out prev and next, coalesce with self, and add to beginning of list */ else if (!prev_alloc && !next_alloc) /* Case 4 */ { size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp))); removeBlockFromList(PREV_BLKP(bp)); removeBlockFromList(NEXT_BLKP(bp)); bp = PREV_BLKP(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); addToBeginningOfFreeList(bp); } free_listp = bp; /* start of the new free list is at the block that has been put at front of list */ 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)); } }
/* * coalesce * coalesce consecutive free blocks * use hdr and ftr to do constant time coalesce */ void *coalesce(void *bp){ size_t prev_alloc = GET(FTRP(PREV_BLKP(bp))) & 0x1; size_t next_alloc = GET_ALLOC(NEXT_BLKP(bp)); if(prev_alloc && next_alloc){ /* prev/next blocks are not free */ }else if(prev_alloc && !next_alloc){ /* next block is free */ coalesce_next(bp); }else if(!prev_alloc && next_alloc){ /* prev block is free */ bp = PREV_BLKP(bp); coalesce_next(bp); }else{ coalesce_next(bp); bp = PREV_BLKP(bp); coalesce_next(bp); } return bp; }
/* * coalesce - Boundary tag coalescing. Return ptr to coalesced block */ 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) { return bp; } else if (prev_alloc && !next_alloc) { delete_node(bp); delete_node(NEXT_BLKP(bp)); /* Case 2 */ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size,0)); } else if (!prev_alloc && next_alloc) { /* Case 3 */ delete_node(bp); delete_node(PREV_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } else { delete_node(bp); delete_node(PREV_BLKP(bp)); delete_node(NEXT_BLKP(bp)); /* Case 4 */ size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } #ifdef NEXT_FIT /* Make sure the rover isn't pointing into the free block */ /* that we just coalesced */ if ((rover > (char *)bp) && (rover < NEXT_BLKP(bp))) rover = bp; #endif insert_node(bp, size); return bp; }
static void *coalesce(void *ptr) { size_t prev_alloc = GET_ALLOC(HDRP(PREV_BLKP(ptr))); size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(ptr))); size_t size = GET_SIZE(HDRP(ptr)); // Do not coalesce with previous block if the previous block is tagged with Reallocation tag if (GET_TAG(HDRP(PREV_BLKP(ptr)))) prev_alloc = 1; if (prev_alloc && next_alloc) { // Case 1 return ptr; } else if (prev_alloc && !next_alloc) { // Case 2 delete_node(ptr); delete_node(NEXT_BLKP(ptr)); size += GET_SIZE(HDRP(NEXT_BLKP(ptr))); PUT(HDRP(ptr), PACK(size, 0)); PUT(FTRP(ptr), PACK(size, 0)); } else if (!prev_alloc && next_alloc) { // Case 3 delete_node(ptr); delete_node(PREV_BLKP(ptr)); size += GET_SIZE(HDRP(PREV_BLKP(ptr))); PUT(FTRP(ptr), PACK(size, 0)); PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0)); ptr = PREV_BLKP(ptr); } else { // Case 4 delete_node(ptr); delete_node(PREV_BLKP(ptr)); delete_node(NEXT_BLKP(ptr)); size += GET_SIZE(HDRP(PREV_BLKP(ptr))) + GET_SIZE(HDRP(NEXT_BLKP(ptr))); PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(ptr)), PACK(size, 0)); ptr = PREV_BLKP(ptr); } insert_node(ptr, size); return ptr; }
// // coalesce - boundary tag coalescing. Return ptr to coalesced block // static void *coalesce(void *bp) { FL_Pointer prev = PREV_BLKP(bp); FL_Pointer next = NEXT_BLKP(bp); size_t prev_alloc = GET_ALLOC(FTRP(prev)); size_t next_alloc = GET_ALLOC(HDRP(next)); size_t size = GET_SIZE(HDRP(bp)); //CASE 1 : Both neighbors are allocated if (prev_alloc && next_alloc) { // we need to add free list node here b/c we do not do it in mm_free CL_append(&free_list, bp); } //CASE 2 : Only next free else if (prev_alloc && !next_alloc) { // unlink node thats next, b/c our current position will be beggining of new free node CL_unlink(next); CL_append(&free_list, bp); size += GET_SIZE(HDRP(next)); PUT(HDRP(bp), PACK(size,0)); PUT(FTRP(bp), PACK(size,0)); } //CASE 3 : Only prev free else if (!prev_alloc && next_alloc){ size += GET_SIZE(HDRP(prev)); // no need to make new here b/c one exists at prev_node PUT(FTRP(bp), PACK(size,0)); PUT(HDRP(prev), PACK(size,0)); bp = prev; } //CASE 4 : both neighbors unallocated else { size += GET_SIZE(HDRP(prev)) + GET_SIZE(FTRP(next)); // unlink node that is above us, we can ignore the one below us because that // will serve ad the head for this free block CL_unlink(next); PUT(HDRP(prev), PACK(size,0)); PUT(FTRP(next), PACK(size,0)); bp = prev; } return bp; }
/* * Requires: * "bp" is the address of a newly freed block. * * Effects: * Perform boundary tag coalescing. Returns the address of the coalesced * block. */ static void * coalesce(void *bp) { printf("Start coalesce\n"); if (bp == NULL) printf("Pointer is NULL\n"); struct node *new_node; size_t size = GET_SIZE(HDRP(bp)); printf("Got size\n"); bool prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); printf("Stored whether previous block was allocated\n"); bool next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); printf("Stored whether the next block was allocated\n"); printf("Finished coalesce initializations\n"); if (prev_alloc && next_alloc) { /* Case 1 */ printf("Case 1\n"); return (bp); } else if (prev_alloc && !next_alloc) { /* Case 2 */ printf("Case 2\n"); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); splice((struct node *)NEXT_BLKP(bp)); } else if (!prev_alloc && next_alloc) { /* Case 3 */ printf("Case 3\n"); size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); /* Seems to work for now, but rather hackish */ /* the issue arises because bp is not actually in the list yet (I think) */ struct node *temp = (struct node *)bp; if (temp->next != NULL) splice(bp); bp = PREV_BLKP((void *)bp); } else { /* Case 4 */ printf("Case 4\n"); size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); splice((struct node *)bp); splice((struct node *)NEXT_BLKP(bp)); bp = PREV_BLKP(bp); } new_node = (struct node *)coalesce(bp); new_node->next = list_start; new_node->previous = NULL; list_start->previous = new_node; list_start = new_node; checkheap(1); return (bp); }
static char *coalesce(char *bp) { ASSERT(bp != NULL) ; size_t prev_alloc = GETALLOC(FTRP(PREV_BLKP(bp))); size_t next_alloc = GETALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GETSIZE(HDRP(bp)); if (prev_alloc && next_alloc) { /* Case 1 */ FL_insert(bp) ; } else if (prev_alloc && !next_alloc) { /* Case 2 , bottom free*/ FL_remove((char*)(NEXT_BLKP(bp))) ; //remove next block from free list size += GETSIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size,0)); FL_insert((char*)bp) ; // insert new block into free list } else if (!prev_alloc && next_alloc) { /* Case 3 */ //prev is free, next is alloc FL_remove((char*)(PREV_BLKP(bp))) ; // remove prev block from free list size += GETSIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); FL_insert((char*)bp) ; // add new block to free list } else { /* Case 4 */ //remove both top and bottom from free list FL_remove((char*)(PREV_BLKP(bp))) ; FL_remove((char*)(NEXT_BLKP(bp))) ; size += GETSIZE(HDRP(PREV_BLKP(bp))) + GETSIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); FL_insert((char*)bp) ; // insert modified block back } ASSERT(bp == firstFBP) ; return (char*)bp ; }
/* * 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; }
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 */ { return bp; } else if (prev_alloc && !next_alloc) /* Case 2 */ { size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size,0)); } else if (!prev_alloc && next_alloc) /* Case 3 */ { char * pbp = HDRP(PREV_BLKP(bp)); size += GET_SIZE(pbp); PUT(FTRP(bp), PACK(size, 0)); PUT(pbp, PACK(size, 0)); bp = PREV_BLKP(bp); } else /* Case 4 */ { char * pbp = HDRP(PREV_BLKP(bp)); char * nbp = FTRP(NEXT_BLKP(bp)); size += GET_SIZE(pbp) + GET_SIZE(nbp); PUT(pbp, PACK(size, 0)); PUT(nbp, PACK(size, 0)); bp = PREV_BLKP(bp); } return bp; }
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 previous and next are allocated do nothing */ if (prev_alloc && next_alloc) { return bp; } /* if next is not allocated */ else if (prev_alloc && !next_alloc) { size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size ,0)); /* this node's successor is the next node's */ size_t oldSucc = SCRP(NEXT_BLKP(bp)); PUT(SCRP(bp), oldSucc); return(bp); } else if (!prev_alloc && next_alloc) { size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); size_t oldSucc = SCRP(PREV_BLKP(bp)); PUT(SCRP(PREV_BLKP(bp)), oldSucc); return(PREV_BLKP(bp)); } else { size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); return(PREV_BLKP(bp)); } }
/* * checkFreeNodes - function that checks correctness of the blocks in * the free list */ static void checkFreeNodes(void *bp) { /* Seperate condition for free_listp since it does not have a * previous pointer. */ if(bp == free_listp) { /* Checking that free_listp indeed points to a free block. */ if(GET_ALLOC(HDRP(bp))) printf("Error: Freelistp points to an allocated block.\n"); /* Free_listp must point to a valid block and must not be * out of bounds */ if(!(bp > mem_heap_lo() && bp < mem_heap_hi())) printf("Error: Free list pointer out of heap bounds.\n"); /* Previous pointer of free_listp * must point nowhere (nil). */ if(PREV_FREE(bp) != 0 ) printf("Error: Free pointer is not null.\n"); return; } /* Checking that bp is indeed pointing to a free block */ if(GET_ALLOC(HDRP(bp)) != 0) printf("Error: There exists an allocated block in the free list.\n"); /* Check that next and prev pointers in consecutive blocks are consistent * Next pointer of previous block points to current block and previous pointer * of next block points to current block */ // Split one print statement into 2 to not cross the 80 character limit. if(PREV_FREE(bp) && NEXT_FREE(PREV_FREE(bp)) != bp) { printf("Error: Next pointer of previous free block "); printf("not pointing to current block.\n"); } if(NEXT_FREE(bp) && PREV_FREE(NEXT_FREE(bp)) != bp) { printf("Error: Previous pointer of next free block "); printf("not pointing to current block.\n"); } /* Check that coalescing was correct at the free block pointed to by bp. The previous and next blocks must both be allocated.*/ if(!GET_ALLOC(HDRP(NEXT_BLKP(bp))) || !GET_ALLOC(HDRP(PREV_BLKP(bp)))) printf("Error: Contiguous free blocks in the heap\n"); }
static void checkblock(void *bp) { if ((uintptr_t)bp % DSIZE) printf("Error: %p is not doubleword aligned\n", bp); if (GET(HDRP(bp)) != GET(FTRP(bp))){ size_t h=GET(HDRP(bp)); size_t f=GET(FTRP(bp)); size_t preh=GET(HDRP(PREV_BLKP(bp))); printf("Error: header %zu does not match footer %zu %p and previous block %zu\n,",h,f,bp,preh); } }
/* * mm_checkheap - Check the heap for consistency */ void mm_checkheap(int verbose) { if (verbose) printf("Check heap: \n"); char *bp = heap_listp; int free_block_flag = 0; int free_block_count = 0; if (verbose) printf("Heap (%p):\n", heap_listp); // check prologue block if ((GET_SIZE(HDRP(heap_listp)) != OVERHEAD) || !GET_ALLOC(HDRP(heap_listp))) printf("Bad prologue header\n"); checkblock(heap_listp); for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) { if (verbose) printblock(bp); checkblock(bp); // check coalescing if (!GET_ALLOC(HDRP(bp))) { if (free_block_flag == 1) { printf("Error: consecutive free blocks %p | %p in the heap.\n", PREV_BLKP(bp),bp); } free_block_flag = 1; free_block_count++; } else { free_block_flag = 0; } } if (verbose) printblock(bp); // check epilogue block if ((GET_SIZE(HDRP(bp)) != 0) || !(GET_ALLOC(HDRP(bp)))) printf("Bad epilogue header\n"); // print heap boundaries check_heapboundaries(heap_listp-DSIZE, bp-1); if (verbose) { printfreelist(); } checkfreelist(free_block_count); }
/********************************************************** * alloc_block_overlap * Check if any two blocks overlap * for each block in the heap, it will check if the previous * block's footer address is greater than current block's * header address *********************************************************/ int alloc_block_overlap(void){ void *bp; if (heap_listp == NULL) return 1; //no blocks if (NEXT_BLKP(heap_listp) == NULL) return 1; //only one block for (bp = NEXT_BLKP(heap_listp); GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) { if (FTRP(PREV_BLKP(bp)) >= HDRP(bp)) { return 0; } } return 1; }
/** * 把左右两边的空闲块合并成一个大的空闲块, * 一共有四种情况 * */ static void *coalesce(void *bp) { size_t prev_alloc = GET_ALLOC((char*)bp - DSIZE); size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); /* 左右两侧的Block都已经分配 */ if (prev_alloc && next_alloc ) { } else if (!prev_alloc && next_alloc ) { /* 左侧的Block未分配 */ size += GET_SIZE((char*)bp - DSIZE); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); /* prev block的footer并没被修改,因此PREV_BLKP能正确获取到prev block的地址 */ bp = PREV_BLKP(bp); } else if (prev_alloc && !next_alloc ) { /* 右侧的Block未分配 */ size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); PUT(HDRP(bp), PACK(size, 0)); } else { /* 左右两侧的Block都未分配 */ size += GET_SIZE((char*)bp - DSIZE) + GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); /* prev block的footer并没被修改,因此PREV_BLKP能正确获取到prev block的地址 */ bp = PREV_BLKP(bp); } return bp; }
/* * coalesce */ 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)); /*prev and next block are allocated*/ if(prev_alloc && next_alloc){ //insert_free_block(bp); //return bp; } /* next block is free */ else if(prev_alloc && !next_alloc){ delete_free_block(NEXT_BLKP(bp)); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp),PACK(size,0)); PUT(FTRP(bp),PACK(size,0)); //insert_free_block(bp); } /* prev block is free */ else if(!prev_alloc && next_alloc){ delete_free_block(PREV_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp),PACK(size,0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size,0)); bp = PREV_BLKP(bp); //insert_free_block(bp); } /*prev and next are free*/ else{ delete_free_block(PREV_BLKP(bp)); delete_free_block(NEXT_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size,0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size,0)); bp = PREV_BLKP(bp); //insert_free_block(bp); } insert_free_block(bp); return bp; }
/* * coalesce - Coalesces the memory surrounding block bp using the Boundary Tag strategy * proposed in the text (Page 851, Section 9.9.11). * * Adjancent blocks which are free are merged together and the aggregate free block * is added to the free list. Any individual free blocks which were merged are removed * from the free list. */ static void *coalesce(void *bp) { // Determine the current allocation state of the previous and next blocks size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))) || PREV_BLKP(bp) == bp; size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); // Get the size of the current free block size_t size = GET_SIZE(HDRP(bp)); /* If the next block is free, then coalesce the current block * (bp) and the next block */ if (prev_alloc && !next_alloc) { // Case 2 (in text) size += GET_SIZE(HDRP(NEXT_BLKP(bp))); remove_freeblock(NEXT_BLKP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } /* If the previous block is free, then coalesce the current * block (bp) and the previous block */ else if (!prev_alloc && next_alloc) { // Case 3 (in text) size += GET_SIZE(HDRP(PREV_BLKP(bp))); bp = PREV_BLKP(bp); remove_freeblock(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } /* If the previous block and next block are free, coalesce * both */ else if (!prev_alloc && !next_alloc) { // Case 4 (in text) size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp))); remove_freeblock(PREV_BLKP(bp)); remove_freeblock(NEXT_BLKP(bp)); bp = PREV_BLKP(bp); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); } // Insert the coalesced block at the front of the free list NEXT_FREE(bp) = free_listp; PREV_FREE(free_listp) = bp; PREV_FREE(bp) = NULL; free_listp = bp; // Return the coalesced block return bp; }
void *coalesce(void *bp) { size_t previous_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); /* Previous & Next both are allocated. DO NOT COALESCE */ if (previous_alloc && next_alloc) { addFreeBlock(bp); return bp; } /* Previous is allocated, Next is free. */ else if (previous_alloc && !next_alloc) { delFreeBlock(NEXT_BLKP(bp)); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); addFreeBlock(bp); } /* Previous is free, Next is Allocated */ else if (!previous_alloc && next_alloc) { delFreeBlock(PREV_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); addFreeBlock(bp); } /* Both previousious & next are free */ else { delFreeBlock(PREV_BLKP(bp)); delFreeBlock(NEXT_BLKP(bp)); size+=GET_SIZE(HDRP(PREV_BLKP(bp))); size+=GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); addFreeBlock(bp); } return bp; /* return the void pointer ... anyway we are not getting to catch it */ }