Exemple #1
0
/*
 * Place the block and potentially split the block
 * Return: Nothing
 */
static void place(void *block, unsigned int awords) {
    REQUIRES(awords >= 2 && awords % 2 == 0);
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));
    REQUIRES(in_list(block));

    unsigned int cwords = block_size(block); //the size of the given freeblock
    block_delete(block);      // delete block from the seg list
    
    ENSURES(!in_list(block));

    if ((cwords - awords) >= 4) {
        set_size(block, awords);
        block_mark(block, ALLOCATED);
        block = block_next(block);
        set_size(block, cwords - awords - 2);
        block_mark(block, FREE);
        block_insert(block);

        ENSURES(in_list(block));
    } else {
        set_size(block, cwords);
        block_mark(block, ALLOCATED);
    }    
 }
Exemple #2
0
/*
 * Merge block with adjacent free blocks
 * Return: the pointer to the new free block 
 */
static void *coalesce(void *block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    uint32_t *prev_block = block_prev(block);
    uint32_t *next_block = block_next(block);
    int prev_free = block_free(prev_block);
    int next_free = block_free(next_block);
    unsigned int words = block_size(block);
    

    if (prev_free && next_free) {       // Case 4, both free

        block_delete(prev_block);
        block_delete(next_block);

        words += block_size(prev_block) + block_size(next_block) + 4;
        set_size(prev_block, words);
        block_mark(prev_block, FREE);
        block = (void *)prev_block;

        block_insert(block);
        ENSURES(in_list(block));    
    }

    else if (!prev_free && next_free) { // Case 2, next if free

        block_delete(next_block);

        words += block_size(next_block) + 2;
        set_size(block, words);
        block_mark(block, FREE);  

        block_insert(block);
        ENSURES(in_list(block));      
    }

    else if (prev_free && !next_free) { // Case 3, prev is free
        block_delete(prev_block);

        words += block_size(prev_block) + 2;
        set_size(prev_block, words);
        block_mark(prev_block, FREE);
        block = (void *)prev_block;

        block_insert(block);
        ENSURES(in_list(block));
    }

    else {                              // Case 1, both unfree
        block_insert(block);
        ENSURES(in_list(block));
        return block;
    }
    return block;
 } 
Exemple #3
0
// Returns a pointer if block of sufficient size is available 
// will allocate a new block if none are free
static void* find_free_block(int index, size_t size){
    REQUIRES(0 <= index && index < NUM_FREE_LISTS);

    void* block;
    void* current;
    int new_index = index; 

    while(new_index < NUM_FREE_LISTS){
    	current = free_lists[new_index];

    	while(current != NULL){
    		if(block_size(current) >= size){
    			// if(new_index > index){
    			// 	block = split_block(new_index);
    			// 	block_mark(block, 0);
    			// 	return block;
    			// }
    			block = current;
    			block_mark(block, 0);
    			remove_block_from_list(new_index, block);
    		}
    		current = block_next(current);
    	}
        new_index++;
    }
    assert(aligned(block));
    block = allocate_block(size);

    ENSURES(block != NULL);
    return block;
}
Exemple #4
0
/*
 * free
 */
void free (void *ptr) {
    if (ptr == NULL) {
        return;
    }
    block_mark(get_header(ptr), 0);
    coalesce(ptr);
}
Exemple #5
0
/*
 * Extends the heap with a new free block
 * Return: the pointer to the new free block 
 *         NULL on error.
 */
static void *extend_heap(unsigned int words) {
    REQUIRES(words > 4);

    uint32_t *block;
    uint32_t *next;
    

    /* Ask for 2 more words for header and footer */
    words = (words % 2) ? (words + 1) : words;
    if (VERBOSE)
        printf("Extend Words = %d bytes\n", words * 4);
    if ((long)(block = mem_sbrk(words * WSIZE)) == -1)
        return NULL;

    block--;          // back step 1 since the last one is the epi block
    set_size(block, words - 2);
    block_mark(block, FREE);

    ENSURES(block != NULL);
    // New eqilogue block
    next = block_next(block);    
    set_size(next, 0);
    *next |= 0x40000000;
    //block_mark(block_next(block), ALLOCATED);

    ENSURES(!block_free(next));
    ENSURES(block_size(next) == 0);
    block = coalesce(block);    // Coalesce if necessary
    ENSURES(in_list(block));
    return block;
 }
Exemple #6
0
/*
 * free
 */
