Esempio n. 1
0
static void place(void *bp, size_t asize)   {
	//dbg_printf("place%p\n",bp);
    size_t csize = GET_SIZE(HDRP(bp));   
//	void *remain_blk;
size_t remain_size=csize-asize;
    if ((remain_size) >= 16) {
	void *remain_blk; 
		delete_free_block(bp);	
//		size_t predoff=get_pred_offset(bp);
//		size_t succoff=get_succ_offset(bp);
		alloc_block(bp,asize);
		remain_blk= NEXT_BLKP(bp);
		PUT(HDRP(remain_blk), PACK(remain_size, 0));
		PUT(FTRP(remain_blk), PACK(remain_size, 0));
		add_free_block(remain_blk,remain_size);
		/*size_t re_off=get_offset(remain_blk);
		set_succ(remain_blk,succoff);
		set_pred(remain_blk,predoff);
//	if (predoff){
		set_succ(get_addr(predoff),re_off);
//	}
//	else free_list=remain_blk;
	if (succoff){
		set_pred(get_addr(succoff),re_off);
		}*/
    }
    else { 
		delete_free_block(bp);
		PUT(HDRP(bp), PACK(csize, 1));
		PUT(FTRP(bp), PACK(csize, 1));
    }
}
Esempio n. 2
0
/* Free the block whose first page (aka block leader) is specified
 * by "page_idx". return 1 on success and 0 otherwise.
 */
int
free_block(page_idx_t page_idx) {
    (void)remove_alloc_block(page_idx);

    lm_page_t* pi = alloc_info->page_info;
    lm_page_t* page = pi + page_idx;
    int order = page->order;
    ASSERT (find_block(page_idx, order, NULL) == 0);

    /* Consolidate adjacent buddies */
    int page_num = alloc_info->page_num;
    page_id_t page_id = page_idx_to_id(page_idx);
    int min_page_id = alloc_info->idx_2_id_adj;
    while (1) {
        page_id_t buddy_id = page_id ^ (1<<order);
        if (buddy_id < min_page_id)
            break;

        page_idx_t buddy_idx = page_id_to_idx(buddy_id);
        if (buddy_idx >= page_num ||
            pi[buddy_idx].order != order ||
            !is_page_leader(pi + buddy_idx) ||
            is_allocated_blk(pi + buddy_idx)) {
            break;
        }
        remove_free_block(buddy_idx, order, 0);
        reset_page_leader(alloc_info->page_info + buddy_idx);

        page_id = page_id < buddy_id ? page_id : buddy_id;
        order++;
    }

    add_free_block(page_id_to_idx(page_id), order);
    return 1;
}
Esempio n. 3
0
/*
 * realloc
 */
void *realloc(void *ptr, size_t size) {
    size_t oldsize;
    void *newptr;

    /* If size == 0 then this is just free, and we return NULL. */
    if(size == 0) {
        free(ptr);
        return 0;
    }

    /* If oldptr is NULL, then this is just malloc. */
    if(ptr == NULL) {
        return malloc(size);
    }
    oldsize=GET_SIZE(HDRP(ptr));
    size_t asize=(size+15)&(~0x7);
    if (asize==oldsize) {
        return ptr;
    }

    else if (asize<oldsize) {
        size_t free_size=oldsize-asize;
        if(free_size<16) {
            newptr=malloc(size);
            if(!newptr) {
                return 0;
            }
            memcpy(newptr,ptr,size);
            free(ptr);
            return newptr;
        }
        else {
            void *free_block=(void*)((char *)ptr+asize);
            alloc_block(ptr,asize);
            PUT(HDRP(free_block),PACK(free_size,0));
            PUT(FTRP(free_block),PACK(free_size,0));
            add_free_block(free_block);
            return ptr;
        }
    }
    else {
        newptr = malloc(size);

        /* If realloc() fails the original block is left untouched  */
        if(!newptr) {
            return 0;
        }

        /* Copy the old data. */
        // oldsize = GET_SIZE(HDRP(ptr));
        //  if(size < oldsize) oldsize = size;
        memcpy(newptr, ptr, oldsize);

        /* Free the old block. */
        free(ptr);
        return newptr;
    }
    return newptr;
}
Esempio n. 4
0
static void* coalesce(void *bp) //bp point to header
{
	//dbg_printf("coalesce %p\n",bp);
	void *prev_blk=PREV_BLKP(bp);
	void *next_blk=NEXT_BLKP(bp);
	size_t prev_alloc = GET_ALLOC(FTRP(prev_blk));
    size_t next_alloc = GET_ALLOC(HDRP(next_blk));
    size_t size = GET_SIZE(HDRP(bp));
	
    if (prev_alloc && next_alloc) {            /* Case 1 */
		
dbg_printf("no coal%p\n",bp);
add_free_block(bp,size);
		return bp;
    }

    else if (prev_alloc && !next_alloc) {      /* Case 2 */
		size += GET_SIZE(HDRP(next_blk));
		delete_free_block(next_blk);
		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_blk));
		delete_free_block(prev_blk);
		PUT(FTRP(bp), PACK(size, 0));
		PUT(HDRP(prev_blk), PACK(size, 0));
		bp = prev_blk;
    }

    else {                                     /* Case 4 */
		size += GET_SIZE(HDRP(prev_blk)) + 
	    GET_SIZE(FTRP(next_blk));
		delete_free_block(prev_blk);
		delete_free_block(next_blk);
		PUT(HDRP(prev_blk), PACK(size, 0));
		PUT(FTRP(next_blk), PACK(size, 0));
		bp = prev_blk;
   }

	add_free_block(bp,size);
    return bp;
	
}
Esempio n. 5
0
/**********************************************************
 * place
 * Mark the block as allocated.
 * Also create a new free block of the size difference if possible.
 **********************************************************/
