/*
 * 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;
}
Beispiel #3
0
/*
 * 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;
}
Beispiel #4
0
/*
 * 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;
}
Beispiel #8
0
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));
    }
}