/* * mm-naive.c - The fastest, least memory-efficient malloc package. * * In this naive approach, a block is allocated by simply incrementing * the brk pointer. A block is pure payload. There are no headers or * footers. Blocks are never coalesced or reused. Realloc is * implemented directly using mm_malloc and mm_free. * * NOTE TO STUDENTS: Replace this header comment with your own header * comment that gives a high level description of your solution. */ #include #include #include #include #include #include "mm.h" #include "memlib.h" /********************************************************* * NOTE TO STUDENTS: Before you do anything else, please * provide your team information in the following struct. ********************************************************/ team_t team = { /* Team name */ "anna.schlittenhardt@stud.uni-due.de+tuan-dat.tran@stud.uni-due.de", /* First member's full name */ "Anna Schlittenhardt", /* First member's email address */ "anna.schlittenhardt@stud.uni-due.de", /* Second member's full name (leave blank if none) */ "Tuan-Dat Tran", /* Second member's email address (leave blank if none) */ "tuan-dat.tran@stud.uni-due.de" }; //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// STRUCTURE ////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Filled Blk // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // HEADER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // BP-> | ALLOCED MEMORY | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // FOOTER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // // Empty Blk // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // HEADER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // BP-> | PTR TO PREV FREE BLK | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // | PTR TO NEXT FREE BLK | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // | UNALLOC MEMORY | // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // FOOTER | SIZE | A| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// DEFINES /////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /* single word (4) or double word (8) alignment */ #define ALIGNMENT 8 /* rounds up to the nearest multiple of ALIGNMENT */ #define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7) #define SIZE_T_SIZE (ALIGN(sizeof(size_t))) /* Page 830, Pearson R. Bryant – D. O’Hallaron. Computer Systems: A Programmer’s Perspective.3rd Edition, Pearson, 2003. */ /* Basic constants and macros */ #define WSIZE 4 /* Word and header/footer size (bytes) */ #define DSIZE 8 /* Double word size (bytes) */ #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)) /* Read and write a word at address p */ #define GET(p) (*(unsigned int *)(p)) #define PUT(p, val) (*(unsigned int *)(p) = (val)) /* Read the size and allocated fields from address p */ #define GET_SIZE(p) (GET(p) & ~0x7) #define GET_ALLOC(p) (GET(p) & 0x1) /* Given block ptr bp, compute address of its header and footer */ #define HDRP(bp) ((char *)(bp) - WSIZE) #define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE) /* Given block ptr bp, compute address of next and previous blocks */ #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_PTR(ptr) ((char *)(ptr)) #define NXT_PTR(ptr) ((char *)(ptr) + WSIZE) #define PRV_BLK(ptr) (*(char **)(ptr)) #define NXT_BLK(ptr) (*(char **)(NXT_PTR(ptr))) //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////// GLOBAL VARS ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// #define LISTSIZE 20 static char* heap_listp; char* seg_list[LISTSIZE]; static void insert_node(void *ptr, size_t size) { int list = 0; void *search_ptr = ptr; void *insert_ptr = NULL; // Select segregated list while ((list < LISTSIZE - 1) && (size > 1)) { size >>= 1; list++; } // Keep size ascending order and search search_ptr = seg_list[list]; while ((search_ptr != NULL) && (size > GET_SIZE(HDRP(search_ptr)))) { insert_ptr = search_ptr; search_ptr = PRV_BLK(search_ptr); } // Set predecessor and successor if (search_ptr != NULL) { if (insert_ptr != NULL) { PUT_PTR(PRV_PTR(ptr), search_ptr); PUT_PTR(NXT_PTR(search_ptr), ptr); PUT_PTR(NXT_PTR(ptr), insert_ptr); PUT_PTR(PRV_PTR(insert_ptr), ptr); } else { PUT_PTR(PRV_PTR(ptr), search_ptr); PUT_PTR(NXT_PTR(search_ptr), ptr); PUT_PTR(NXT_PTR(ptr), NULL); seg_list[list] = ptr; } } else { if (insert_ptr != NULL) { PUT_PTR(PRV_PTR(ptr), NULL); PUT_PTR(NXT_PTR(ptr), insert_ptr); PUT_PTR(PRV_PTR(insert_ptr), ptr); } else { PUT_PTR(PRV_PTR(ptr), NULL); PUT_PTR(NXT_PTR(ptr), NULL); seg_list[list] = ptr; } } return; } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// HELPER PREDEF //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /* Page 856-858, Pearson R. Bryant – D. O’Hallaron. Computer Systems: A Programmer’s Perspective.3rd Edition, Pearson, 2003. */ static void place(void *bp, size_t asize); /* 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); /* Page 833, Pearson R. Bryant – D. O’Hallaron. Computer Systems: A Programmer’s Perspective.3rd Edition, Pearson, 2003. */ static void* coalesce(void *bp); /* Page 831, Pearson R. Bryant – D. O’Hallaron. Computer Systems: A Programmer’s Perspective.3rd Edition, Pearson, 2003. */ static void* extend_heap(size_t words); static void add_free(void* bp, size_t asize); //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// HELPER FUNCTIONS /////////////////////////////// //////////////////////////////////////////////////////////////////////////////// static void add_free(void* bp, size_t asize) { insert_node(bp, asize); } static int getSzClass(size_t asize) { for (size_t i = 0; i < LISTSIZE; ++i) { if (asize == (1 << i)) { return i; } } return LISTSIZE-1; } static void remove_free(void* bp) { int szClass = getSzClass(GET_SIZE(HDRP(bp))); if (PRV_BLK(bp) == NULL && NXT_BLK(bp) == NULL) { seg_list[szClass] = NULL; } else if (PRV_BLK(bp) != NULL && NXT_BLK(bp) == NULL) { PUT_PTR(PRV_PTR(PRV_BLK(bp)), NULL); seg_list[szClass] = PRV_BLK(bp); } else if (PRV_BLK(bp) == NULL && NXT_BLK(bp) != NULL) { PUT_PTR(PRV_PTR(NXT_BLK(bp)), NULL); } if (PRV_BLK(bp) != NULL && NXT_BLK(bp) != NULL) { PUT_PTR(NXT_PTR(PRV_BLK(bp)), NXT_BLK(bp)); PUT_PTR(PRV_PTR(NXT_BLK(bp)), PRV_BLK(bp)); } } static void place(void *bp, size_t asize) { size_t csize = GET_SIZE(HDRP(bp)); remove_free(bp); PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); if (asize <= (2*(1 << (LISTSIZE-1)))) { return; } else { bp = NEXT_BLKP(bp); PUT(HDRP(bp), PACK(csize-asize, 0)); PUT(FTRP(bp), PACK(csize-asize, 0)); add_free(bp, csize-asize); } } static void* best_fit(void* ptr, size_t asize) { unsigned long left_over = GET_SIZE(ptr) - asize; void* bestfit = ptr; unsigned long best_left_over = GET_SIZE(ptr) - asize; while (NXT_PTR(ptr) != NULL) { left_over = GET_SIZE(ptr) - asize; if(left_over