/* Initialize the allocator. */ int mm_init () { // Head of the free list. BlockInfo *firstFreeBlock; // Initial heap size: WORD_SIZE byte header (stores pointer to head // of free list), MIN_BLOCK_SIZE bytes of space, WORD_SIZE byte footer. int initsize = WORD_SIZE+MIN_BLOCK_SIZE+WORD_SIZE; int totalSize; void* mem_sbrk_result = mem_sbrk(initsize); // printf("mem_sbrk returned %p\n", mem_sbrk_result); if ((int)mem_sbrk_result == -1) { printf("ERROR: mem_sbrk failed in mm_init, returning %p\n", mem_sbrk_result); exit(1); } firstFreeBlock = (BlockInfo*)POINTER_ADD(mem_heap_lo(), WORD_SIZE); // total usable size is full size minus header and footer words. totalSize = initsize - WORD_SIZE - WORD_SIZE; // initialize the free block firstFreeBlock->sizeAndTags = totalSize | TAG_PRECEDING_USED; firstFreeBlock->next = NULL; firstFreeBlock->prev = NULL; // boundary tag *((int*)POINTER_ADD(firstFreeBlock, totalSize - WORD_SIZE)) = totalSize | TAG_PRECEDING_USED; // Tag "useless" word at end of heap as used. *((int*)POINTER_SUB(mem_heap_hi(), 3)) = TAG_USED; // set the head of the free list to this new free block. FREE_LIST_HEAD = firstFreeBlock; return 0; }
static void checkblock(void *bp) { size_t halloc = GET_ALLOC(HDRP(bp)); // check if free block is inside heap if ((bp < mem_heap_lo()) || (mem_heap_hi() < bp)) { printf("mm_check: block pointer %p outside of heap\n",bp); fflush(stdout); exit(0); } // alignment check if ((size_t)bp % 8) { printf("Error: %p is not doubleword aligned\n", bp); exit(0); } // allocated block does not have footer if (!halloc) { if (GET(HDRP(bp)) != GET(FTRP(bp))) { printf("Error: header does not match footer\n"); exit(0); } } }
/* Print the heap by iterating through it as an implicit free list. */ static void examine_heap() { BlockInfo *block; /* print to stderr so output isn't buffered and not output if we crash */ fprintf(stderr, "FREE_LIST_HEAD: %p\n", (void *)FREE_LIST_HEAD); for(block = (BlockInfo *)UNSCALED_POINTER_ADD(mem_heap_lo(), WORD_SIZE); /* first block on heap */ SIZE(block->sizeAndTags) != 0 && block < mem_heap_hi(); block = (BlockInfo *)UNSCALED_POINTER_ADD(block, SIZE(block->sizeAndTags))) { /* print out common block attributes */ fprintf(stderr, "%p: %ld %ld %ld %ld %ld \t", (void *)block, SIZE(block->sizeAndTags), block->sizeAndTags & TAG_PRECEDING_USED, block->sizeAndTags & TAG_USED, block->sizeAndTags, ((BlockInfo *) UNSCALED_POINTER_ADD(block, SIZE(block->sizeAndTags) - WORD_SIZE))->sizeAndTags); /* and allocated/free specific data */ if (block->sizeAndTags & TAG_USED) { fprintf(stderr, "ALLOCATED\n"); } else { fprintf(stderr, "FREE\tnext: %p, prev: %p\n", (void *)block->next, (void *)block->prev); } } fprintf(stderr, "END OF HEAP\n\n"); }
/* * mm_check - heap consistency checker. return 0 if something is wrong, 1 otherwise. */ int mm_check(void) { void *cur, *end; if(!rb_check_preorder()){ return 0; } cur = mem_heap_lo() + MIN_BLOCK_SIZE; end = mem_heap_hi() - 3; while(cur < end){ if(CUR_FREE(cur)){ // cur is free block if(PREV_FREE(cur)){ // contiguous free block printf("%p, %p are consecutive, but both are free.\n", PREV_BLOCK(cur, CUR_SIZE_MASKED(cur)), cur); return 0; } if(IS_IN_RB(cur) && !rb_find_exact(cur)){ // cur is not in Red-black tree printf("%p is free block, but is not in Red-black tree.\n", cur); return 0; } }else{ // cur is allocated block } cur = NEXT_BLOCK(cur, CUR_SIZE_MASKED(cur)); } return 1; }
/* * * coalesce - boundary tag coalescing. Return ptr to coalesced block * */ static void *coalesce(void *bp) { hdr_p p, np, pp, fp; p = (hdr_p)HDRP(bp); np = (hdr_p)HDRP(NEXT_BLKP(bp)); pp = (hdr_p)HDRP(PREV_BLKP(bp)); size_t prev_alloc = GET_ALLOC(pp); size_t next_alloc = GET_ALLOC(np); size_t size = GET_SIZE(HDRP(bp)); if ((prev_alloc && next_alloc) || (np->size == 0 && pp->size ==0)) { /* Case 1 */ fp = (hdr_p)mem_heap_lo(); p->next = fp->next; p->prev = fp->prev; fp->next = p; fp->prev->next = p; // return bp; } else if ((prev_alloc && !next_alloc) || (pp->size ==0 && !next_alloc)) { /* Case 2 */ size += GET_SIZE(np) + OVERHEAD; p->next = np->next; p->prev = np->prev; // np->prev->next = p; // np->next->prev = p; p->size = PACK(size, 0); PUT(FTRP(bp), PACK(size,0)); } else if ((!prev_alloc && next_alloc) || (np->size == 0 && !prev_alloc)) { /* Case 3 */ size += GET_SIZE(pp) + OVERHEAD; pp->next = p->next; pp->prev = p->prev; p->prev->next = pp; p->next->prev = pp; pp->size = PACK(size, 0); PUT(FTRP(BLPTR(pp)), pp->size); bp = BLPTR(pp); } else { /* Case 4 */ pp->next = np->next; pp->prev = np->prev; // pp->prev->next = pp; // pp->next->prev = pp; size += GET_SIZE(np) + GET_SIZE(pp) + (OVERHEAD << 1); pp->size = PACK(size,0); PUT(FTRP(BLPTR(pp)), pp->size); bp = BLPTR(pp); } return bp; }
/* * checkBlock - Checks a block for consistency * Checks prev and next pointers to see if they are within heap boundaries. * Checks for 8-byte alignment. * Checks header and footer for consistency. * * This function takes a block pointer (to a block for examinination) as a * parameter. */ static void checkBlock(void *bp) { // Reports if the next and prev pointers are within heap bounds if (NEXT_FREEP(bp)< mem_heap_lo() || NEXT_FREEP(bp) > mem_heap_hi()) printf("Error: next pointer %p is not within heap bounds \n" , NEXT_FREEP(bp)); if (PREV_FREEP(bp)< mem_heap_lo() || PREV_FREEP(bp) > mem_heap_hi()) printf("Error: prev pointer %p is not within heap bounds \n" , PREV_FREEP(bp)); /* Reports if there isn't 8-byte alignment by checking if the block pointer * is divisible by 8. */ if ((size_t)bp % 8) printf("Error: %p is not doubleword aligned\n", bp); // Reports if the header information does not match the footer information if (GET(HDRP(bp)) != GET(FTRP(bp))) printf("Error: header does not match footer\n"); }
void print_the_heap() // printing the information related to blocks in the heap { blockHdr *bp = mem_heap_lo(); while(bp<(blockHdr *)mem_heap_hi()){ printf("%s block at: %p,size: %d\n",(bp->size&1)?"allocated":"free",bp ,(int)(bp->size & ~1)); bp = (blockHdr *)((char *)bp +(bp->size & ~1)); } }
void print_heap() { hblock *bp = mem_heap_lo(); while(bp < (hblock *) mem_heap_hi()) { printf("%s block at %p, size %d\n", GET_ALLOC(bp) ? "allocated":"free", bp, GET_SIZE(bp)); bp = (hblock *) NEXT_BLKP(bp); } }
void mm_free(void *ptr) { blockHdr *bp = ptr-BLK_HDR_SIZE, *head = mem_heap_lo(); bp->size &= ~1; bp->next_p = head->next_p; bp->prior_p = head; head->next_p = bp; bp->next_p->prior_p = bp; }
/********************************************************** * is_in_heap * Checks if the block pointer is in heap. Prints an error * message if the block is outside the heap **********************************************************/ int is_in_heap(void *bp) { if (bp < mem_heap_lo() || bp > mem_heap_hi()) { PRINTDBG (("The block is not on the heap\n")); return 0; } return 1; }
void print_heap() { blockHdr *bp = mem_heap_lo(); while (bp < (blockHdr *)mem_heap_hi()) { printf("%s block at %p, size %d\n", (bp->size&1)?"allocated":"free", bp, (int)(bp->size & ~1)); bp = (blockHdr *)((char *)bp + (bp->size & ~1)); } }
void print_heap(){ blockHdr *bp = mem_heap_lo(); int i = 0; while (bp < (blockHdr *) mem_heap_hi()) { printf("%d. %s block at %p, size %ld + \n", i, (bp->size&1)?"allocated":"free", bp, (long) (bp->size & ~1)); bp = (blockHdr *) ((char *) bp + (bp->size & ~1)); i++; } }
/* * 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"); }
void checklist(void) { void* bp = heap_listp; void* prev_ptr; //int prev_alloc = 1; int i; dbg1("[IN ] : checklist\n"); /* go through each segregated free list */ for ( i = 0; i <= MAXCLASS; i++ ) { if (verbose) printlist(i); bp = GET_FREE_LISTP(i); prev_ptr = NULL; while( bp != NULL) { /* see if pointer is within heap */ if ((bp < mem_heap_lo()) || (mem_heap_hi() < bp)) { printf("mm_check: free block pointer %p outside of heap\n",bp); fflush(stdout); exit(0); } /* make sure block is truly free */ if (GET_ALLOC(HDRP(bp))) { printf("mm_check: free block list %d has allocated block\n", i); fflush(stdout); exit(0); } /* make sure block is not smaller than min block */ if (GET_SIZE(HDRP(bp)) < OVERHEAD + 2*DSIZE) { printf("mm_check: block too small in list %d with block at %p\n", i, bp); printf("mm_check: %x\n", GET_SIZE(HDRP(bp))); fflush(stdout); exit(0); } /* make sure previous pointer is correct */ if (PREV_FREE_BLKP(bp) != prev_ptr) { printf("mm_check: previous block ptr in list %d does not point to previous block\n", i); fflush(stdout); exit(0); } /* go to next free block */ prev_ptr = bp; bp = (void*)NEXT_FREE_BLKP(bp); } } dbg1("[OUT] : checklist\n"); return; }
/* * checkblock - checks basic invariants of a block in the heap list */ static void checkblock(void *bp) { /* Checking for double word alignment */ if ((size_t)bp % 8) printf("Error: %p is not doubleword aligned\n", bp); /* Header must match footer for allocation bit and size */ if (GET(HDRP(bp)) != GET(FTRP(bp))) printf("Error: header does not match footer\n"); /* Block pointer must be within the heap boundaries */ if(bp > mem_heap_hi() || bp < mem_heap_lo()) printf("Error: block pointer not within heap boundaries.\n"); }
/* * mm_free - Freeing a block does nothing. */ void mm_free(void *ptr) // to free an allocated block { blockHdr *bp = ptr-BLK_HDR_SIZE, *head = mem_heap_lo(); /* status changed from allocated to free */ bp->size &= ~1; bp->next = head->next; bp->prev = head; head->next = bp; bp->next->prev = bp; }
/* * mm_exit - finalize the malloc package. */ void mm_exit(void) { void *cur, *end; cur = mem_heap_lo() + MIN_BLOCK_SIZE; end = mem_heap_hi() - 3; while(cur < end){ /* check if there are allocated blocks remaining */ if(!CUR_FREE(cur)){ printf("memory leak at %p is detected.\n", cur); mm_free(cur + HEADER_SIZE); } cur = NEXT_BLOCK(cur, CUR_SIZE_MASKED(cur)); } }
/* $begin mmfree */ void mm_free(void *bp) { // printf("MM_free "); hdr_p fp,p; p = (hdr_p)HDRP(bp); size_t size = GET_SIZE(p); ((hdr_p)HDRP(bp))->size = PACK(size,0); PUT(FTRP(bp), PACK(size, 0)); fp = (hdr_p)mem_heap_lo(); // p->next = fp->next; // p->prev = fp; // fp->next = p; // printf(" DONE \n"); // coalesce((char *)bp); }
/* * mm_print - Print block list for debug purpose. */ void mm_print(void) { void *now = mem_heap_lo(); size_t now_size = 0; printf("\n"); // scan the block list while ((now - 1) != mem_heap_hi()) { now_size = MM(now)->size; printf("pos: %x - head: %x\n", (unsigned) now, now_size); // visit the next block now += SIGN_CHECK(now_size) ? SIGN_MARK(now_size) : now_size; } }
/* check_heap - Check the heap for consistency etc. Convenient to manually call while running GDB but is not called otherwise */ void check_heap() { listBlock* ptr; int *footer; listBlock* heapStart = (listBlock*)mem_heap_lo(); listBlock* heapEnd = (listBlock*)mem_heap_hi(); printf("Address Block size Allocated\n"); ptr = heapStart; while (ptr < heapEnd) { footer = (int *)(((char *)ptr) + (ptr->header&~0x1) - WORD_SIZE); printf("%5p%14d%12d%10s\n", ptr, (int)(ptr->header & ~0x1), ptr->header & 0x1, ptr->header == *footer?"OK":"corrupt"); ptr = (listBlock*)((char*)ptr + (ptr->header & ~0x1)); } printf("Heap Size Total: %5d\n", (int)mem_heapsize()); }
void *map_to_list(int size){ //given a certain size, this function returns a pointer to it's corresponding free list //It's basically a function (well, in a mathemathical sense) that maps some size //to the free list which contains items of that size blockHdr *list = (blockHdr *) mem_heap_lo(); if(size < 290){ return list; }else if (size < 540){ return list + 1; }else if (size < 2080){ return list + 2; }else{ return list + 3; } }
/* * mm_free - Freeing a block with coalescing */ void mm_free(void *ptr) { listBlock *blockToFree = ptr - OFFSET; // because the pointer the user has is to one that follows after the payload, so have to go back to start of block blockToFree->header = blockToFree->header & ~0x1; // set allocation bit to Free int *footer = (int *)(((char *)blockToFree) + blockToFree->header - WORD_SIZE); // set the footer even though it may well be unnecessary *footer = blockToFree->header; int needsLinking = coalesce(blockToFree); // coalesce the block if (needsLinking == 1) { // if the block did not coalesce with the block in front of it, need to link it into the free list listBlock *firstFree = (listBlock *)mem_heap_lo(); blockToFree->next = firstFree->next; blockToFree->prev = firstFree; firstFree->next = blockToFree; blockToFree->next->prev = blockToFree; } }
/* find_free_block - Search the linked list of free blocks to find one of sufficient size. If the search is taking too long without * locating a suitable block, give up and just expand the heap, my assumption being that if the first 400 blocks are that fragmented * then it's better to create a new, larger block at the front than have to keep scanning through so many that are too small. */ listBlock *find_free_block(size_t size) { int count = 0; listBlock *freeBlock; listBlock *heapStart = (listBlock *)mem_heap_lo(); for (freeBlock = heapStart->next; (freeBlock != heapStart) && (freeBlock->header < size) && (count < 400); freeBlock = freeBlock->next) { count++; } if ((freeBlock != heapStart) && (freeBlock->header >= size)) { return freeBlock; } else { return NULL; } }
/* * mm_init - Initialize the malloc package, and return 0 if successful and -1 otherwise. */ int mm_init(void) { /* Attempt to create an empty heap with just a prologue * at the beginning */ if (mem_sbrk(HSIZE) == (void *)-1) return -1; p = (hblock *) mem_heap_lo(); /* Set the block size of the header, and make it point to itself */ p->header = HSIZE | 0x1; // The prologue will be the only allocated block of HSIZE p->footer = p->header; p->succ_p = p; p->pred_p = p; return 0; }
/** * mm_init - Initialize the malloc package. */ int mm_init(void) { TRACE(">>>Entering mm_init()\n"); mem_init(); #ifdef DO_MM_CHECK /* initialize the ENTIRE heap provided by memlib to 0x00 */ memset(mem_heap_lo(), 0, MAX_HEAP); #endif /*Each element in free_lists starts off as the empty head of a linked list*/ memset(free_lists, (int)NULL, sizeof(free_lists)); /* Initialize write-once variables */ PAGE_SIZE = mem_pagesize(); ADJUSTED_PAGESIZE = ADJUST_BYTESIZE((PAGE_SIZE*2)); /* Initially allocate 1 page of memory plus room for the prologue and epilogue blocks and free block header */ if((heap_start = mem_sbrk(ADJUSTED_PAGESIZE + (4 * WSIZE))) == NULL) return -1; heap_end = mem_heap_hi(); /* Alignment word */ PUTW(heap_start, 0x8BADF00D); /* Prologue header */ PUTW(heap_start + (1 * WSIZE), PACK(DSIZE, THISALLOC | PREVALLOC)); PUTW(heap_start + (2 * WSIZE), PACK(DSIZE, THISALLOC | PREVALLOC)); /* Epilogue header */ PUTW(heap_start + ADJUSTED_PAGESIZE + 3 * WSIZE, PACK(0xEA7F00D0, THISALLOC)); /* Setup initial free block */ PUTW(heap_start + (3 * WSIZE), PACK(ADJUSTED_PAGESIZE, PREVALLOC)); PUTW((heap_end - WSIZE + 1) - WSIZE, PACK(ADJUSTED_PAGESIZE, PREVALLOC)); add_to_list(heap_start + (4 * WSIZE), calc_list_index(ADJUSTED_PAGESIZE)); RUN_MM_CHECK(); TRACE("<<<---Leaving mm_init()\n"); return 0; }
/* Initialize the allocator. */ int mm_init () { // Head of the free list. BlockInfo *firstFreeBlock; // Initial heap size: WORD_SIZE byte heap-header (stores pointer to head // of free list), MIN_BLOCK_SIZE bytes of space, WORD_SIZE byte heap-footer. size_t initSize = WORD_SIZE+MIN_BLOCK_SIZE+WORD_SIZE; size_t totalSize; void* mem_sbrk_result = mem_sbrk(initSize); // printf("mem_sbrk returned %p\n", mem_sbrk_result); if ((ssize_t)mem_sbrk_result == -1) { printf("ERROR: mem_sbrk failed in mm_init, returning %p\n", mem_sbrk_result); exit(1); } firstFreeBlock = (BlockInfo*)UNSCALED_POINTER_ADD(mem_heap_lo(), WORD_SIZE); // Total usable size is full size minus heap-header and heap-footer words // NOTE: These are different than the "header" and "footer" of a block! // The heap-header is a pointer to the first free block in the free list. // The heap-footer is used to keep the data structures consistent (see // requestMoreSpace() for more info, but you should be able to ignore it). totalSize = initSize - WORD_SIZE - WORD_SIZE; // The heap starts with one free block, which we initialize now. firstFreeBlock->sizeAndTags = totalSize | TAG_PRECEDING_USED; firstFreeBlock->next = NULL; firstFreeBlock->prev = NULL; // boundary tag *((size_t*)UNSCALED_POINTER_ADD(firstFreeBlock, totalSize - WORD_SIZE)) = totalSize | TAG_PRECEDING_USED; // Tag "useless" word at end of heap as used. // This is the is the heap-footer. *((size_t*)UNSCALED_POINTER_SUB(mem_heap_hi(), WORD_SIZE - 1)) = TAG_USED; // set the head of the free list to this new free block. FREE_LIST_HEAD = firstFreeBlock; printf("Heap after initialization\n"); examine_heap(); return 0; }
/* * Initialize: return -1 on error, 0 on success.i */ int mm_init(void) { if((heap_listp = mem_sbrk(22*WSIZE)) == (void *)-1) return -1; heapstart = mem_heap_lo(); int offset = 16; root=heap_listp + 8; /* Padding for 8-byte alignment */ PUT(heap_listp,0); /* The root block's header is used as prologue * Hence, its allocated bit is set to avoid boundary conditions */ PUT(heap_listp + WSIZE, PACK(80,2, 1)); /* Storing the next/prev pointers of the root nodes of the 9 lists * The lists are arranged in ascending order of sizes */ PUT(heap_listp + 8, (long)(root)- (long)(heapstart)); PUT(heap_listp + 12, (long)(root)- (long)(heapstart)); while(offset != 80) { PUT(heap_listp+offset, (long)(heap_listp+offset)-(long)(heapstart)); PUT(heap_listp+offset+4, (long)(heap_listp+offset)-(long)(heapstart)); offset = offset+8; } PUT(heap_listp + 80, PACK(80,2, 1)); /* Epilogue blocks allocated bit is set to 1 to avoid boundary conditions * The size is 0, to differentiate it from other blocks * The prev_alloc bit is set to 1, which indicates root always allocated */ PUT(heap_listp + 84, PACK(0,2, 1)); if(extend_heap(CHUNKSIZE/WSIZE) == NULL) return -1; return 0; }
/* * Returns true if the given tree, along with all its children, * lies entirely within the heap. */ int mm_tree_ok(char *node) { if (node == NULL) { return !0; } if (node < (char *)mem_heap_lo() || node > (char *)mem_heap_hi()) { return 0; } if (!mm_tree_ok(rbtree_get_left(node))) { return 0; } if (!mm_tree_ok(rbtree_get_right(node))) { return 0; } return !0; }
// check - This checks our invariant that the size_t header before every // block points to either the beginning of the next block, or the end of the // heap. int allocator::check() { char *p; char *lo = (char*)mem_heap_lo(); char *hi = (char*)mem_heap_hi() + 1; size_t size = 0; p = lo; while (lo <= p && p < hi) { size = ALIGN(*(size_t*)p + SIZE_T_SIZE); p += size; } if (p != hi) { printf("Bad headers did not end at heap_hi!\n"); printf("heap_lo: %p, heap_hi: %p, size: %lu, p: %p\n", lo, hi, size, p); return -1; } return 0; }
/* $begin mmplace-proto */ static void place(void *bp, size_t asize) /* $end mmplace-proto */ { size_t csize = GET_SIZE(HDRP(bp)); // printf("csize=%d asize=%d ble=%d\n", csize, asize, ALIGN(DSIZE+OVERHEAD)); // printf("PLACE "); if ((csize - asize) <= ALIGN(DSIZE)) { // printf("kill \n"); hdr_p p, fp; p = HDRP(bp); fp = (hdr_p)mem_heap_lo(); p->size=PACK(asize, 1); // PUT(FTRP(BLPTR(p)), p->size); // bp = NEXT_BLKP(bp); // hdr_p np = HDRP(bp); // np->next = fp->next; // fp->next->prev = fp; // np->prev = fp->prev; // np->size = PACK((csize - asize), 0); // PUT(FTRP(BLPTR(np)), np->size); // PUT(HDRP(bp), PACK(csize-asize, 0)); // PUT(FTRP(bp), PACK(csize-asize, 0)); } else { hdr_p p = (hdr_p)HDRP(bp); if (p->next == NULL) p->prev->next == NULL; else p->next->prev = p->prev; // p->prev->next = p->next; // p->size = PACK(asize-OVERHEAD,1); // PUT(FTRP(BLPTR(p)), p->size); // PUT(HDRP(bp), PACK(csize, 1)); // PUT(FTRP(bp), PACK(csize, 1)); } // printf(" DONE \n"); }