void free (void *ptr) {
    /* If ptr is NULL, no operation is performed. */    
    if (ptr == NULL)
        return;

    uint32_t* block = block_block(ptr);

    block_mark(block, FREE);
    coalesce(block);
}
Exemple #7
0
static void* allocate_block(size_t size){
    void* block;
    
    block = mem_sbrk(size);
    if(block == NULL) return NULL;
    set_size(block, size);
    set_prev_pointer(block, NULL);
    set_next_pointer(block, NULL);
    block_mark(block, 0);

    return block;
}
Exemple #8
0
/*
 * free
 */
void free (void *ptr) {
    size_t size;
    void* block;
    int index;

    checkheap(1);

    if (ptr == NULL) {
        return;
    }
    if(heap_start == 0)
                mm_init();
    block = block_from_ptr(ptr);
    index = coalesce(block, &size);

    block_mark(block, 1);
    //set_prev_pointer(block, NULL);
    //set_next_pointer(block, NULL);

    add_block_to_list(index, block);

    checkheap(1);
    return;    
}
Exemple #9
0
/*
 * Initialize: return -1 on error, 0 on success.
 */
int mm_init(void) {

    /* Initialize the seg_list with NULL */
    seg_list = mem_sbrk(SEG_LIST_SIZE * sizeof(uint32_t *));
    for (int i = 0; i < SEG_LIST_SIZE; ++i) {
        seg_list[i] = NULL;
    }

    if ((heap_listp = mem_sbrk(4 * WSIZE)) == (void *)-1)
        return -1;
    set_size(heap_listp, 0);                 // Allignment padding
    set_size(heap_listp + 1, 0);             // Pro of 0 size
    set_size(heap_listp + 3, 0);             // Epi of 0 size
    (heap_listp + 3)[0] |= 0x40000000;       // Mark epi as allocated
    block_mark(heap_listp + 1, ALLOCATED);   // Mark prologue as allocated

    heap_listp += 1;                            
    
    /* Extend the empty heap with a free block of CHUNKSIZE bytes 
     * extend_heap would ask for 2 more words */
    if (extend_heap(CHUNKSIZE + 2) == NULL)
        return -1;
    return 0;
}
Exemple #10
0
/*
 * realloc - you may want to look at mm-naive.c
 */
void *realloc(void *oldptr, size_t size) {
    if (oldptr == NULL)   // if oldptr is NULL, this works as malloc(size)
        return malloc(size);
    if (size == 0) {      // if size is 0, this works as free(oldptr)
        free(oldptr);
        return NULL;
    }

    uint32_t *block = block_block(oldptr);

    REQUIRES(in_heap(block));
    REQUIRES(!block_free(block));



    unsigned int words = block_size(block);  // old size in words
    unsigned int nwords;                      // new size in words
    uint32_t * ptr;                           // temp ptr

    /* Adjust size to include alignment and convert to multipes of 4 bytes */
    if (size <= DSIZE)
        nwords = 2;
    else
        nwords = (((size) + (DSIZE-1)) & ~0x7) / WSIZE;

    /* if new size is the same as old size or the old size is larger but no larger
     * than 4 words, return oldptr without spliting */
    //printf("RE, words = %d, nwords = %d\n", words, nwords);
    if (nwords == words || (words > nwords && words - nwords < 4))
        return oldptr;
    else if (nwords < words) {
        /* if old size is at least 4 words larger than new size
         * return oldptr with spliting */      
        set_size(block, nwords);
        block_mark(block, ALLOCATED);
        ptr = block_next(block);
        ENSURES(words - nwords - 2 < words);
        set_size(ptr, words - nwords - 2);
        block_mark(ptr, FREE);
        block_insert(ptr);
        return oldptr;
    } else {
        /* if old size is smaller than new size, look for more space */

        ptr = block_next(block);
        if (block_free(ptr)) {
            ENSURES(in_list(ptr));

            // if next block is free
            unsigned int owords = block_size(ptr);  //size of next blockdd
            int remain = owords + 2 - (nwords - words);
            if (remain >= 4) {
                // the next free block is enough large to split
                block_delete(ptr);
                set_size(block, nwords);
                block_mark(block, ALLOCATED);
                ptr = block_next(block);
                set_size(ptr, owords - (nwords - words));
                block_mark(ptr, FREE);
                block_insert(ptr);
                return oldptr;
            } else if (remain >= 0) {
                // the next free block can not split
                block_delete(ptr);
                set_size(block, words + owords + 2);
                block_mark(block, ALLOCATED);
                return oldptr;
            }
        } 
        /* the next free block is too small, or
         * next block is not free, malloc whole new one. */
        ptr = malloc(size);
        /* Copy the old data. */
        memcpy(ptr, oldptr, block_size(block) * WSIZE);
        /* Free the old block. */
        free(oldptr);
        return ptr;
    }
}