/* * free */ void free(void *ptr) { dbg_printf("=== FREE : 0x%lx\n",(size_t)ptr); #if DEBUG if (NEXT_BLKP(ptr)) { if (!GET_PREV_ALLOC(GET_HEADER(NEXT_BLKP(ptr)))) { dbg_printf("0x%lx Fail to inform next block when malloc, or next block fail to update\n", (size_t)ptr); exit(3); } } #endif if(!ptr) return; /* Debug */ if(!in_heap(ptr)) { dbg_printf("ptr is not in heap!\n"); mm_checkheap(63); exit(1); } if (!aligned(ptr)) { dbg_printf("ptr is not aligned!\n"); mm_checkheap(63); exit(1); } size_t bsize = GET_SIZE(GET_HEADER(ptr)); size_t flag = GET_PREV_ALLOC(GET_HEADER(ptr)) ? 0x2 : 0x0; PUT(GET_HEADER(ptr), PACK(bsize, flag)); PUT(GET_FOOTER(ptr), PACK(bsize, flag)); /* Inform the next block that this block is freed */ char *nextbp = NEXT_BLKP(ptr); if (nextbp) { flag = GET(GET_HEADER(nextbp)); flag &= ~0x2; PUT(GET_HEADER(nextbp), flag); /* Only put footer when next block is free */ if (!GET_ALLOC(GET_HEADER(nextbp))) { PUT(GET_FOOTER(nextbp), flag); } } coalesce(ptr); mm_checkheap(CHECK_HEAP); }
/* * malloc */ void *malloc (size_t size) { //dbg_printf("malloc size%u\n",(uint32_t)size); size_t asize; /* Adjusted block size */ size_t extendsize; /* Amount to extend heap if no fit */ char *bp; mm_checkheap(0); /* Ignore spurious requests */ if (size == 0) return NULL; /* Adjust block size to include overhead and alignment reqs. */ asize=(size+15)&(~0x7); /* Search the free list for a fit */ if ((bp = find_fit(asize)) != NULL) { place(bp, asize); return bp; } /* No fit found. Get more memory and place the block */ extendsize = MAX(asize,CHUNKSIZE); if ((bp = extend_heap(extendsize)) == NULL) return NULL; place(bp, asize); return bp; }
/* * malloc */ void *malloc (size_t size) { size_t asize; /* Adjusted block size */ size_t extendsize; /* Amount to extend heap if no fit */ char *bp; if (heap_listp == 0){ mm_init(); } /* Ignore spurious requests */ if (size == 0) return NULL; asize = ALIGN(size + 4); /* the overhead is payload + header(4 byte) + padding(optional) */ asize = MAX(asize, MINSIZE * WSIZE); /* require minimum size */ /* Search the free list for a fit */ if ((bp = find_fit(asize)) != NULL) { #ifdef DEBUG printf("malloc: before alloc.\n"); mm_checkheap(1); #endif place(bp, asize); #ifdef DEBUG printf("malloc: after alloc.\n"); mm_checkheap(1); printf("\n\n"); #endif return bp; } /* No fit found. Get more memory and place the block */ int tail_free = 0; // the free space we have in the tail of heap if (heap_tailp && !GET_ALLOC(HDRP(heap_tailp))) { tail_free = GET_SIZE(HDRP(heap_tailp)); } extendsize = MAX(asize - tail_free,CHUNKSIZE); bp = extend_heap(extendsize/WSIZE); if (bp == NULL) return NULL; place(bp, asize); return bp; }
/* * free */ void free (void *bp) { if(bp == 0) return; if (heap_listp == 0){ mm_init(); } #ifdef DEBUG printf("free: before.\n"); mm_checkheap(1); #endif MARK_FREE(HDRP(bp)); PUT(FTRP(bp), GET(HDRP(bp))); coalesce(bp); #ifdef DEBUG printf("free: after.\n"); mm_checkheap(1); printf("\n\n"); #endif }
static void *extend_heap(int words) { /* last block of heap, size = 0, alloc = 1 */ char *epilogue = (mem_heap_hi() + 1); char *bp; /* block pointer */ int bsize; /* block size to extend */ size_t flag = 0; /* Allocate even number of words to maintain alignment */ bsize = (words % 2) ? ((words + 1) * WSIZE) : (words * WSIZE); dbg_printf("EXTEND_HEAD: words = %d bszie = %d\n", words, bsize); dbg_printf("!!!!!!!!!!!!!!!!!!!!!!!!Before Extend!!!!\n"); mm_checkheap(CHECK_HEAP); /* Record if last block is allocated or not */ flag = GET_PREV_ALLOC(GET_HEADER(epilogue)) ? 0x2 : 0x0; if ((long)(bp = mem_sbrk(bsize)) == -1) return NULL; /* Init free block header/footer and the epilogue header */ PUT(GET_HEADER(bp), PACK(bsize, flag)); PUT(GET_FOOTER(bp), PACK(bsize, flag)); /* Set epilogue to be size = 0, alloc = 1 */ PUT(GET_HEADER(NEXT_BLKP(bp)), PACK(0, 1)); SET_PRED(bp, NULL); SET_SUCC(bp, NULL); mm_checkheap(CHECK_HEAP); return coalesce(bp); }
/* * free */ void free(void *bp) { if(bp == 0) return; if (first_block == 0) mm_init(); UNSET_ALLOC(HDRP(bp)); PUT(FTRP(bp), GET(HDRP(bp))); coalesce(bp); #ifdef DEBUG mm_checkheap(1); #endif }
/* * malloc */ void *malloc (size_t size) { size_t asize; /* Adjusted block size */ size_t extendsize; /* Amount to extend heap if no fit */ char *bp; /* Re-initiate */ if (first_block == 0){ mm_init(); } /* Ignore spurious requests */ if (size == 0) return NULL; /* Adjust block size to include overhead and alignment*/ asize = MAX(ALIGN(size + WSIZE), MINSIZE * WSIZE); assert(asize >= MINSIZE * WSIZE); /* Search the free list for a fit */ if ((bp = find_fit(asize)) != NULL) { place(bp, asize); #ifdef DEBUG mm_checkheap(1); #endif return bp; } /* No fit found. Get more memory and place the block */ extendsize = MAX(asize,CHUNKSIZE); if (NULL == (bp = extend_heap(extendsize/WSIZE))) return NULL; place(bp, asize); #ifdef DEBUG mm_checkheap(1); #endif return bp; }
static void printblock(void *bp) { size_t hsize, halloc, fsize, falloc; mm_checkheap(0); hsize = GET_SIZE(HDRP(bp)); halloc = GET_ALLOC(HDRP(bp)); fsize = GET_SIZE(FTRP(bp)); falloc = GET_ALLOC(FTRP(bp)); if (hsize == 0) { printf("%p: EOL\n", bp); return; } /* printf("%p: header: [%p:%c] footer: [%p:%c]\n", bp, hsize, (halloc ? 'a' : 'f'), fsize, (falloc ? 'a' : 'f')); */ }
/* * Initialize: return -1 on error, 0 on success. */ int mm_init(void) { heap_listp = NULL; classp = NULL; int i = 0; /* Init segregated free list class pointer space */ if ((classp = mem_sbrk(CLASS_NUM * WSIZE)) == (void *)-1) return -1; for (i = 0; i < CLASS_NUM; i++) { SET_CLASS_ROOT_BLK(classp + (i * WSIZE), NULL); } /* Try mm_init with sbrk*/ if ((heap_listp = mem_sbrk(4 * WSIZE)) == (void *)-1) return -1; PUT(heap_listp, 0); PUT(heap_listp + (1 * WSIZE), PACK(DSIZE, 3)); /* Prologue header */ PUT(heap_listp + (2 * WSIZE), PACK(DSIZE, 3)); /* Prologue footer */ PUT(heap_listp + (3 * WSIZE), PACK(0, 3)); /* Epilogue header */ heap_listp += 2 * WSIZE; if (extend_heap(CHUNKSIZE/WSIZE) == NULL) { return -1; } dbg_printf("HEAP INIT\n"); mm_checkheap(CHECK_HEAP); return 0; }
/* Place an ADJUSTED sized block in heap */ static void place(void *bp, size_t asize) { #if DEBUG if (NEXT_BLKP(bp)) { if (GET_PREV_ALLOC(GET_HEADER(NEXT_BLKP(bp)))) { dbg_printf("0x%lx: Fail to inform next block when free\n", (size_t)bp); exit(2); } } #endif dbg_printf("=== Place, bp = 0x%lx, adjusted size = %ld \n", (size_t)bp, asize); /* block free size */ size_t csize = GET_SIZE(GET_HEADER(bp)); char *nextbp = NULL; int class_idx = 0; size_t flag = 0; /* Split, say, minimum block size set to 1 WSIZE = 8 byte */ if ((csize - asize) >= (4 * WSIZE)) { class_idx = get_class_idx_by_size(GET_SIZE(GET_HEADER(bp))); /* Include previous block's information */ flag = GET_PREV_ALLOC(GET_HEADER(bp)) ? 0x3 : 0x1; PUT(GET_HEADER(bp), PACK(asize, flag)); PUT(GET_FOOTER(bp), PACK(asize, flag)); nextbp = NEXT_BLKP(bp); PUT(GET_HEADER(nextbp), PACK((csize - asize), 0)); PUT(GET_FOOTER(nextbp), PACK((csize - asize), 0)); /* Inform the next block that this block is allocated */ flag = GET(GET_HEADER(nextbp)); flag |= 0x2; PUT(GET_HEADER(nextbp), flag); PUT(GET_FOOTER(nextbp), flag); split_free_block(bp, nextbp); remove_free_block(bp, class_idx); remove_free_block(nextbp, class_idx); insert_first(nextbp); mm_checkheap(CHECK_HEAP); } else { /* Include previous block's information */ flag = GET_PREV_ALLOC(GET_HEADER(bp)) ? 0x3 : 0x1; PUT(GET_HEADER(bp), PACK(csize, flag)); PUT(GET_FOOTER(bp), PACK(csize, flag)); /* Inform the next block that this block is allocated */ if ((size_t)bp == 0x800004980) { dbg_printf("bp size = %ld\n",GET_SIZE(GET_HEADER(bp))); dbg_printf("NEXT_BLKP(bp); 0x%lx\n",(size_t)NEXT_BLKP(bp)); } nextbp = NEXT_BLKP(bp); if (nextbp) { flag = GET(GET_HEADER(nextbp)); flag |= 0x2; PUT(GET_HEADER(nextbp), flag); /* Only put footer when next block is free */ if (!GET_ALLOC(GET_HEADER(nextbp))) { PUT(GET_FOOTER(nextbp), flag); } } remove_free_block(bp, get_class_idx_by_size(csize)); } }