Esempio n. 1
0
void ThreadPool::shutDown() {
    Lock(poolLock);
    ThreadInfo *p;
    // note: do not terminate thread 0 (main thread) in this loop
    for (unsigned i = 1; i < nThreads; i++) {
        p = data[i];
        // All threads should be idle when this function is called.
        if (p->state == ThreadInfo::Idle) {
          // Set the thread to the terminating state that will force thread
          // procedure exit
          p->state = ThreadInfo::Terminating;
          // unblock the thread
          p->signal();
       }
       // wait for the thread to terminate
#ifdef _WIN32
       WaitForSingleObject(p->thread_id,INFINITE);
#else
       void *value_ptr;
       pthread_join(p->thread_id,&value_ptr);
#endif
       // Free thread data 
       delete p;
    }
    // now free main thread data
    delete data[0]->work;
    delete data[0]; // main thread structure
    Unlock(poolLock);
}
Esempio n. 2
0
void ThreadPool::resize(unsigned n, SearchController *controller) {
    if (n >= 1 && n < Constants::MaxCPUs && n != nThreads) {
        lock();
#ifdef NUMA
        topo.recalc();
#endif
        if (n>nThreads) {
            // growing
            while (n > nThreads) {
               data[nThreads] = new ThreadInfo(this,nThreads);
               nThreads++;
            }
        }
        else {
            // shrinking
            while (n < nThreads) {
                ThreadInfo *p = data[nThreads-1];
                p->state = ThreadInfo::Terminating;
                if (p->state == ThreadInfo::Idle) {
                    p->signal(); // unblock thread & exit thread proc
                    // wait for thread exit
#ifdef _WIN32
                    WaitForSingleObject(p->thread_id,INFINITE);
#else
                    void *value_ptr;
                    pthread_join(p->thread_id,&value_ptr);
#endif
                }
                delete p;
                data[nThreads] = NULL;
                --nThreads;
            }
        }
        unlock();
    }
    ASSERT(nThreads == n);
    availableMask = (n == 64) ? 0xffffffffffffffffULL :
       (1ULL << n)-1;
}
Esempio n. 3
0
void ThreadPool::checkIn(ThreadInfo *ti) {
#ifdef _THREAD_TRACE
    {
        std::ostringstream s;
        s << "checkIn: " << ti->index << " master=" <<
            ti->work->split->master->index << '\0';
        log(s.str());
    }
#endif
    Lock(poolLock);
    SplitPoint *split = ti->work->split;
    ThreadInfo *parent = split->master;
    Search *parentSearch = parent->work;
    // lock parent's stack
    Lock(parentSearch->splitLock);
    split->lock();
    // dissociate the thread from the parent
    ArasanSet<ThreadInfo *,Constants::MaxCPUs> &slaves =
        split->slaves;
    // remove ti from the list of slave threads in the parent
#ifdef _THREAD_TRACE
    {
        std::ostringstream s;
        s << "removing slave thread " <<  ti->index << " from master "
          << split->master->index << '\0';
        log(s.str());
    }
#endif
#ifdef _DEBUG
    ASSERT(slaves.remove(ti));
#else
    slaves.remove(ti);
#endif
    const int remaining = slaves.size();
    const bool top = split - parentSearch->splitStack + 1 == parentSearch->activeSplitPoints;
#ifdef _THREAD_TRACE
    {
        std::ostringstream s;
        s << "after checkIn: " << ti->index << " remaining: " << remaining << " top=" << top << '\0';
        log(s.str());
    }
#endif
    if (!remaining && top) {
        // all slave threads are completed, so signal parent that it
        // can exit its wait state and pop the split stack.
        ASSERT(parent);
        // Set parent state to Working before it even wakes up. This
        // ensures it will not be allocated to another split point.
        parent->state = ThreadInfo::Working;
        activeMask |= (1ULL << parent->index);
#ifdef _THREAD_TRACE
        std::ostringstream s;
        s << "thread " << ti->index <<  
            " signaling parent (" << parent->index << ")" << 
            " parent state=" << parent->state << '\0';
        log(s.str());
#endif
        ASSERT(parent->index != ti->index);
#ifdef _THREAD_TRACE
        log("signal",parent->index);
#endif
        parent->signal();
    }
    // ensure we we will wait when back in the idle loop
    ti->reset();
    split->unlock();
    Unlock(parentSearch->splitLock);
    Unlock(poolLock);
}