/* 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;
}
Beispiel #2
0
	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
	}