diff --git a/mm.c b/mm.c index 53f7e3a..66d87e1 100644 --- a/mm.c +++ b/mm.c @@ -34,6 +34,7 @@ team_t team = { /* Second member's email address (leave blank if none) */ "tuan-dat.tran@stud.uni-due.de" }; + //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// STRUCTURE ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -43,7 +44,7 @@ team_t team = { // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // HEADER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// BODY | ALLOCED MEMORY | +// BP-> | ALLOCED MEMORY | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // FOOTER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ @@ -53,11 +54,11 @@ team_t team = { // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // HEADER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | PTR TO PREV FREE BLK | +// BP-> | PTR TO PREV FREE BLK | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // | PTR TO NEXT FREE BLK | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// BODY | UNALLOC MEMORY | +// | UNALLOC MEMORY | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // FOOTER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ @@ -80,6 +81,7 @@ team_t team = { #define CHUNKSIZE (1<<12) /* Extend heap by this amount (bytes) */ #define MAX(x, y) ((x) > (y)? (x) : (y)) +#define MIN(x, y) ((x) < (y)? (x) : (y)) /* Pack a size and allocated bit into a word */ #define PACK(size, alloc) ((size) | (alloc)) @@ -100,12 +102,17 @@ team_t team = { #define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE))) #define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE))) +#define PUT_PTR(p, ptr) (*(unsigned int *)(p) = (unsigned int)(ptr)) + +#define PRV_FREE(bp) ((char *)(bp)) +#define NXT_FREE(bp) ((char *)(bp) + WSIZE) + //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////// STATIC VARS ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -const size_t LIST_SIZE = 100; +const size_t LISTSIZE = 11; static char* heap_listp; -static char* seg_list[LIST_SIZE]; +char* seg_list[LISTSIZE]; //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// HELPER PREDEF //////////////////////////////// @@ -138,23 +145,42 @@ static void place(void *bp, size_t asize) PUT(FTRP(bp), PACK(csize, 1)); } } -static void* first_fit(size_t asize) { - /* First fit search */ - void *bp; - for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) { - if (!GET_ALLOC(HDRP(bp)) && (asize <= GET_SIZE(HDRP(bp)))) { - return bp; +static int getSzClass(size_t asize) { + for (size_t i = 0; i < LISTSIZE; ++i) { + if (asize == (1 << i)) { + return i; } } - return NULL; /* No fit */ - + return LISTSIZE; } +static void* best_fit(void* ptr, size_t asize) { + unsigned long left_over = GET_SIZE(ptr) - asize; + int c = 0; + while (NXT_FREE(ptr) != NULL) { + left_over = (MIN(left_over, GET_SIZE(ptr) - asize)); + ptr = NXT_FREE(ptr); + } + return NULL; +} /* Page 856, Pearson R. Bryant – D. O’Hallaron. Computer Systems: A Programmer’s Perspective.3rd Edition, Pearson, 2003. */ static void* find_fit(size_t asize) { - return first_fit(asize); + int szClass = getSzClass(asize); + void* classPtr = seg_list[szClass]; + if (classPtr == NULL) { + return NULL; + } else { + if (szClass != LISTSIZE -1) { + while (NXT_FREE(classPtr) != NULL) { + classPtr = NXT_FREE(classPtr); + } + return classPtr; + } else { + return best_fit(classPtr, asize); + } + } } /* Page 833, Pearson R. Bryant – D. O’Hallaron. Computer Systems: A Programmer’s Perspective.3rd Edition, Pearson, 2003. */ @@ -190,6 +216,10 @@ static void *extend_heap(size_t words) char *bp; size_t size; + if (words == 0) { + return NULL; + } + /* Allocate an even number of words to maintain alignment */ size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; if ((long)(bp = mem_sbrk(size)) == -1) @@ -200,6 +230,9 @@ static void *extend_heap(size_t words) PUT(FTRP(bp), PACK(size,0)); /* Free block footer */ PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ + PUT_PTR(PRV_FREE(bp), 0); + PUT_PTR(NXT_FREE(bp), 0); + /* Coalesce if the previous block was free */ return coalesce(bp); } @@ -213,9 +246,11 @@ static void *extend_heap(size_t words) */ int mm_init(void) { - for (size_t i = 0; i < LIST_SIZE; ++i) { + // init seg_list + for (size_t i = 0; i < LISTSIZE; ++i) { seg_list[i] = NULL; } + /* Create the initial empty heap */ if ((heap_listp = mem_sbrk(4*WSIZE)) == (void *)-1) return -1; @@ -250,7 +285,7 @@ void *mm_malloc(size_t size) if (size <= DSIZE) asize = 2*DSIZE; else - asize = DSIZE * ((size + (DSIZE) + (DSIZE-1)) / DSIZE); + asize = ALIGN(size+DSIZE); /* Search the free list for a fit */ if ((bp = find_fit(asize)) != NULL) { @@ -272,9 +307,10 @@ void *mm_malloc(size_t size) */ void mm_free(void *ptr) { - size_t size= GET_SIZE(HDRP(ptr)); + size_t size = GET_SIZE(HDRP(ptr)); PUT(HDRP(ptr), PACK(size, 0)); PUT(FTRP(ptr), PACK(size, 0)); + coalesce(ptr); }