/* * Initialize: return -1 on error, 0 on success. * The heap format is padding alignment, prologue header, free * list header, prologue footer, regular blks and epilogue. */ int mm_init(void) { size_t initSize, prologueSize; size_t listAddr; initSize = (LISTNUM + 2) * DSIZE; if ((heap_listp = mem_sbrk(initSize)) == (void *)-1) { return -1; } // padding put(heap_listp, pack(0, 0, 0)); // prologue prologueSize = (LISTNUM + 1) * DSIZE; put(heap_listp+WSIZE, pack(prologueSize, 2, 1)); put(heap_listp+DSIZE, pack(prologueSize, 2, 1)); // free list header for (size_t i = 0; i < LISTNUM; i++) { listAddr = (i + 1) * DSIZE; put(heap_listp + listAddr, listAddr); // pointer is 8 bytes put(heap_listp + (listAddr + WSIZE), listAddr); } // epilogue put(getFooter(heap_listp+DSIZE) + WSIZE, pack(0, 2, 1)); if (extendHeap(CHUNKSIZE / WSIZE) == NULL) return -1; return 0; }
/* * 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; }
/* * mm_malloc - Allocate a block with at least size bytes of payload * This function takes into account alignment and how the heap space * is organized during any given malloc call. * * The adjusted block size is calculated by taking the max of the * minimum size (24 bytes) and the requested size (aligned size + 8). * * It then searches the free list until it finds a place to put the block. * Using this block pointer, it places the block in this spot. * * If no space was found, we must ask for more memory and then place at * the block at the start of the new heap memory. * * This function takes a payload size as a parameter and returns * a pointer to the start of the alocated block. */ void *mm_malloc(size_t size) { size_t asize; /* adjusted block size */ size_t extendsize; /* amount to extend heap if no fit */ char *bp; /* Ignore spurious requests */ if (size <= 0) return NULL; /* Adjust block size to include overhead and alignment reqs */ asize = MAX(ALIGN(size) + DSIZE, MINIMUM); /* Search the free list for a fit */ if ((bp = findFit(asize))) { place(bp, asize); return bp; } /* No fit found. Get more memory and place the block */ extendsize = MAX(asize, CHUNKSIZE); //return NULL if unable to get heap space if ((bp = extendHeap(extendsize/WSIZE)) == NULL) return NULL; place(bp, asize); return bp; }
/* * 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) { /*return -1 if unable to get heap space*/ if ((heap_listp = mem_sbrk(2*MINIMUM)) == NULL) return -1; PUT(heap_listp, 0); //Alignment padding /*initialize dummy block header*/ PUT(heap_listp + WSIZE, PACK(MINIMUM, 1)); //WSIZE = padding PUT(heap_listp + DSIZE, 0); //PREV pointer PUT(heap_listp + DSIZE+WSIZE, 0); //NEXT pointer /*initialize dummy block footer*/ PUT(heap_listp + MINIMUM, PACK(MINIMUM, 1)); /*initialize dummy tail block*/ PUT(heap_listp+WSIZE + MINIMUM, PACK(0, 1)); /*initialize the free list pointer to the tail block*/ free_listp = heap_listp + DSIZE; free_listp_head = heap_listp + DSIZE; /*return -1 if unable to get heap space*/ if (extendHeap(CHUNKSIZE/WSIZE) == NULL) return -1; return 0; }
/* * mm_malloc - The allocator * malloc allocates free blocks on the heap. * It first aligns the size by rounding size to * the nearest multiple of ALIGNMENT(8) and then * adds DSIZE to this value to accomodate the header * and footer. We then call findFit to find a free block * that can accomodate this size. After doing so, we * set the allocated bit in the header and return the * current block pointer. */ void *mm_malloc(size_t size) { size_t asize; /* adjusted block size */ size_t extendsize; /* amount to extend heap if no fit */ char *bp; /* Block pointer to be returned. */ /* Ignore spurious requests */ if (size <= 0) return NULL; /* Adjust block size to include overhead(by adding DSIZE) for header+footer * and alignment reqs */ asize = MAX(ALIGN(size) + DSIZE, MINBLOCKSIZE); /* Search the free list for a fit */ if ((bp = findFit(asize)) != NULL) { place(bp, asize); //mm_checkheap(0); return bp; } /* No fit found. Get more memory and place the block */ extendsize = MAX(asize, CHUNKSIZE); /* Return NULL if unable to get heap space */ if ((bp = extendHeap(extendsize/WSIZE)) == NULL) return NULL; place(bp, asize); //mm_checkheap(0); return bp; }
/* * mm_init - Heap initializer * * mm_init initializes the heap by first creating an `* initial block described in the function and then * extending the heap by chunksize/dsize. The initial heap * consists of a single free block. The minimum block size * is 24 bytes because we require 8 for both the header and * and footer and 8 each for the next and prev pointers of * the doubly linked list. */ int mm_init(void) { /* Initial Block has * PADDING|HEADER | PREV PTR | NEXT PTR | FOOTER | EPILOGUE BLOCK| * 4 BYTES|4 BYTES| 8 BYTES | 8 BYTES | 4 BYTES | 4 BYTES | * for a total of MINBLOCKSIZE+DSIZE */ /*return -1 if unable to get heap space*/ if ((heap_listp = mem_sbrk(DSIZE+MINBLOCKSIZE)) == NULL) return -1; PUT(heap_listp, 0); /* Alignment padding */ /*Initialize prologue block header and footer * and pointers. * 4 bytes for header * 4 bytes for footer * 8 bytes for prev ptr, * 8 bytes for next ptr */ PUT(heap_listp + WSIZE, PACK(MINBLOCKSIZE, 1)); //HEADER PUT(heap_listp + DSIZE, 0); //PREV ptr PUT(heap_listp + 2*DSIZE, 0); //NEXT ptr PUT(heap_listp + MINBLOCKSIZE, PACK(MINBLOCKSIZE, 1)); // FOOTER PUT(heap_listp+ MINBLOCKSIZE + WSIZE, PACK(0, 1)); // Epilogue Block /* Set free list pointer to point to first word of * payload in the first free block. */ free_listp = heap_listp + DSIZE; /* Set heap pointer to point to first word AFTER header */ heap_listp += DSIZE; //mm_checkheap(0); if (extendHeap(CHUNKSIZE/DSIZE) == NULL) return -1; //mm_checkheap(0); return 0; }
void *memmalloc(size_t size) { size_t asize; size_t extendsize; char *bp; if (size == 0) return NULL; //块大小要能够包含头部和尾部以及前后向指针 if (size <= DSIZE) asize = 4 * DSIZE; else asize = DSIZE * ((size + (DSIZE)+(DSIZE - 1)) / DSIZE); //寻找合适大小的块 if ((bp = (char*)findFit(asize)) != NULL) { place(bp, asize); return bp; } //没有合适大小的块就要重新申请 extendsize = MAX(asize,CHUNKSIZE); if ((bp = (char*)extendHeap(extendsize/WSIZE)) == NULL) return NULL; //将新分配的块放在空闲队列头部 PUT(bp, &head); PUT(bp + (1 * WSIZE), (void*)head.next); if (head.next != NULL) PUT((void*)head.next, FTRP(bp) + DSIZE); head.next = bp; place(bp, asize); return bp; }
int meminit(void) { char *fbp; if ((heap_listp = (char*)memSbrk(4 * WSIZE)) == (void *)-1) return -1; PUT(heap_listp, 0); //对齐填充 PUT(heap_listp + (1 * WSIZE), PACK(DSIZE, 1)); //序言块头部 PUT(heap_listp + (2 * WSIZE), PACK(DSIZE, 1)); //序言块尾 PUT(heap_listp + (3 * WSIZE), PACK(0, 1)); //结尾块 heap_listp += (2 * WSIZE); //堆指针指向序言块中间 head.next = NULL; head.prev = NULL; if ((fbp = (char*)extendHeap(CHUNKSIZE/WSIZE)) == NULL) //分配第一个空闲块 return -1; head.next = fbp; //链表头节点指针指向第一个块 PUT(head.next, &head); PUT(head.next + (1 * WSIZE), NULL); //祖先和后继为链表头部 return 0; }
/* * malloc: adjust the size to the minimum block size or a * multiple of alignment. Search the free list for a fit, * if not, extend the heap */ void *malloc (size_t size) { //checkheap(1); // Let's make sure the heap is ok! size_t asize; // adjust size size_t extendsize; char *bp; if (size <= 0){ return NULL; } // Adjust the size to at least the minimum blk size and // a multiple of alignment 8 if (size <= (DSIZE + WSIZE)){ asize = 2 * DSIZE; } else{ asize = DSIZE*((size + DSIZE + (DSIZE - 1)) / DSIZE); } // search the freelist for a fit if ((bp = findFit(asize)) != NULL){ place(bp, asize); return bp; } // If no fit, extend the heap if(asize>CHUNKSIZE) extendsize = asize; else extendsize = CHUNKSIZE; if ((bp = extendHeap(extendsize / WSIZE)) == NULL) return NULL; place(bp, asize); return bp; }