diff --git a/mm.c b/mm.c index 7b81d04..5d6ff7c 100644 --- a/mm.c +++ b/mm.c @@ -1,3 +1,24 @@ +/* + * mm.c - Dynamic Memory Allocator + * + * This is a segregated free list implementation with multiple + * lists to hold different block sizes. The size ranges for our 8 lists * are powers of 2, with + * the smallest size on the lower bound being 8 words, + * + * A seperate list is used to store the sizes, and is checked when a + * free block is added to a list. + * + * Both allocated and free blocks are stored in the heap + * with the pointer heap_listp. + * Each block has a header and a footer, which + * store the size in 31 bits, and 1 bit for determining whether it is + * free. + * + * Blocks have a payload which holds hold necessary data and a list_elem struct so blocks can be stored in lists + */ + + + #include #include #include @@ -211,8 +232,9 @@ void mm_free(void *bp) //~ } void *mm_realloc(void *ptr, size_t size) { - void *new_ptr = NULL; - + size_t bytesize; + void *new_ptr; + if (ptr == NULL) { return mm_malloc(size); } @@ -223,20 +245,55 @@ void *mm_realloc(void *ptr, size_t size) { } struct block *oldblock = ptr - offsetof(struct block, payload); - size_t oldwords = blk_size(oldblock); - size_t oldsize = oldwords * WSIZE; + bool prev_alloc = prev_blk_footer(oldblock)->inuse; + bool next_alloc = !blk_free(next_blk(oldblock)); - if (!(new_ptr = mm_malloc(size))) { - return NULL; + if (!next_alloc) + { + struct block *right; + right = next_blk(oldblock); + list_remove(&right->elem); + set_block_used(oldblock, blk_size(oldblock) + blk_size(next_blk(oldblock))); } - if (size < oldsize) { - oldsize = size; - } - memcpy(new_ptr, ptr, oldsize); - mm_free(ptr); + + if (blk_size(oldblock) >= size) { + return oldblock->payload; + } + if (!prev_alloc) + { + struct block *left; + left = prev_blk(oldblock); + list_remove(&left->elem); + set_block_used(left, blk_size(oldblock) + blk_size(left)); + oldblock = left; + } + + + if (blk_size(oldblock) >= size) + { + bytesize = blk_size(oldblock) * WSIZE; + if(size < bytesize) bytesize = size; + memcpy(oldblock->payload, ptr, bytesize); + return oldblock->payload; + } + + + new_ptr = mm_malloc(size); + + + if(!new_ptr) return 0; + + + struct block *copyblk = ptr - offsetof(struct block, payload); + bytesize = blk_size(copyblk) * WSIZE; //find number of BYTES, not words + if(size < bytesize) bytesize = size; + memcpy(new_ptr, ptr, bytesize); + + + mm_free(oldblock->payload); + return new_ptr; - } static struct block *coalesce(struct block *bp)