void ThreadPoolImpl::Stop()
{
    if (m_ok)
    {
        // wait for all threads to idle
        while (PoolThread::s_sleepCount < m_numThreads)
        {
            GIVE_UP_TIME();
        }

        // set invalid flag, then wake them up so they exit their main func
        m_ok = false;
        int exited_count;
        do
        {
            pokeIdleThread();
            GIVE_UP_TIME();
            exited_count = 0;
            for (int i = 0; i < m_numThreads; i++)
            {
                exited_count += m_threads[i].isExited() ? 1 : 0;
            }
        }
        while (exited_count < m_numThreads);

        // join each thread to cleanup resources
        for (int i = 0; i < m_numThreads; i++)
        {
            m_threads[i].stop();
        }
    }
}
ThreadPoolImpl::ThreadPoolImpl(int numThreads)
    : m_ok(false)
    , m_referenceCount(1)
    , m_firstProvider(NULL)
    , m_lastProvider(NULL)
{
    if (numThreads == 0)
        numThreads = get_cpu_count();

    char *buffer = new char[sizeof(PoolThread) * numThreads];
    m_threads = reinterpret_cast<PoolThread*>(buffer);
    m_numThreads = numThreads;

    if (m_threads)
    {
        m_ok = true;
        for (int i = 0; i < numThreads; i++)
        {
            new (buffer)PoolThread(*this);
            buffer += sizeof(PoolThread);
            m_ok = m_ok && m_threads[i].start();
        }

        // Wait for threads to spin up and idle
        while (PoolThread::s_sleepCount < m_numThreads)
        {
            GIVE_UP_TIME();
        }
    }
}
Example #3
0
void ThreadPool::stopWorkers()
{
    if (m_workers)
    {
        m_isActive = false;
        for (int i = 0; i < m_numWorkers; i++)
        {
            while (!(m_sleepBitmap & ((sleepbitmap_t)1 << i)))
                GIVE_UP_TIME();
            m_workers[i].awaken();
            m_workers[i].stop();
        }
    }
}
Example #4
0
void ThreadPoolImpl::waitForAllIdle()
{
    if (!m_ok)
        return;

    int id = 0;
    do
    {
        int word = id >> 6;
        uint64_t bit = 1LL << (id & 63);
        if (m_sleepMap[word] & bit)
        {
            id++;
        }
        else
        {
            GIVE_UP_TIME();
        }
    }
    while (id < m_numThreads);
}
/* Ensure all threads are either idle, or have made a full
 * pass through the provider list, ensuring dequeued providers
 * are safe for deletion. */
void ThreadPoolImpl::FlushProviderList()
{
    for (int i = 0; i < m_numThreads; i++)
    {
        m_threads[i].markDirty();
    }

    int i;
    do
    {
        for (i = 0; i < m_numThreads; i++)
        {
            if (m_threads[i].isDirty())
            {
                GIVE_UP_TIME();
                break;
            }
        }
    }
    while (i < m_numThreads);
}