コード例 #1
0
void BlockAllocator::blockFreeingThreadMain()
{
    size_t currentNumberOfEmptyRegions;
    while (!m_blockFreeingThreadShouldQuit) {
        // Generally wait for one second before scavenging free blocks. This
        // may return early, particularly when we're being asked to quit.
        waitForRelativeTime(1.0);
        if (m_blockFreeingThreadShouldQuit)
            break;
        
        if (m_isCurrentlyAllocating) {
            m_isCurrentlyAllocating = false;
            continue;
        }

        // Sleep until there is actually work to do rather than waking up every second to check.
        {
            MutexLocker locker(m_emptyRegionConditionLock);
            SpinLockHolder regionLocker(&m_regionLock);
            while (!m_numberOfEmptyRegions && !m_blockFreeingThreadShouldQuit) {
                m_regionLock.Unlock();
                m_emptyRegionCondition.wait(m_emptyRegionConditionLock);
                m_regionLock.Lock();
            }
            currentNumberOfEmptyRegions = m_numberOfEmptyRegions;
        }
        
        size_t desiredNumberOfEmptyRegions = currentNumberOfEmptyRegions / 2;
        
        while (!m_blockFreeingThreadShouldQuit) {
            Region* region;
            {
                SpinLockHolder locker(&m_regionLock);
                if (m_numberOfEmptyRegions <= desiredNumberOfEmptyRegions)
                    region = 0;
                else {
                    region = m_emptyRegions.removeHead();
                    RELEASE_ASSERT(region);
                    m_numberOfEmptyRegions--;
                }
            }
            
            if (!region)
                break;
            
            delete region;
        }
    }
}
コード例 #2
0
void BlockAllocator::blockFreeingThreadMain()
{
    while (!m_blockFreeingThreadShouldQuit) {
        // Generally wait for one second before scavenging free blocks. This
        // may return early, particularly when we're being asked to quit.
        waitForRelativeTime(1.0);
        if (m_blockFreeingThreadShouldQuit)
            break;
        
        if (m_isCurrentlyAllocating) {
            m_isCurrentlyAllocating = false;
            continue;
        }

        // Now process the list of free blocks. Keep freeing until half of the
        // blocks that are currently on the list are gone. Assume that a size_t
        // field can be accessed atomically.
        size_t currentNumberOfFreeBlocks = m_numberOfFreeBlocks;
        if (!currentNumberOfFreeBlocks)
            continue;
        
        size_t desiredNumberOfFreeBlocks = currentNumberOfFreeBlocks / 2;
        
        while (!m_blockFreeingThreadShouldQuit) {
            MarkedBlock* block;
            {
                MutexLocker locker(m_freeBlockLock);
                if (m_numberOfFreeBlocks <= desiredNumberOfFreeBlocks)
                    block = 0;
                else {
                    // FIXME: How do we know this is a MarkedBlock? It could be a CopiedBlock.
                    block = static_cast<MarkedBlock*>(m_freeBlocks.removeHead());
                    ASSERT(block);
                    m_numberOfFreeBlocks--;
                }
            }
            
            if (!block)
                break;
            
            MarkedBlock::destroy(block);
        }
    }
}