diff --git a/mm.c b/mm.c index 5fa877b..da69789 100644 --- a/mm.c +++ b/mm.c @@ -52,7 +52,7 @@ static size_t list_sizes[NUM_LISTS]; /* Function prototypes for internal helper routines */ static struct block *extend_heap(size_t words, int realloc); static void place(struct block *blck, size_t asize); -static struct list* find_list(size_t size); +static struct list* find_list(int not_empty, size_t size); static struct block *find_fit(size_t num_words); //~ static void coalesce_free_lists(); static struct block *coalesce(struct block *bp); @@ -196,7 +196,7 @@ void mm_free(void *bp) set_block_free(blk, size); - list_push_front(find_list(size), &blk->elem); + list_push_front(find_list(0, size), &blk->elem); coalesce(blk); } @@ -255,30 +255,31 @@ static struct block *coalesce(struct block *bp) else if (prev_alloc && !next_alloc) { /* Case 2 */ // combine this block and next block by extending it list_remove(&bp->elem); - set_block_free(bp, size + blk_size(next_blk(bp))); list_remove(&next_blk(bp)->elem); - list_push_front(find_list(size + blk_size(next_blk(bp))), &bp->elem); + size_t new_size = size + blk_size(next_blk(bp)); + set_block_free(bp, new_size); + list_push_front(find_list(0, new_size), &bp->elem); } else if (!prev_alloc && next_alloc) { /* Case 3 */ // combine previous and this block by extending previous + list_remove(&prev_blk(bp)->elem); list_remove(&bp->elem); + size_t new_size = blk_size(prev_blk(bp)) + size; bp = prev_blk(bp); - set_block_free(bp, size + blk_size(bp)); - list_remove(&bp->elem); - list_push_front(find_list(size + blk_size(next_blk(bp))), &bp->elem); - + set_block_free(bp, new_size); + list_push_front(find_list(0, new_size), &bp->elem); } else { /* Case 4 */ // combine all previous, this, and next block into one - list_remove(&bp->elem); - set_block_free(prev_blk(bp), - size + blk_size(next_blk(bp)) + blk_size(prev_blk(bp))); - bp = prev_blk(bp); + list_remove(&prev_blk(bp)->elem); list_remove(&bp->elem); list_remove(&next_blk(bp)->elem); - list_push_front(find_list(size + blk_size(next_blk(bp))), &bp->elem); + size_t new_size = blk_size(prev_blk(bp)) + size + blk_size(next_blk(bp)); + bp = prev_blk(bp); + set_block_free(bp, new_size); + list_push_front(find_list(0, new_size), &bp->elem); } return bp; } @@ -302,7 +303,7 @@ static struct block *extend_heap(size_t words, int realloc) if (realloc) { return blk; } - list_push_front(find_list(words), &blk->elem); + list_push_front(find_list(0, words), &blk->elem); return coalesce(blk); @@ -326,7 +327,7 @@ static void place(struct block *blck, size_t asize) { set_block_free(blck, remaining_size); /* Add remaining free block back into list */ - list_push_front(find_list(remaining_size), &blck->elem); + list_push_front(find_list(0, remaining_size), &blck->elem); } else { set_block_used(blck, csize); @@ -335,12 +336,15 @@ static void place(struct block *blck, size_t asize) { /** * Find free list with blocks of given size + * + * not_empty == 0, find "any" list + * not_empty == 1, find a not empty list */ -static struct list* find_list(size_t n_words) { +static struct list* find_list(int not_empty, size_t n_words) { for (int i = 0; i < NUM_LISTS; i++) { if ((n_words < list_sizes[i]) || (i == (NUM_LISTS - 1))) { - if (list_empty(&free_lists[i])) { + if (not_empty && list_empty(&free_lists[i])) { continue; } return &free_lists[i]; @@ -354,7 +358,7 @@ static struct list* find_list(size_t n_words) { */ static struct block *find_fit(size_t num_words) { - struct list* free_list = find_list(num_words); + struct list* free_list = find_list(1, num_words); if (free_list == NULL) { return NULL;