/* Allocate a block of size size and return a pointer to it. */ void * mm_malloc (size_t size) { size_t reqSize; BlockInfo * ptrFreeBlock = NULL; //Zero-size requests get NULL; if (size == 0){ return NULL; } //Add one word for the initial size header. //Note that we don't need to boundary tag when the block is used! if (size <= MIN_BLOCK_SIZE) { // Make sure we allocate enough space for a blockInfo in case we // free this block (when we free this block, we'll need to use the // next pointer, the prev pointer, and the boundary tag). reqSize = MIN_BLOCK_SIZE; } else { // Round up for correct alignment reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT); } printf("Begin malloc of reqSize: %zd \n", reqSize); printf("Free list head: %p\n", FREE_LIST_HEAD); examine_heap(); while ((ptrFreeBlock = searchFreeList(reqSize)) == NULL){ requestMoreSpace(reqSize); printf("Finished space request\n"); } removeFreeBlock(ptrFreeBlock); placeBlock(ptrFreeBlock, reqSize); printf("Completed malloc\n"); printf("Pointer free block: %p\n", ptrFreeBlock); examine_heap(); return UNSCALED_POINTER_ADD(ptrFreeBlock, WORD_SIZE); }
/* Allocate a block of size size and return a pointer to it. */ void* mm_malloc (size_t size) { size_t reqSize; BlockInfo * ptrFreeBlock = NULL, * head; size_t blockSize; size_t precedingBlockUseTag; size_t extendsize; /* Amount to extend heap if no fit */ // Zero-size requests get NULL. if (size == 0) { return NULL; } // Add one word for the initial size header. // Note that we don't need to boundary tag when the block is used! size += WORD_SIZE; if (size <= MIN_BLOCK_SIZE) { // Make sure we allocate enough space for a blockInfo in case we // free this block (when we free this block, we'll need to use the // next pointer, the prev pointer, and the boundary tag). reqSize = MIN_BLOCK_SIZE; } else { // Round up for correct alignment reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT); } // Implement mm_malloc. You can change or remove any of the above // code. It is included as a suggestion of where to start. // You will want to replace this return statement... //head = FREE_LIST_HEAD; //printf("\nSo we were requested %d (%d). Free list head was 0x%x %d 0x%x 0x%x\n", // size, reqSize, head, head->sizeAndTags, head->next, head->prev ); // half-arsed fix reqSize=reqSize+ALIGNMENT; if ( ptrFreeBlock = searchFreeList(reqSize) ) { precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED; placeBlock( ptrFreeBlock, reqSize, precedingBlockUseTag ); } else { //printf("But there wasn't big enough free block, we requsted extension %d\n", extendsize); requestMoreSpace( reqSize ); ptrFreeBlock = searchFreeList(reqSize); //printf("We got ourselves new pointer to free block after 0x%x %d 0x%x 0x%x\n", // (int*)ptrFreeBlock, (int)ptrFreeBlock->sizeAndTags, (int*)ptrFreeBlock->next, (int*)ptrFreeBlock->prev); precedingBlockUseTag = TAG_PRECEDING_USED; placeBlock( ptrFreeBlock, reqSize, precedingBlockUseTag ); } return ((void*) POINTER_ADD(ptrFreeBlock, WORD_SIZE)); }
/* Allocate a block of size size and return a pointer to it. */ void* mm_malloc (size_t size) { size_t reqSize; BlockInfo * ptrFreeBlock = NULL; size_t precedingBlockUseTag; // Zero-size requests get NULL. if (size == 0) { return NULL; } // Add one word for the initial size header. // Note that we don't need to boundary tag when the block is used! size += WORD_SIZE; if (size <= MIN_BLOCK_SIZE) { // Make sure we allocate enough space for a blockInfo in case we // free this block (when we free this block, we'll need to use the // next pointer, the prev pointer, and the boundary tag). reqSize = MIN_BLOCK_SIZE; } else { // Round up for correct alignment reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT); } ptrFreeBlock = searchFreeList(reqSize); //test for available block if(ptrFreeBlock != NULL){ //if block of correct size available: precedingBlockUseTag = (ptrFreeBlock)->sizeAndTags & (TAG_PRECEDING_USED); //test to see if block preceeding the block to be allocated is allocated setBlock(ptrFreeBlock, reqSize, precedingBlockUseTag);//call to helper function, setBlock } else{ requestMoreSpace(reqSize); //request a freeBlock of the appropriate size ptrFreeBlock = searchFreeList(reqSize);//search the free list now that we know the free block is there precedingBlockUseTag = TAG_PRECEDING_USED; setBlock(ptrFreeBlock, reqSize, precedingBlockUseTag);//call to helper function, setBlock } return UNSCALED_POINTER_ADD(ptrFreeBlock, WORD_SIZE); }
/* Allocate a block of size size and return a pointer to it. */ void* mm_malloc (size_t size) { size_t reqSize; BlockInfo * ptrFreeBlock = NULL; size_t blockSize; size_t precedingBlockUseTag; // Zero-size requests get NULL. if (size == 0) { return NULL; } // Add one word for the initial size header. // Note that we don't need to boundary tag when the block is used! size += WORD_SIZE; if (size <= MIN_BLOCK_SIZE) { // Make sure we allocate enough space for a blockInfo in case we // free this block (when we free this block, we'll need to use the // next pointer, the prev pointer, and the boundary tag). reqSize = MIN_BLOCK_SIZE; } else { // Round up for correct alignment reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT); } // Implement mm_malloc. You can change or remove any of the above // code. It is included as a suggestion of where to start. // You will want to replace this return statement... // Search the free list for a fit ptrFreeBlock = searchFreeList(reqSize); // No fit found. Get more memory if (ptrFreeBlock == NULL) { requestMoreSpace(reqSize); ptrFreeBlock = searchFreeList(reqSize); } // place the acquired block and split excessive part as needed removeFreeBlock(ptrFreeBlock); blockSize = SIZE(ptrFreeBlock->sizeAndTags); precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED; if (blockSize - reqSize >= MIN_BLOCK_SIZE) { size_t newFreeBlockSize = blockSize - reqSize; BlockInfo *newPtrFreeBlock = (BlockInfo*)POINTER_ADD(ptrFreeBlock, reqSize); newPtrFreeBlock->sizeAndTags = newFreeBlockSize | TAG_PRECEDING_USED; // !TAG_USED // update the boundary tag *((size_t*)POINTER_ADD(newPtrFreeBlock, newFreeBlockSize - WORD_SIZE)) = newFreeBlockSize | TAG_PRECEDING_USED; // !TAG_USED // insert the new free block into free list insertFreeBlock(newPtrFreeBlock); blockSize = reqSize; } else { // do not need to split the block, but need to update the status of following block BlockInfo *followingBlock = (BlockInfo*)POINTER_ADD(ptrFreeBlock, blockSize); size_t followingBlockSize = SIZE(followingBlock->sizeAndTags); size_t followingBlockUsed = followingBlock->sizeAndTags & TAG_USED; followingBlock->sizeAndTags = followingBlockSize | TAG_PRECEDING_USED | followingBlockUsed; if (followingBlockUsed != TAG_USED) { *((size_t*)POINTER_ADD(followingBlock, followingBlockSize - WORD_SIZE)) = followingBlock->sizeAndTags; } } ptrFreeBlock->sizeAndTags = blockSize | precedingBlockUseTag | TAG_USED; // we do not care about the boundary tag of used block! return POINTER_ADD(ptrFreeBlock, WORD_SIZE); }
/* Allocate a block of size size and return a pointer to it. */ void* mm_malloc (size_t size) { size_t reqSize; BlockInfo * ptrFreeBlock = NULL; size_t blockSize; size_t precedingBlockUseTag; BlockInfo * nextBlock = NULL; BlockInfo * newBlock = NULL; // Zero-size requests get NULL. if (size == 0) { return NULL; } // Add one word for the initial size header. // Note that we don't need to boundary tag when the block is used! size += WORD_SIZE; if (size <= MIN_BLOCK_SIZE) { // Make sure we allocate enough space for a blockInfo in case we // free this block (when we free this block, we'll need to use the // next pointer, the prev pointer, and the boundary tag). reqSize = MIN_BLOCK_SIZE; } else { // Round up for correct alignment reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT); } // Implement mm_malloc. You can change or remove any of the above // code. It is included as a suggestion of where to start. // You will want to replace this return statement... /* ptrFreeBlock = searchFreeList(reqSize); if( ptrFreeBlock != NULL) { blockSize = SIZE(ptrFreeBlock->sizeAndTags); nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize); nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED; removeFreeBlock(ptrFreeBlock); ptrFreeBlock->sizeAndTags = ptrFreeBlock->sizeAndTags | TAG_USED; return POINTER_ADD( ptrFreeBlock, WORD_SIZE); } requestMoreSpace(reqSize); ptrFreeBlock = searchFreeList(reqSize); if( ptrFreeBlock != NULL) { blockSize = SIZE(ptrFreeBlock->sizeAndTags); nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize); nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED; removeFreeBlock(ptrFreeBlock); ptrFreeBlock->sizeAndTags = ptrFreeBlock->sizeAndTags | TAG_USED; return POINTER_ADD( ptrFreeBlock, WORD_SIZE); } */ ptrFreeBlock = searchFreeList(reqSize); if( ptrFreeBlock == NULL){ requestMoreSpace(reqSize); ptrFreeBlock = searchFreeList(reqSize); } blockSize = SIZE(ptrFreeBlock->sizeAndTags); if( (blockSize - reqSize) >= MIN_BLOCK_SIZE ){ precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED; ptrFreeBlock->sizeAndTags = reqSize | precedingBlockUseTag | TAG_USED ; removeFreeBlock(ptrFreeBlock); newBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, reqSize); newBlock->sizeAndTags = blockSize - reqSize; newBlock->sizeAndTags = newBlock->sizeAndTags | TAG_PRECEDING_USED; *((size_t*)POINTER_ADD(newBlock, blockSize - reqSize - WORD_SIZE ) ) = newBlock->sizeAndTags; insertFreeBlock(newBlock); }else{ nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize); nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED; ptrFreeBlock->sizeAndTags = ptrFreeBlock->sizeAndTags | TAG_USED; removeFreeBlock(ptrFreeBlock); } return POINTER_ADD( ptrFreeBlock, WORD_SIZE); }
/* Allocate a block of size size and return a pointer to it. */ void* mm_malloc (size_t size) { size_t reqSize; BlockInfo * ptrFreeBlock = NULL; BlockInfo * splitBlock; size_t blockSize; size_t precedingBlockUseTag; // Zero-size requests get NULL. if (size == 0) { return NULL; } // Add one word for the initial size header. // Note that we don't need to boundary tag when the block is used! size += WORD_SIZE; if (size <= MIN_BLOCK_SIZE) { // Make sure we allocate enough space for a blockInfo in case we // free this block (when we free this block, we'll need to use the // next pointer, the prev pointer, and the boundary tag). reqSize = MIN_BLOCK_SIZE; } else { // Round up for correct alignment reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT); } // Implement mm_malloc. You can change or remove any of the above // code. It is included as a suggestion of where to start. // You will want to replace this return statement... // find free block of reqSize ptrFreeBlock = searchFreeList(reqSize); while ( ptrFreeBlock == NULL ) { requestMoreSpace(1 << 14); ptrFreeBlock = searchFreeList(reqSize); } // check free block size vs reqSize vs alignment requirements, // split if necessary. If split, reformat newly created free // block (add header, set bits, add footer). blockSize = SIZE(ptrFreeBlock->sizeAndTags); if ( blockSize - reqSize >= MIN_BLOCK_SIZE ) { // Split, set size and tags of new block splitBlock = (BlockInfo*) POINTER_ADD(ptrFreeBlock, reqSize); blockSize -= reqSize; splitBlock->sizeAndTags = blockSize | TAG_PRECEDING_USED; splitBlock->sizeAndTags &= ~0 << 1; // turn off use bit - preserve others // set footer equal to header. Current ptr + blockSize - one word = boundary // tag of current block (word prior to start of next block) *((size_t*) POINTER_ADD(splitBlock, blockSize- WORD_SIZE))= splitBlock->sizeAndTags; insertFreeBlock(splitBlock); // set size of ptrFreeBlock to exclude size of newBlock blockSize = reqSize; } else { // if we didnt split, set the next block's preceding tag to 1 *((size_t*) POINTER_ADD(ptrFreeBlock, SIZE(ptrFreeBlock->sizeAndTags))) |= TAG_PRECEDING_USED; } removeFreeBlock(ptrFreeBlock); precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED; // if the preceding block is used as well, set lower two bits. Else, set only // used bit. if ( precedingBlockUseTag ) { ptrFreeBlock->sizeAndTags = blockSize | (TAG_PRECEDING_USED + TAG_USED); } else { ptrFreeBlock->sizeAndTags = blockSize | TAG_USED; } // return pointer to block (beginning of payload) // if null, return null. else return 8 after start of block (ie skip header, // return ptr to payload region) if ( ptrFreeBlock == NULL) { return NULL; } else { return (void*) POINTER_ADD(ptrFreeBlock, WORD_SIZE); } }