示例#1
0
/*
 * add_block - add a block to the list in order of address
 */
static void add_block(void *bp) {
    int list = get_list(GET_SIZE(HDRP(bp)));
    void *next = free_lists[list];

    while (next != LIST_END) {
        /* Insert bp in middle of list, or beginning if prev(next) is NULL */
        if (next > bp) {
            if (GET_PREV_FREE(next) == LIST_END)
                free_lists[list] = bp; /* Update list head */
            else
                SET_NEXT_FREE(GET_PREV_FREE(next), bp);
            SET_PREV_FREE(bp, GET_PREV_FREE(next));
            SET_PREV_FREE(next, bp);
            SET_NEXT_FREE(bp, next);    
            return;
        /* Reached end of list, add bp to the end using saved block */
        } else if (GET_NEXT_FREE(next) == LIST_END) {
            SET_PREV_FREE(bp, next);
            SET_NEXT_FREE(next, bp);
            SET_NEXT_FREE(bp, LIST_END); 
            return;
        } 
        next = GET_NEXT_FREE(next);
    }

    /* Edge case: list is empty, add bp */
    SET_PREV_FREE(bp, LIST_END);
    SET_NEXT_FREE(bp, LIST_END);
    free_lists[list] = bp;
}
示例#2
0
/*Removes the free block pointer int the free_list*/
static void removeFromFree(void *bp){
  if (GET_PREV_FREE(bp))
    SET_NEXT_FREE(GET_PREV_FREE(bp), GET_NEXT_FREE(bp));
  else
    free_listp = GET_NEXT_FREE(bp);
  SET_PREV_FREE(GET_NEXT_FREE(bp), GET_PREV_FREE(bp));
}
static void delete_free_block(void *ptr)
{
    void *next_free = GET_NEXT_FREE(ptr);
    void *prev_free = GET_PREV_FREE(ptr);

    if (ptr == free_headp && ptr == free_tailp)
    {
        free_headp = NULL;
        free_tailp = NULL;
    }
    else if (ptr == free_headp)
    {
        free_headp = next_free;
        PUT_PREV_FREE(free_headp, NULL);
    }
    else if (ptr == free_tailp)
    {
        free_tailp = prev_free;
        PUT_NEXT_FREE(free_tailp, NULL);
    }
    else
    {
        PUT_NEXT_FREE(prev_free, next_free);
        PUT_PREV_FREE(next_free, prev_free);
    }
}
示例#4
0
/*
 * delete_block - delete a block from the free list
 */
static void delete_block(void *bp) {
    void *prev = GET_PREV_FREE(bp);
    void *next = GET_NEXT_FREE(bp);

    int list = get_list(GET_SIZE(HDRP(bp)));

    /* Case 1: bp is the only block in list */
    if ((prev == LIST_END) && (next == LIST_END)) {
        free_lists[list] = NULL;
        return;
    /* Case 2: bp is the first block in the list */
    } else if (prev == LIST_END) {
        SET_PREV_FREE(next, LIST_END);
        free_lists[list] = next;
        return;
    /* Case 3: bp is the last block in the list */
    } else if (next == LIST_END) {
        SET_NEXT_FREE(prev, LIST_END);
        return;
    /* Case 4: bp is in the middle of the list */
    } else {
        SET_NEXT_FREE(prev, next);
        SET_PREV_FREE(next, prev);
        return;
    }
}
示例#5
0
static void *find_fit(size_t asize){
  void *bp;

  for (bp = free_listp; GET_ALLOC(HDRP(bp)) == 0; bp = GET_NEXT_FREE(bp) ){
    if (asize <= (size_t)GET_SIZE(HDRP(bp)) ) {
      return bp;
    }
    
  }
  return NULL;
}
示例#6
0
/*
 * search_list - search the free list for a block of at least asize
 */
static void *search_list(size_t asize) {
    /* root of free list */
    void* bp = free_list;

    /* traverse the free list */
    while (bp != NULL) {
        if (GET_SIZE(HDRP(bp)) >= asize)
            return split(bp, asize); 
        bp = GET_NEXT_FREE(bp); 
    }
    /* No free block found */
    return NULL;
}
static void *find_fit(size_t size)
{
    void * ptr = free_headp;
    while (ptr)
    {
        size_t bsize = GET_SIZE(HDRP(ptr));
        mm_log("considering %p (%d)\n", ptr, (int)bsize);
        if (bsize >= size)
            return ptr;
        
        ptr = GET_NEXT_FREE(ptr);
    }
    return NULL;
}
示例#8
0
/*
 * search_list - search the free list for a block of at least asize
 */
