inline static void insert_free_block(void* bp) { #else static void insert_free_block(void* bp) { #endif /* get specific segregated free list */ size_t free_list_num = get_list_num(GET_SIZE(HDRP(bp))); dbg1("[IN ] : insert_free_block() : insert at tail\n"); if (GET_FREE_LISTP(free_list_num) != NULL) { /* if the list is not empty, insert at tail */ PUT8(NEXT_FREEP(GET_FREE_LISTP_T(free_list_num)), bp); PUT8(PREV_FREEP(bp), GET_FREE_LISTP_T(free_list_num)); } else { /* if list is empty, just setup pointers */ PUT8(FREE_LISTP(free_list_num), bp); PUT8(PREV_FREEP(bp), NULL); } /* update tail pointer */ PUT8(NEXT_FREEP(bp), NULL); PUT8(FREE_LISTP_T(free_list_num), bp); dbg1("[OUT] : insert_free_block()\n"); return; }
static void mm_remove(void *bp){ if(PREV_FREEP(bp) != NULL){ NEXT_FREEP(PREV_FREEP(bp)) = NEXT_FREEP(bp); }else{ head = NEXT_FREEP(bp); } PREV_FREEP(NEXT_FREEP(bp)) = PREV_FREEP(bp); }
/* * removeBlock - Removes a block from the free list * This function takes a block pointer of the block to remove as a * parameter. */ static void removeBlock(void *bp) { /* If there's a previous block, set its next pointer to the * next block. * If not, set the block's previous pointer to the prev block. */ if (PREV_FREEP(bp)) NEXT_FREEP(PREV_FREEP(bp)) = NEXT_FREEP(bp); else free_listp = NEXT_FREEP(bp); PREV_FREEP(NEXT_FREEP(bp)) = PREV_FREEP(bp); }
/* * printBlock - Prints the details of a block in the list. * This function displays previous and next pointers if the block * is marked as free. * * This function takes a block pointer (to a block for examination) as a * parameter. */ static void printBlock(void *bp) { int hsize, halloc, fsize, falloc; /* Basic header and footer information */ 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; } /* Prints out header and footer info if it's an allocated block. * Prints out header and footer info and next and prev info * if it's a free block. */ if (halloc) printf("%p: header:[%d:%c] footer:[%d:%c]\n", bp, hsize, (halloc ? 'a' : 'f'), fsize, (falloc ? 'a' : 'f')); else printf("%p:header:[%d:%c] prev:%p next:%p footer:[%d:%c]\n", bp, hsize, (halloc ? 'a' : 'f'), PREV_FREEP(bp), NEXT_FREEP(bp), fsize, (falloc ? 'a' : 'f')); }
/* * mm_checkheap - Check the heap for consistency * Checks the epilogue and prologue blocks for size and allocation bit. * Checks the 8-byte address alignment for each block in the free list. * Checks each free block to see if its next and previous pointers are * within heap bounds. * Checks the consistency of header and footer size and allocation bits * for each free block. */ void mm_checkheap(int verbose) { void *bp = heap_listp; //Points to the first block in the heap if (verbose) printf("Heap (%p):\n", heap_listp); /* If first block's header's size or allocation bit is wrong, * the prologue header is wrong */ if ((GET_SIZE(HDRP(heap_listp)) != MINIMUM) || !GET_ALLOC(HDRP(heap_listp))) printf("Bad prologue header\n"); checkBlock(heap_listp); // /* Print the stats of every free block in the free list */ for (bp = free_listp; GET_ALLOC(HDRP(bp))==0; bp = NEXT_FREEP(bp)) { if (verbose) printBlock(bp); checkBlock(bp); } /* Print the stats of the last block in the heap */ if (verbose) printBlock(bp); /* If last block's header's size or allocation bit is wrong, * the epilogue's header is wrong */ if ((GET_SIZE(HDRP(bp)) != 0) || !(GET_ALLOC(HDRP(bp)))) printf("Bad epilogue header\n"); }
/* * insertAtFront - Inserts a block at the front of the free list * This function takes a block pointer of the block to add to the * free list as a parameter. */ static void insertAtFront(void *bp) { NEXT_FREEP(bp) = free_listp; //Sets next ptr to start of free list PREV_FREEP(free_listp) = bp; //Sets current's prev to new block PREV_FREEP(bp) = NULL; // Sets prev pointer to NULL free_listp = bp; // Sets start of free list as new block }
/* * checkBlock - Checks a block for consistency * Checks prev and next pointers to see if they are within heap boundaries. * Checks for 8-byte alignment. * Checks header and footer for consistency. * * This function takes a block pointer (to a block for examinination) as a * parameter. */ static void checkBlock(void *bp) { // Reports if the next and prev pointers are within heap bounds if (NEXT_FREEP(bp)< mem_heap_lo() || NEXT_FREEP(bp) > mem_heap_hi()) printf("Error: next pointer %p is not within heap bounds \n" , NEXT_FREEP(bp)); if (PREV_FREEP(bp)< mem_heap_lo() || PREV_FREEP(bp) > mem_heap_hi()) printf("Error: prev pointer %p is not within heap bounds \n" , PREV_FREEP(bp)); /* Reports if there isn't 8-byte alignment by checking if the block pointer * is divisible by 8. */ if ((size_t)bp % 8) printf("Error: %p is not doubleword aligned\n", bp); // Reports if the header information does not match the footer information if (GET(HDRP(bp)) != GET(FTRP(bp))) printf("Error: header does not match footer\n"); }
/* * removeBlock - Removes a block from the free list * This function takes a block pointer of the block to remove as a * parameter. */ static void removeBlock(void *bp) { /* If there's a previous block, set its next pointer to the * next block. * If not, set the block's previous pointer to the prev block. */ if (bp == NULL) { return; } if (PREV_FREEP(bp)){ PREV_FREEP(NEXT_FREEP(bp)) = PREV_FREEP(bp); NEXT_FREEP(PREV_FREEP(bp)) = NEXT_FREEP(bp); } else { PREV_FREEP(NEXT_FREEP(bp)) = NULL; NEXT_FREEP(bp) = NULL; } }
static void *find_fit(size_t size){ void *bp; for(bp = head; GET_ALLOC(HDRP(bp)) == 0; bp = NEXT_FREEP(bp)){ if(size <= GET_SIZE(HDRP(bp))){ return bp; } } return NULL; }
/* * insertAtFront - Inserts a block at the front of the free list * This function takes a block pointer of the block to add to the * free list as a parameter. */ static void insertAtFront(void *bp) { if (bp == NULL) { return; } int offset = get_seglist_no(GET_SIZE(HDRP(bp))); void *free_list = heap_listp + offset * DSIZE; void *head = PREV_FREEP(free_list); if (head == NULL) { PREV_FREEP(free_list) = bp; NEXT_FREEP(bp) = free_list; PREV_FREEP(bp) = NULL; return; }else{ PREV_FREEP(free_list) = bp; NEXT_FREEP(bp) = free_list; PREV_FREEP(bp) = head; NEXT_FREEP(head) = bp; return; } }
/* * findFit - Find a fit for a block with asize bytes * This function iterates through the free list and uses a first-fit search * to find the first free block with size greater than or equal to the requested block size * * This function takes the requested block size, asize, as a parameter * and returns a pointer to the free block we wish to use for allocation. */ static void *findFit(size_t asize) { void *bp; /* First fit search */ /* Iterates through free list to find a free block large enough to * accomodate the size we want to allocate. */ for (bp = free_listp; GET_ALLOC(HDRP(bp)) == 0; bp = NEXT_FREEP(bp)) { if (asize <= (size_t)GET_SIZE(HDRP(bp))) return bp; } return NULL; // No fit }
inline static void remove_free_block(void* bp) { #else static void remove_free_block(void* bp) { #endif /* get specific segregated free list */ size_t free_list_num = get_list_num(GET_SIZE(HDRP(bp))); dbg1("[IN ] : remove_free_block()\n"); /* remove block */ if ((void*)NEXT_FREE_BLKP(bp) == NULL) { /* if next pointer is null */ if ((void*)PREV_FREE_BLKP(bp) == NULL) { /* if prev pointer is null, make list empty */ PUT8(FREE_LISTP(free_list_num), NULL); PUT8(FREE_LISTP_T(free_list_num), NULL); dbg1("[OUT] : remove_free_block() : list is empty\n"); return; } /* remove from tail */ PUT8(NEXT_FREEP(PREV_FREE_BLKP(bp)), NULL); PUT8(FREE_LISTP_T(free_list_num), PREV_FREE_BLKP(bp)); } else if ((void*)PREV_FREE_BLKP(bp) == NULL) { /* if prev pointer is null, remove from head */ PUT8(FREE_LISTP(free_list_num), NEXT_FREE_BLKP(bp)); PUT8(PREV_FREEP(GET_FREE_LISTP(free_list_num)), NULL); } else { /* just remove from middle of list */ PUT8(PREV_FREEP(NEXT_FREE_BLKP(bp)), PREV_FREE_BLKP(bp)); PUT8(NEXT_FREEP(PREV_FREE_BLKP(bp)), NEXT_FREE_BLKP(bp)); } dbg1("[OUT] : remove_free_block()\n"); }
/* * insertAtFront - Inserts a block at the front of the free list * This function takes a block pointer of the block to add to the * free list as a parameter. */ static void insertAtFront(void *bp) { void *searchp; searchp = free_listp; if (bp > searchp) { NEXT_FREEP(bp) = free_listp; //Sets next ptr to start of free list PREV_FREEP(free_listp) = bp; //Sets current's prev to new block PREV_FREEP(bp) = NULL; // Sets prev pointer to NULL free_listp = bp; // Sets start of free list as new block return; } searchp = NEXT_FREEP(searchp); while (GET_ALLOC(HDRP(searchp)) == 0) { if (bp > searchp) { NEXT_FREEP(PREV_FREEP(searchp)) = bp; PREV_FREEP(bp) = PREV_FREEP(searchp); PREV_FREEP(searchp) = bp; NEXT_FREEP(bp) = searchp; return; } else { searchp = NEXT_FREEP(searchp); } } NEXT_FREEP(PREV_FREEP(free_listp_head)) = bp; PREV_FREEP(bp) = PREV_FREEP(free_listp_head); PREV_FREEP(free_listp_head) = bp; NEXT_FREEP(bp) = free_listp_head; return; }
/********************************************************** * mm_check * Check the consistency of the memory heap * Return nonzero if the heap is consistant. * Checks: * -If the alloc bit and size are same in both header and footer * -If the total free and allocated blocks add up to the heap size * -If adjacent free blocks might have skipped coalescing * -If all the free blocks are in the free list * -If a free block is marked correctly * -Check if block is valid heap address *********************************************************/ int mm_check(void){ if (heap_listp == NULL) { //heap has not been initialized return 1; } void *traverse = NEXT_BLKP(heap_listp); //traverse heap void *traverse_free; //traverse free list int heap_size_counter, heap_size; heap_size_counter = 2*WSIZE; if (GET_SIZE(HDRP(traverse)) == 0) { //no memory has been allocated so far return 1; } while (GET_SIZE(HDRP(traverse)) != 0) { if (GET_SIZE(HDRP(traverse)) != GET_SIZE(FTRP(traverse))) { //check if the size indicated by header is the same as footer printf ("Error: Size indicated by header does not equal to size indicated by footer\n"); printf("%p\n", traverse); return 0; } if (GET_ALLOC(HDRP(traverse)) != GET_ALLOC(FTRP(traverse))) { //check if the alloc bit indicated by header is the same as footer printf ("Error: Alloc bit indicated by the header does not equal to alloc bit indicated by footer\n"); printf("%p\n", traverse); return 0; } if (GET_ALLOC(HDRP(traverse)) == 0 && GET_ALLOC(HDRP(NEXT_BLKP(traverse))) == 0) { // check if there exists two adjacent free blocks not coalesced printf("Error: two adjacent free blocks not coalesced\n"); printf("%p\n", traverse); return 0; } if (( ((void *)NEXT_BLKP(traverse)-WSIZE) > mem_heap_hi()) || ((traverse + WSIZE) < mem_heap_lo())) { printf("Error: block is not valid heap memory\n"); printf("%p\n", traverse); return 0; } if (GET_ALLOC(HDRP(traverse)) == 0) { // check if this free block is in the free list int found_free = 0; traverse_free = free_listp; while (traverse_free != NULL) { if (traverse_free == traverse) { found_free = 1; break; } traverse_free = NEXT_FREEP(traverse_free); } if (found_free == 0) { printf("Error: free block not in free list\n"); return 0; } } heap_size_counter += GET_SIZE(HDRP(traverse)); traverse = NEXT_BLKP(traverse); } heap_size = mem_sbrk(0) - heap_listp; if (heap_size_counter != heap_size) { printf ("Error: heap size counter does not match total heap size\n"); return 0; } //Check if every free block is marked as free traverse = free_listp; while (traverse != NULL){ if (GET_ALLOC(HDRP(traverse)) != 0 || GET_ALLOC(FTRP(traverse)) != 0) { printf ("Error: free blocks not marked as free\n"); printf("%p\n", traverse); return 0; } traverse = NEXT_FREEP(traverse); } return 1; }
//I inserted the new block at the beginning of the free list static void mm_insert(void *bp){ NEXT_FREEP(bp) = head; PREV_FREEP(head) = bp; PREV_FREEP(bp) = NULL; head = bp; }