void place(void* bp, size_t asize)
{
    remove_free_block(bp);
    /* Get the current block size */
    size_t bsize = GET_SIZE(HDRP(bp));

    // Create a block of the size difference and insert it into the free list.
    if (bsize - asize > 8*DSIZE) {
        PUT(HDRP(bp), PACK(asize, 1));
        PUT(FTRP(bp), PACK(asize, 1));
        PUT(HDRP(NEXT_BLKP(bp)), PACK(bsize-asize, 0));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(bsize-asize, 0));
        add_free_block(NEXT_BLKP(bp));
    } else {
        PUT(HDRP(bp), PACK(bsize, 1));
        PUT(FTRP(bp), PACK(bsize, 1));
    }
}
Esempio n. 6
0
/**********************************************************
 * extend_heap
 * Extend the heap by "words" words, maintaining alignment
 * requirements of course. Free the former epilogue block
 * and reallocate its new header
 **********************************************************/
void *extend_heap(size_t words)
{
    char *bp;
    size_t size;

    /* Allocate an even number of words to maintain alignments */
    size = (words % 2) ? (words+1) * WSIZE : words * WSIZE;
    if ( (bp = mem_sbrk(size)) == (void *)-1 )
        return NULL;

    logg(1, "extend_heap extends words: %zx(h)(size: %zx(h)); new bp: %p", words, size, bp);
    /* Initialize free block header/footer and the epilogue header */
    PUT(HDRP(bp), PACK(size, 0));                // free block header
    PUT(FTRP(bp), PACK(size, 0));                // free block footer
    PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1));        // new epilogue header
    add_free_block(bp);
    return bp;
}
Esempio n. 7
0
/* $begin coalesce */
static void *coalesce(void *bp) //bp point to header
{
	void *prev_block=prev_blkp(bp);
	void *next_block=next_blkp(bp);

    uint32_t prev_alloc = GET_ALLOC(prev_block);
    uint32_t next_alloc = GET_ALLOC(next_block);
    uint32_t size = GET_SIZE(bp);

    if (prev_alloc && next_alloc) {            /* Case 1 */
		return bp;
    }

    else if (prev_alloc && !next_alloc) {      /* Case 2 */
	size += GET_SIZE(next_block);
	delete_free_block(next_block);
	PUT(bp, PACK(size, 0));
	PUT(FTRP1(bp), PACK(size,0));
    }

    else if (!prev_alloc && next_alloc) {      /* Case 3 */
	size += GET_SIZE(prev_block);
	delete_free_block(prev_block);
	PUT(FTRP1(bp), PACK(size, 0));
	PUT(prev_block, PACK(size, 0));
	bp = prev_block;
    }

    else {                                     /* Case 4 */
	size += GET_SIZE(prev_block) + 
	    GET_SIZE(next_block);
	delete_free_block(prev_block);
	delete_free_block(next_block);

	PUT(prev_block, PACK(size, 0));
	PUT(FTRP1(next_block), PACK(size, 0));
	bp = prev_block;
    }

	add_free_block(bp);
	return bp;
	
}
Esempio n. 8
0
/**********************************************************
 * coalesce
 * 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
 **********************************************************/
