예제 #1
0
MemoryPool::MemoryPool(bool shared, int rounding, int cutoff, int minAlloc)
    :	roundingSize(rounding), threshold(cutoff), minAllocation(minAlloc),
      threadShared(shared), pool_destroying(false), stats(default_stats_group), parent(NULL)
{
    const size_t vecSize = (cutoff + rounding) / rounding;
    init(allocRaw(vecSize * sizeof(void*)), vecSize);
}
예제 #2
0
파일: mempool.hpp 프로젝트: mingspy/mseg
    void *allocAligned( std::size_t size )
    {
        // Calculate aligned pointer
        char * result = align( m_ptr );

        // If not enough memory left in current pool, allocate a new pool
        if ( result + size > m_end ) {
            // Calculate required pool size (may be bigger than CLAS_DYNAMIC_POOL_SIZE)
            std::size_t pool_size = m_dynamicSize;
            if ( pool_size < size )
                pool_size = size;

            // Allocate
            // 2 alignments required in worst case: one for header, one for actual allocation
            std::size_t alloc_size = sizeof( header ) + ( 2 * CLAS_ALIGNMENT - 2 ) + pool_size;
            char *raw_memory = allocRaw( alloc_size );

            // Setup new pool in allocated memory
            char *pool = align( raw_memory );
            header *new_header = reinterpret_cast<header *>( pool );
            new_header->previous_begin = m_begin;
            m_begin = raw_memory;
            m_ptr = pool + sizeof( header );
            m_end = raw_memory + alloc_size;

            // Calculate aligned pointer again using new pool
            result = align( m_ptr );
        }

        // Update pool and return aligned pointer
        m_ptr = result + size;
        return result;
    }
예제 #3
0
MemBlock* MemoryPool::alloc(const size_t length) throw (OOM_EXCEPTION)
{
    MutexLockGuard guard(mutex, "MemoryPool::alloc");

    // If this is a small block, look for it there

    if (length <= threshold)
    {
        unsigned int slot = length / roundingSize;
        MemBlock* block;

        if (threadShared)
        {
            while (block = freeObjects[slot])
            {
                if (freeObjects[slot].compareExchange(block, block->next))
                {
#ifdef MEM_DEBUG
                    if (slot != block->length / roundingSize)
                        corrupt("length trashed for block in slot");
#endif
                    return block;
                }
            }
        }
        else
        {
            block = freeObjects[slot];

            if (block)
            {
                freeObjects[slot] = (MemBlock*) block->pool;

#ifdef MEM_DEBUG
                if (slot != block->length / roundingSize)
                    corrupt("length trashed for block in slot");
#endif
                return block;
            }
        }

        // See if some other hunk has unallocated space to use

        MemSmallHunk* hunk;

        for (hunk = smallHunks; hunk; hunk = hunk->nextHunk)
        {
            if (length <= hunk->spaceRemaining)
            {
                MemBlock* block = (MemBlock*) hunk->memory;
                hunk->memory += length;
                hunk->spaceRemaining -= length;
                block->length = length;

                return block;
            }
        }

        // No good so far.  Time for a new hunk

        hunk = (MemSmallHunk*) allocRaw(minAllocation);
        hunk->length = minAllocation - 16;
        hunk->nextHunk = smallHunks;
        smallHunks = hunk;

        size_t l = ROUNDUP(sizeof(MemSmallHunk), sizeof(double));
        block = (MemBlock*) ((UCHAR*) hunk + l);
        hunk->spaceRemaining = minAllocation - length - l;
        hunk->memory = (UCHAR*) block + length;
        block->length = length;

        return block;
    }

    /*
     *  OK, we've got a "big block" on on hands.  To maximize confusing, the indicated
     *  length of a free big block is the length of MemHeader plus body, explicitly
     *  excluding the MemFreeBlock and MemBigHeader fields.

                         [MemHeader::length]

    	                <---- MemBlock ---->

    	*--------------*----------*---------*
    	| MemBigHeader | MemHeader |  Body  |
    	*--------------*----------*---------*

    	 <---- MemBigObject ----->

    	*--------------*----------*---------------*
    	| MemBigHeader | MemHeader | MemFreeBlock |
    	*--------------*----------*---------------*

    	 <--------------- MemFreeBlock ---------->
     */


    MemFreeBlock* freeBlock;

    for (freeBlock = freeBlocks.nextLarger; freeBlock != &freeBlocks; freeBlock = freeBlock->nextLarger)
    {
        if (freeBlock->memHeader.length >= length)
        {
            remove(freeBlock);
            MemBlock* block = (MemBlock*) &freeBlock->memHeader;

            // Compute length (MemHeader + body) for new free block

            unsigned int tail = block->length - length;

            // If there isn't room to split off a new free block, allocate the whole thing

            if (tail < sizeof(MemFreeBlock))
            {
                block->pool = this;
                return block;
            }

            // Otherwise, chop up the block

            MemBigObject* newBlock = freeBlock;
            freeBlock = (MemFreeBlock*) ((UCHAR*) block + length);
            freeBlock->memHeader.length = tail - sizeof(MemBigObject);
            block->length = length;
            block->pool = this;

            if (freeBlock->next = newBlock->next)
                freeBlock->next->prior = freeBlock;

            newBlock->next = freeBlock;
            freeBlock->prior = newBlock;
            freeBlock->memHeader.pool = NULL;		// indicate block is free
            insert(freeBlock);

            return block;
        }
    }

    // Didn't find existing space -- allocate new hunk

    size_t hunkLength = sizeof(MemBigHunk) + sizeof(MemBigHeader) + length;
    size_t freeSpace = 0;

    // If the hunk size is sufficient below minAllocation, allocate extra space

    if (hunkLength + sizeof(MemBigObject) + threshold < minAllocation)
    {
        hunkLength = minAllocation;
        //freeSpace = hunkLength - 2 * sizeof(MemBigObject) - length;
        freeSpace = hunkLength - sizeof(MemBigHunk) - 2 * sizeof(MemBigHeader) - length;
    }

    // Allocate the new hunk

    MemBigHunk* hunk = (MemBigHunk*) allocRaw(hunkLength);
    hunk->nextHunk = bigHunks;
    bigHunks = hunk;
    hunk->length = hunkLength;

    // Create the new block

    MemBigObject* newBlock = (MemBigObject*) &hunk->blocks;
    newBlock->prior = NULL;
    newBlock->next = NULL;

    MemBlock* block = (MemBlock*) &newBlock->memHeader;
    block->pool = this;
    block->length = length;

    // If there is space left over, create a free block

    if (freeSpace)
    {
        freeBlock = (MemFreeBlock*) ((UCHAR*) block + length);
        freeBlock->memHeader.length = freeSpace;
        freeBlock->memHeader.pool = NULL;
        freeBlock->next = NULL;
        freeBlock->prior = newBlock;
        newBlock->next = freeBlock;
        insert(freeBlock);
    }

    return block;
}