static void *search_list(size_t asize) {
    /* root of smallest free list that fits asize */
    int list = get_list(asize);
    void *bp = free_lists[list];

    /* cycle through all lists with bucket size >= query size */
    while (list < NUM_LISTS+1) {
        while (bp != NULL) {
            if (GET_SIZE(HDRP(bp)) >= asize)
                return split(bp, asize); 
            bp = GET_NEXT_FREE(bp); 
        }
        bp = free_lists[list++];
    }
    /* No free block found */
    return NULL;
}
/*
 * mm_check - TODO
 */
static int mm_check()
{    
    /* Check that the blocks are properly organized & that epilogue is present */
    void *ptr = heap_listp;
    int prev_alloced;
    int freecount = 0;
    while (ptr < mem_heap_hi())
    {
        size_t size = GET_SIZE(HDRP(ptr));
        size_t size2 = GET_SIZE(FTRP(ptr));
        int allocated = GET_ALLOC(HDRP(ptr));
        int allocated2 = GET_ALLOC(FTRP(ptr));

        if (size == 0)
        {
            if (ptr != mem_heap_hi() - WSIZE)
            {
                mm_log("mm_check error: ran into size 0 (epilogue) at %p, which is not heap_hi().\n",ptr);
                return -1;
            }
            if (!allocated)
            {
                mm_log("mm_check error: epilogue at %p is marked as free\n",ptr);
                return -1;
            }
        }

        if (size != size2)
        {
            mm_log("mm_check error: %p size in header %d != footer %d\n", ptr, (int)size, (int)size2);
            return -1;
        }

        if (allocated != allocated2)
        {
            mm_log("mm_check error: %p alloc in header %d != footer %d\n", ptr, allocated, allocated2);
            return -1;
        }


        if (!allocated && !prev_alloced)
        {
            mm_log("mm_check error: two contiguous free blocks that should be coalesced. %p and prev.\n",ptr);
        }

        if (allocated)
        {
            //mm_log("block %p (%d,%d)\n", ptr, (int)size, allocated);
        }
        else
        {
            mm_log("block %p (%d,%d). prev=%p next=%p\n", ptr, (int)size, allocated, GET_PREV_FREE(ptr), GET_NEXT_FREE(ptr));
            freecount++;
        }

        prev_alloced = allocated;
        ptr += size;
    }

    /* Check the free list */
    int count = 0;
    ptr = free_headp;
    void *prev = NULL;
    while (ptr != NULL)
    {
        count++;
        size_t bsize = GET_SIZE(HDRP(ptr));

        if (GET_NEXT_FREE(ptr) && GET_PREV_FREE(GET_NEXT_FREE(ptr)) != ptr)
        {
            mm_log("mm_check error: prev of next of %p is %p\n", ptr, GET_PREV_FREE(GET_NEXT_FREE(ptr)));
            return -1;
        }

        if (GET_PREV_FREE(ptr) && GET_NEXT_FREE(GET_PREV_FREE(ptr)) != ptr)
        {
            mm_log("mm_check error: next of prev of %p is %p\n", ptr, GET_NEXT_FREE(GET_PREV_FREE(ptr)));
            return -1;
        }

        if (bsize == 0)
        {
            mm_log("mm_check error: block size 0 at %p\n", ptr);
            return -1;
        }
        if (GET_ALLOC(HDRP(ptr)) || GET_ALLOC(FTRP(ptr)))
        {
            mm_log("mm_check error: block at %p on the freelist is marked allocated\n", ptr);
            return -1;
        }
        if (GET_PREV_FREE(ptr) != prev)
        {
            mm_log("mm_check error: block at %p does not point to prev %p (points to %p)\n", ptr, prev, GET_PREV_FREE(ptr));
            return -1;
        }

        prev = ptr;
        ptr = GET_NEXT_FREE(ptr);
    }

    if (prev != free_tailp)
    {
        mm_log("mm_check error: last free block (%p) should == free_tailp (%p)\n", prev, free_tailp);
        return -1;
    }

    if (freecount != count)
    {
        mm_log("mm_check error: found %d free blocks, but only %d on the freelist.\n",freecount, count);
        return -1;
    }

    mm_log("mm_check says %d free block(s)\n",count);

    return 0;
}
示例#10
0
/* 
 * mm_checkheap - Check the heap for correctness. It prints a nice grid
 *                representation of the heap at the moment in time it is
 *                called, as well as the block pointer and epilogue
 *                pointer. It takes __LINE__ as input, allowing it to print
 *                the number of the line it is called at. It also silently
 *                checks for errors and exits the program if any error
 *                is found. If silent is 0, it will only print the results
 *                upon finding an error.
 *
 *                NOTE: if mm_checkheap is called ANYWHERE besides malloc and
 *                free, it will find errors because of intermediate states
 *                that trigger error conditions. Therefore error_check should
 *                be 0 if you call it anywhere besides inside malloc and free.
 */
