CSAPP 六個重要實驗 lab5,csapplab5
CSAPP && lab5
實驗指導書:
http://download.csdn.net/detail/u011368821/7951657
實驗材料:
http://download.csdn.net/detail/u011368821/8019293
搞定這個實驗還是要看一下以前的筆記,再複習一下block的組織方式,只看link裡面第11節,動態記憶體分配的部分就可以了
http://blog.csdn.net/cinmyheart/article/details/38136375
然後看看對block的探測性學習
http://blog.csdn.net/cinmyheart/article/details/38174421
The only file you will modify and turn in is mm.c.
Your dynamic storage allocator will consist of the following three functions (and several helper functions), which are declared in mm.h and defined in mm.c:
int mm_init(void);void* mm_malloc(size_t size);void mm_free(void* ptr);
Your job is to complete this implementation by filling out mm_malloc() and mm_free().
任務就是利用以下現有的API去補全mm_malloc()和mm_free()
Provided Code
We define a BlockInfo struct designed to be used as a node in a doublylinked explicit free list, and the following functions for manipulating free lists:
BlockInfo* searchFreeList(int reqSize): returns a block of at least the requested size if one exists (and NULL otherwise).void insertFreeBlock(BlockInfo* blockInfo): inserts the given block in the free list in LIFO manner.void removeFreeBlock(BlockInfo* blockInfo): removes the given block from the free list.
In addition, we implement mm_init and provide two helper functions implementing important parts of the allocator:
void requestMoreSpace(int incr): enlarges the heap by incr bytes (if enough memory is available on the machine to do so).void coalesceFreeBlock(BlockInfo* oldBlock): coalesces any other free blocks adjacent in memory to oldBlock into asingle new large block and updates the free list accordingly.
這裡free list的實現介紹: 這裡需要說明一下的就是header處於低地址,footer處於高地址. 這裡說明的原因是因為實現的時候會有指標的加減,注意一下就是了 :-)
sizeAndTags中記錄的size資訊是整個block的大小,包括了struct BlockInfo結構體的大小
論證: 觀察struct BlockInfo結構體在記憶體中的分布
正是根據記憶體布局的特點,這裡blockCursor只想當前block頭的時候減去一個WORD_SIZE會得到什嗎?
前一個block的footer 即boundary tag,由此獲知當前block的前一個block的大小
My answer:
/* 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 * ptrNextBlock = NULL; size_t blockSize; size_t precedingBlockUseTag; size_t* ptrNextBlockFooter = 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) {requestMoreSpace(reqSize);ptrFreeBlock = searchFreeList(reqSize); } blockSize = SIZE(ptrFreeBlock->sizeAndTags); if(blockSize < reqSize + MIN_BLOCK_SIZE) {reqSize = blockSize; } precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED; ptrFreeBlock->sizeAndTags = reqSize | precedingBlockUseTag | TAG_USED; ptrNextBlock = (BlockInfo*)UNSCALED_POINTER_ADD(ptrFreeBlock,reqSize); if(reqSize != blockSize) {ptrNextBlock->sizeAndTags = (blockSize - reqSize) | TAG_PRECEDING_USED;ptrNextBlockFooter = (size_t *)UNSCALED_POINTER_ADD(ptrFreeBlock,blockSize - WORD_SIZE);(*ptrNextBlockFooter) = ptrNextBlock->sizeAndTags;insertFreeBlock(ptrNextBlock); } else { ptrNextBlock->sizeAndTags = ptrNextBlock->sizeAndTags | TAG_PRECEDING_USED;ptrNextBlockFooter = (size_t*)UNSCALED_POINTER_ADD(ptrNextBlock,SIZE(ptrNextBlock->sizeAndTags) - WORD_SIZE);(*ptrNextBlockFooter) = ptrNextBlock->sizeAndTags; } removeFreeBlock(ptrFreeBlock); return (void*)UNSCALED_POINTER_ADD(ptrFreeBlock,WORD_SIZE); }/* Free the block referenced by ptr. */void mm_free (void *ptr) { size_t payloadSize; size_t blockSize; BlockInfo * blockInfo; BlockInfo * followingBlock; // Implement mm_free. You can change or remove the declaraions // above. They are included as minor hints. BlockInfo* prev_block = NULL; BlockInfo* next_block = NULL; blockInfo = (BlockInfo*)UNSCALED_POINTER_SUB(ptr,WORD_SIZE); followingBlock = (BlockInfo *)UNSCALED_POINTER_ADD(blockInfo,blockInfo->sizeAndTags); blockSize = SIZE(blockInfo->sizeAndTags); payloadSize = blockSize - WORD_SIZE; blockInfo->sizeAndTags = blockInfo->sizeAndTags & ~TAG_USED; *(size_t *)UNSCALED_POINTER_ADD(blockInfo,payloadSize) = blockInfo->sizeAndTags; followingBlock->sizeAndTags = followingBlock->sizeAndTags & ~TAG_PRECEDING_USED; if(followingBlock->sizeAndTags & TAG_USED == 0) { *(size_t *)UNSCALED_POINTER_ADD(followingBlock,SIZE(followingBlock->sizeAndTags) - WORD_SIZE) = followingBlock->sizeAndTags; } insertFreeBlock(blockInfo); coalesceFreeBlock(blockInfo);}
最後運行./mdriver
會有一下輸出
題外話,追究這個malloc實現的話....其實它就是基於已經有的stdlib.h已經有的malloc而實現的,介紹的是實現原理,利用雙向鏈表
後面的額外練習表示沒有耐心了,對於realloc...
到此,CSAPP的lab暫時告一段落,以後還會峰峰補補的去更新 :-)
如果對這六個lab感興趣,歡迎郵箱聯絡交流討論
jasonleaster@gmail.com