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; }
/* * 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. */ bp = PREV_FREEP(free_listp_head); while (bp != NULL) { if ((asize <= (size_t)GET_SIZE(HDRP(bp)))) { return bp; } bp = PREV_FREEP(bp); } // for (bp = free_listp_head; GET_ALLOC(HDRP(bp)) == 0; bp = PREV_FREEP(bp)) // { // if (asize <= (size_t)GET_SIZE(HDRP(bp))) // return bp; // } // 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 }
/* * 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 }
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_init - Initialize the memory manager * This function gets heap space and takes care of alignment by adding * padding and creating a dummy block to make sure the payload is aligned on a * 4-byte boundary. * The initial heap looks like this: |PADDING|DUMMY HEADER|DUMMY FOOTER|TAIL BLOCK| * PADDING = 4 bytes, DUMMY HEADER = DUMMY FOOTER = 8 bytes, TAIL BLOCK = 4 bytes * TAIL BLOCK signals the end of the heap => It signals the end of the free list. * * This function should return 0 if successful, -1 if failure. */ int mm_init(void) { int INITIAL_SIZE = DSIZE * (NUM_OF_LIST + 2); /*return -1 if unable to get heap space*/ if ((heap_listp = mem_sbrk(2*INITIAL_SIZE)) == NULL) return -1; PUT(heap_listp, 0); //Alignment padding /*initialize dummy block header*/ PUT(heap_listp + WSIZE, PACK(INITIAL_SIZE - DSIZE, 1)); //WSIZE = padding /*initialize dummy block footer*/ PUT(heap_listp + INITIAL_SIZE - DSIZE, PACK(INITIAL_SIZE - DSIZE, 1)); /*initialize dummy tail block*/ PUT(heap_listp + INITIAL_SIZE - WSIZE, PACK(0, 1)); /*initialize the free list pointer to the tail block*/ free_listp = heap_listp + 1 * DSIZE; for (int i = 1; i <= NUM_OF_LIST; i++) { PREV_FREEP(heap_listp + i * DSIZE) = NULL; } /*return -1 if unable to get heap space*/ if (extendHeap(CHUNKSIZE/WSIZE) == NULL) return -1; return 0; }
/* * 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; } }
/* * 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 *head; int offset; offset = get_seglist_no(asize); /* First fit search */ /* Iterates through free list to find a free block large enough to * accomodate the size we want to allocate. */ for (int i = offset; i <= NUM_OF_LIST; i++) { head = PREV_FREEP(heap_listp + i * DSIZE); while (head != NULL) { if ((asize <= (size_t)GET_SIZE(HDRP(head)))) { return head; } head = PREV_FREEP(head); } } return NULL; // No fit }
/* * 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; } }
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; }
//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; }