void mm_checkheap(int lineno)  
{ 
    char *bp;
    char alloc_char;
    char aligned;
    char hef;
    int payload;
    int size;
    int num_head = 0, num_tail = 0;
    int link_error_flag = 0;
    int alignment_flag = 0;
    int error_flag = 0;
    int error_check = 1; /* set to 0 if called outside malloc() and free() */
    int silent = 1;

    /* Silently check for errors */
    if (error_check) {
        for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
            if (!ALIGNED(bp))
                alignment_flag = 1;

            if (!GET_ALLOC(HDRP(bp))) {
                /* Check for linked list errors in free blocks */
                if (GET_NEXT_FREE(bp) == NULL)
                    num_tail++;
                else if (GET_PREV_FREE(GET_NEXT_FREE(bp)) != bp)
                    link_error_flag = 1;    
                if (GET_PREV_FREE(bp) == NULL)
                    num_head++;
                else if (GET_NEXT_FREE(GET_PREV_FREE(bp)) != bp)
                    link_error_flag = 1;
            }
            if (num_tail > 1||num_head > 1||link_error_flag||alignment_flag)
                error_flag = 1;
        }
    }

    if (error_flag || !silent) {
        printf("\n");
        printf("========================================"
            "==========================================\n");
        printf("                            HEAP CONSISTENCY CHECKER\n");
        printf("========================================"
            "==========================================\n");
        printf("Line number = %d\n", lineno);
        printf("Head of free list = %p\n",free_list);
        printf("Epilogue pointer  = %p\n", eptr);
        printf("----------------------------------------"
            "-----------------------------------------\n");
        printf("T |  Block pointer   | Size  |Payload|"
            "       Prev       |       Next       |A|HEF\n"); 
        printf("--|------------------|-------|-------|--"
            "----------------|------------------|-|---\n");

        for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
           payload = FTRP(bp)-bp;
           size = GET_SIZE(HDRP(bp));
           alloc_char = ALLOC_CHAR(HDRP(bp));
           aligned = ALIGNED_CHAR(bp); /* Check for alignment */
           hef = HEF(bp); /* Check that header = footer */
           if (GET_ALLOC(HDRP(bp))) {
               printf("%c |%18p|%7d|%7d|%18s|%18s|%c| %c \n",
                   alloc_char,
                   bp,
                   size,
                   payload,
                   "",
                   "",
                   aligned,
                   hef);
           } else {
               printf("%c |%18p|%7d|%7d|%18p|%18p|%c| %c \n",
                   alloc_char,
                   bp,
                   size,
                   payload,
                   GET_PREV_FREE(bp),
                   GET_NEXT_FREE(bp),
                   aligned,
                   hef);
          }
        }
        printf("----------------------------------------"
            "-----------------------------------------\n");
        printf("Key: T = (a)llocated or (f)ree. A = aligned to double word."
            " HEF = H/F tags match.\n");

        /* If there is a problem with the free list, print details and exit. */
        if (error_flag) {
            printf("----------------------------------------"
                "-----------------------------------------\n");
            printf("Heap integrity errors found:\n"); 
            if (num_tail > 1)
                printf("    [List error] More than one list tail.\n");
            if (num_head > 1)
                printf("    [List error] More than one list head.\n");
            if (link_error_flag)
                printf("    [List error] Links don't match up in "
                    "at least one block.\n"); 
            if (alignment_flag)
                printf("    [Alignment error] Unaligned block detected.\n");
            printf("----------------------------------------"
                "-----------------------------------------\n");
            printf("\n");
            exit(0);
        }  
    }
}