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) { 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; }
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); } }