/* coalesce free blocks */ static void *coalesce(void *bp){ size_t prevAllocBit = getPrevAlloc(getHeader(bp)); size_t nextAllocBit = getAlloc(getHeader(nextBlock(bp))); size_t size = getSize(getHeader(bp)); size_t index; size_t prevPAlloc; /* both the previous and next block allocated */ if (prevAllocBit && nextAllocBit) { setPrevFree(getHeader(nextBlock(bp))); } /* Only previous block is free */ else if (!prevAllocBit && nextAllocBit) { size += getSize(getHeader(prevBlock(bp))); prevPAlloc = getPrevAlloc(getHeader(prevBlock(bp))); deleteListNode(prevBlock(bp)); put(getFooter(bp), size); bp = prevBlock(bp); put(getHeader(bp), pack(size, prevPAlloc, 0)); setPrevFree(getHeader(nextBlock(bp))); } /* Only next block is free */ else if (prevAllocBit && !nextAllocBit) { size += getSize(getHeader(nextBlock(bp))); deleteListNode(nextBlock(bp)); put(getHeader(bp), pack(size, prevAllocBit, 0)); put(getFooter(bp), size); } /* Both previous and next block are free */ else { size += getSize(getHeader(prevBlock(bp))) + getSize(getFooter(nextBlock(bp))); prevPAlloc = getPrevAlloc(getHeader(prevBlock(bp))); deleteListNode(nextBlock(bp)); deleteListNode(prevBlock(bp)); put(getHeader(prevBlock(bp)), pack(size, prevPAlloc, 0)); put(getFooter(nextBlock(bp)), size); bp = prevBlock(bp); } index = getIndex(size); insertListNode(bp, index); return bp; }
void free(void * ptr) { char * charPtr = static_cast<char *>(ptr); Block & prev = prevBlock(charPtr); Block & next = nextBlock(charPtr); Block & block = blocks.at(charPtr); assert(block.free == false); assert(prev.ptr == NULL || prev.ptr + prev.size == block.ptr); assert(next.ptr == NULL || block.ptr + block.size == next.ptr); /* prev is busy and next is busy */ /* just mark current block as free */ if(!prev.free && !next.free) { markBlockFree(block); } /* prev is free and next is busy */ /* concat prev and curr block into one free block */ else if(prev.free && !next.free) { resizeBlock(prev, prev.size + block.size); removeBlock(block); } /* prev is busy and next is free */ /* concat curr and next block into one free block */ else if(!prev.free && next.free) { resizeBlock(block, block.size + next.size); removeBlock(next); markBlockFree(block); } /* concat all three blocks into one block*/ else if(prev.free && next.free) { resizeBlock(prev, prev.size + block.size + next.size); removeBlock(block); removeBlock(next); } #ifdef SELFTEST selfTest(); #endif }