void *coalesce(void *bp)
{
    logg(4, "============ coalesce() starts ==============");
    logg(1, "coalesce() called with bp: %p; Previous block: %p header: %zx; Next block: %p header: %zx", bp, PREV_BLKP(bp), GET(HDRP(PREV_BLKP(bp))), NEXT_BLKP(bp), GET(HDRP(NEXT_BLKP(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 */
        logg(2, "Case 1: Both prev and next blocks are allocated. NO coalescing.");
    }
    else if (prev_alloc && !next_alloc) { /* Case 2 */
        logg(2, "Case2: Next block is free.");
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        remove_free_block(NEXT_BLKP(bp));
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size, 0));
    }
    else if (!prev_alloc && next_alloc) { /* Case 3 */
        logg(2, "Case3: Prev block is free.");
        size += GET_SIZE(HDRP(PREV_BLKP(bp)));
        remove_free_block(PREV_BLKP(bp));
        bp = PREV_BLKP(bp);     // move bp one block ahead
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size, 0));
    }
    else {            /* Case 4 */
        logg(2, "Case4: Both blocks are free.");
        size += GET_SIZE(HDRP(PREV_BLKP(bp)))  + GET_SIZE(HDRP(NEXT_BLKP(bp)))  ;
        remove_free_block(NEXT_BLKP(bp));
        remove_free_block(PREV_BLKP(bp));
        bp = PREV_BLKP(bp);
        PUT(HDRP(bp), PACK(size,0));
        PUT(FTRP(bp), PACK(size,0));
    }

    // Add the bp block to the beginning of free list of corresponding size.
    add_free_block(bp);
    logg(4, "============ coalesce() ends ==============");
    return bp;
}
Esempio n. 9
0
static void place(void *bp, size_t asize){
	
	size_t osize=GET_SIZE(bp);
	size_t remain_size=osize-asize;

//	size_t old_predaddr=pred_blka(bp);
//	size_t old_succaddr=succ_blka(bp);

	void *remain_block=(char *)bp+asize;

	if (remain_size>=16){
		delete_free_block(bp);
		set_free_block(remain_block,remain_size,0);
		add_free_block(remain_block);
	}
	else{
		delete_free_block(bp);
	}
	alloc_block(bp,asize);
}
Esempio n. 10
0
static void* coalesce_ex(void *bp) //bp point to header
{
    dbg_printf("coalesce ex %p\n",bp);
    void *prev_blk=PREV_BLKP(bp);
    size_t prev_alloc = GET_ALLOC(FTRP(prev_blk));
    size_t size = GET_SIZE(HDRP(bp));

    if (prev_alloc ) {            /* Case 1 */
        add_free_block(bp);
        return bp;
    }

    else {      /* Case 3 */
        size += GET_SIZE(HDRP(prev_blk));
        //	delete_free_block(prev_blk);
        PUT(FTRP(bp), PACK(size, 0));
        PUT(HDRP(prev_blk), PACK(size, 0));
        bp = prev_blk;
    }
    //add_free_block(bp);
    return bp;

}
Esempio n. 11
0
/* Initialize the page allocator, return 1 on success, 0 otherwise. */
int
lm_init_page_alloc(lm_chunk_t* chunk, ljmm_opt_t* mm_opt) {
    if (!chunk) {
        /* Trunk is not yet allocated */
        return 0;
    }

    if (alloc_info) {
        /* This function was succesfully invoked before */
        return 1;
    }

    int page_num = chunk->page_num;
    if (unlikely(mm_opt != NULL)) {
        int pn = mm_opt->dbg_alloc_page_num;
        if (((pn > 0) && (pn > page_num)) || !pn)
            return 0;
        else if (pn > 0) {
            page_num = pn;
        }

        if (!bc_set_parameter(mm_opt->enable_block_cache,
                              mm_opt->blk_cache_in_page)) {
            return 0;
        }
    }

    int alloc_sz = sizeof(lm_alloc_t) +
                   sizeof(lm_page_t) * (page_num + 1);

    alloc_info = (lm_alloc_t*) MYMALLOC(alloc_sz);
    if (!alloc_info) {
        errno = ENOMEM;
        return 0;
    }

    alloc_info->first_page = chunk->base;
    alloc_info->page_num   = page_num;
    alloc_info->page_size  = chunk->page_size;
    alloc_info->page_size_log2 = log2_int32(chunk->page_size);

    /* Init the page-info */
    char* p =  (char*)(alloc_info + 1);
    int align = __alignof__(lm_page_t);
    p = (char*)((((intptr_t)p) + align - 1) & ~align);
    alloc_info->page_info = (lm_page_t*)p;

    int i;
    lm_page_t* pi = alloc_info->page_info;
    for (i = 0; i < page_num; i++) {
        pi[i].order = INVALID_ORDER;
        pi[i].flags = 0;
    }

    /* Init the buddy allocator */
    int e;
    rb_tree_t* free_blks = &alloc_info->free_blks[0];
    for (i = 0, e = MAX_ORDER; i < e; i++)
        rbt_init(&free_blks[i]);
    rbt_init(&alloc_info->alloc_blks);

    /* Determine the max order */
    int max_order = 0;
    unsigned int bitmask;
    for (bitmask = 0x80000000/*2G*/, max_order = 31;
         bitmask;
         bitmask >>= 1, max_order --) {
        if (bitmask & page_num)
            break;
    }
    alloc_info->max_order = max_order;

    /* So, the ID of biggest block's first page is "1 << order". e.g.
     * Suppose the chunk contains 11 pages, which will be divided into 3
     * blocks, eaching containing 1, 2 and 8 pages. The indices of these
     * blocks are 0, 1, 3 respectively, and their IDs are 5, 6, and 8
     * respectively. In this case:
     *    alloc_info->idx_2_id_adj == 5 == page_id(*) - page_idx(*)
     */
    int idx_2_id_adj = (1 << max_order) - (page_num & ((1 << max_order) - 1));
    alloc_info->idx_2_id_adj = idx_2_id_adj;

    /* Divide the chunk into blocks, smaller block first. Smaller blocks
     * are likely allocated and deallocated frequently. Therefore, they are
     * better off residing closer to data segment.
     */
    int page_idx = 0;
    int order = 0;
    for (bitmask = 1, order = 0;
         bitmask != 0;
         bitmask = bitmask << 1, order++) {
        if (page_num & bitmask) {
            add_free_block(page_idx, order);
            page_idx += (1 << order);
        }
    }

    /*init the block cache */
    bc_init();

    return 1;
}
Esempio n. 12
0
static void* coalesce_free(void *bp) //bp point to header
{
    dbg_printf("coalesce free %p\n",bp);
    void *prev_blk=PREV_BLKP(bp);
    void *next_blk=NEXT_BLKP(bp);
    size_t prev_alloc = GET_ALLOC(FTRP(prev_blk));
    size_t next_alloc = GET_ALLOC(HDRP(next_blk));
    size_t size = GET_SIZE(HDRP(bp));

    if (prev_alloc && next_alloc) {            /* Case 1 */
        add_free_block(bp);
        return bp;
    }

    else if (prev_alloc && !next_alloc) {      /* Case 2 */
        size += GET_SIZE(HDRP(next_blk));
        //delete_free_block(next_blk);
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size,0));
        size_t predoff=get_pred_offset(next_blk);
        size_t succoff=get_succ_offset(next_blk);
        set_pred(bp,predoff);
        set_succ(bp,succoff);
        if(predoff) {
            set_succ(get_addr(predoff),get_offset(bp));
        } else {
            free_list=bp;
        }
        if(succoff)
            set_pred(get_addr(succoff),get_offset(bp));

    }

    else if (!prev_alloc && next_alloc) {      /* Case 3 */
        size += GET_SIZE(HDRP(prev_blk));
        //	delete_free_block(prev_blk);
        PUT(FTRP(bp), PACK(size, 0));
        PUT(HDRP(prev_blk), PACK(size, 0));
        bp = prev_blk;
    }

    else {                                     /* Case 4 */
        size += GET_SIZE(HDRP(prev_blk)) +
                GET_SIZE(FTRP(next_blk));
//size_t predoff=get_pred_offset(prev_blk);
        size_t succoff=get_succ_offset(next_blk);
        //delete_free_block(prev_blk);
        //delete_free_block(next_blk);
        PUT(HDRP(prev_blk), PACK(size, 0));
        PUT(FTRP(next_blk), PACK(size, 0));
        bp = prev_blk;
        //set_pred(bp,predoff);
        set_succ(bp,succoff);
        //if(predoff){
        //set_succ(get_addr(predoff),get_offset(bp));
        //free_list=bp;
        //	}
        if(succoff)
            set_pred(get_addr(succoff),get_offset(bp));


    }

//	add_free_block(bp);
    return bp;

}