static void *coalesce(void *bp) { unsigned int prev_allocfield = getAlloc(getBlockFooter(getPrevBlock(bp))); unsigned int next_allocfield = getAlloc(getBlockHeader(getNextBlock(bp))); unsigned int size = getSize(getBlockHeader(bp)); if(prev_allocfield && next_allocfield) return bp; if(prev_allocfield && !next_allocfield) { size += getSize(getBlockHeader(getNextBlock(bp))); put(getBlockHeader(bp),pack(size,0)); put(getBlockFooter(bp),pack(size,0)); } else if(!prev_allocfield && next_allocfield) { size += getSize(getBlockHeader(getPrevBlock(bp))); put(getBlockHeader(getPrevBlock(bp)),pack(size,0)); put(getBlockFooter(bp),pack(size,0)); } else { size += getSize(getBlockHeader(getPrevBlock(bp))) + getSize(getBlockHeader(getNextBlock(bp))); put(getBlockHeader(getPrevBlock(bp)),pack(size,0)); put(getBlockFooter(getNextBlock(bp)),pack(size,0)); bp = getPrevBlock(bp); } return bp; }
inline void *place(void *bp, size_t aSize) //alloc! { #ifdef __DEBUG__ printf("placing on %u, size %u\n",getBlockHeader(bp), aSize); #endif erase(getSize(getBlockHeader(bp)), bp); //no empty size_t cSize = getSize(getBlockHeader(bp)); if((cSize - aSize) >= 2*DSIZE) { if(aSize>=100) { //huge block to right set(getBlockHeader(bp), setMask(cSize - aSize, 0)); set(getBlockFooter(bp), setMask(cSize - aSize, 0)); bp = getNextBlock(bp); set(getBlockHeader(bp), setMask(aSize, 1)); set(getBlockFooter(bp), setMask(aSize, 1)); push_back(cSize-aSize, getPrevBlock(bp)); return bp; } else { //tiny block to left set(getBlockHeader(bp), setMask(aSize, 1)); set(getBlockFooter(bp), setMask(aSize, 1)); bp = getNextBlock(bp); set(getBlockHeader(bp), setMask(cSize - aSize, 0)); set(getBlockFooter(bp), setMask(cSize - aSize, 0)); push_back(cSize-aSize, bp); return getPrevBlock(bp); } } else { set(getBlockHeader(bp), setMask(cSize, 1)); set(getBlockFooter(bp), setMask(cSize, 1)); } return bp; }
static void *coalesce(void *bp) { #ifdef __DEBUG__ fprintf(stderr, "Coalescing...\n"); #endif size_t p = isAllocated(getBlockHeader(getPrevBlock(bp))); //allocated "physically" previous block? size_t n = isAllocated(getBlockHeader(getNextBlock(bp))); //allocated "physicall" next block? size_t size = getSize(getBlockHeader(bp)); //get block size if(p && n) { //no coalescing return bp; } else if(!p && n) //previous block is empty! { #ifdef __DEBUG__ fprintf(stderr, "Merging %u(size : %u) and %u(size : %u)...\n", getPrevBlock(bp), getSize(getBlockHeader(getPrevBlock(bp))), bp, getSize(getBlockHeader(bp))); #endif erase(size, bp); //delete current block erase(getSize(getBlockHeader(getPrevBlock(bp))), getPrevBlock(bp)); //delete previous block size += getSize(getBlockHeader(getPrevBlock(bp))); set(getBlockFooter(bp), setMask(size, 0)); set(getBlockHeader(getPrevBlock(bp)), setMask(size, 0)); push_back(size, getPrevBlock(bp)); //add summed block return getPrevBlock(bp); } else if(p && !n) //next block is empty! { #ifdef __DEBUG__ fprintf(stderr, "Merging %u(size : %u) and %u(size : %u)...\n", bp, getSize(getBlockHeader(bp)), getNextBlock(bp), getSize(getBlockHeader(getNextBlock(bp)))); #endif erase(size, bp); //delete current erase(getSize(getBlockHeader(getNextBlock(bp))), getNextBlock(bp)); //delete next size += getSize(getBlockHeader(getNextBlock(bp))); set(getBlockHeader(bp), setMask(size, 0)); set(getBlockFooter(bp), setMask(size, 0)); push_back(size, bp); //add summed block return bp; } else //both block are empty! { #ifdef __DEBUG__ fprintf(stderr, "Merging %u(size : %u), %u(size : %u) and %u(size : %u)...\n", getPrevBlock(bp), getSize(getBlockHeader(getPrevBlock(bp))), bp, getSize(getBlockHeader(bp)), getNextBlock(bp), getSize(getBlockHeader(getNextBlock(bp)))); #endif erase(size, bp); //delete every adjacent block erase(getSize(getBlockHeader(getPrevBlock(bp))), getPrevBlock(bp)); erase(getSize(getBlockHeader(getNextBlock(bp))), getNextBlock(bp)); size += getSize(getBlockHeader(getNextBlock(bp))) + getSize(getBlockHeader(getPrevBlock(bp))); set(getBlockHeader(getPrevBlock(bp)), setMask(size, 0)); set(getBlockFooter(getNextBlock(bp)), setMask(size, 0)); push_back(size, getPrevBlock(bp)); //sum up return getPrevBlock(bp); } }
void mm_free(void *bp) { unsigned int size = getSize(getBlockHeader(bp)); put(getBlockHeader(bp),pack(size,0)); put(getBlockFooter(bp),pack(size,0)); coalesce(bp); }
static void place(void *bp, unsigned int size) { char *spiltblock_addr; unsigned int spiltblock_size; unsigned int blocksize; blocksize = getSize(getBlockHeader(bp)); /* if the block size == size,then change the block header/footer alloc field simply*/ /* the block size > size,spilt the old block */ if(blocksize > size) { /* inintial the new spilted block(last) header and footer */ spiltblock_addr = (char*)bp + size; spiltblock_size = blocksize - size; put(getBlockHeader(spiltblock_addr),pack(spiltblock_size,0)); put(getBlockFooter(spiltblock_addr),pack(spiltblock_size,0)); } /* inintial the new block header and footer */ put(getBlockHeader(bp),pack(size,1)); put(getBlockFooter(bp),pack(size,1)); }
/* * mm_free - Freeing a block does nothing. */ void mm_free(void *ptr) { #ifdef __DEBUG__ printf("Trying to free...\n"); #endif if(!isAllocated(getBlockHeader(ptr))) return; #ifdef __DEBUG__ fprintf(stderr, "freeing : %u / allocated? : %u / size? : %u\n",getBlockHeader(ptr), isAllocated(getBlockHeader(ptr)), getSize(getBlockHeader(ptr))); #endif size_t size = getSize(getBlockHeader(ptr)); set(getBlockHeader(ptr), setMask(size, 0)); set(getBlockFooter(ptr), setMask(size, 0)); push_back(size, ptr); //new empty block, coalesce(ptr); //and coalesce! }
static void *extend_heap(unsigned int words) { char *bp; unsigned int size; /* allocate an even number of words to maintain alignment */ size = (words % 2)?(words+1)*wsize:words*wsize; if((bp = (char*)mem_sbrk(size)) == (void*)-1) /* mem_sbrk return the old mem_brk */ return NULL; /* inintialize free block header/footer and epilogue header*/ put(getBlockHeader(bp),pack(size,0)); put(getBlockFooter(bp),pack(size,0)); put(getBlockHeader(getNextBlock(bp)),pack(0,1)); /* ??? */ return coalesce(bp); }
static void *extend_heap(size_t words) //extend heap { char *bp; size_t size; size = (words % 2) ? (words + 1)*WSIZE : words * WSIZE; #ifdef __DEBUG__ fprintf(stderr, "Extending heap by %u...\n",size); printf("Heap size now : %u\n",mem_heapsize()); #endif if((long)(bp = mem_sbrk(size)) == -1) return NULL; //sbrk : gathering moar spaces set(getBlockHeader(bp), setMask(size, 0)); set(getBlockFooter(bp), setMask(size, 0)); set(getBlockHeader(getNextBlock(bp)), setMask(0, 1)); push_back(size, bp); //empty block to the list void* result = coalesce(bp); //coalesces! // push_back(getSize(getBlockHeader(result)), result); return result; }