-#else
-
- DWORD WINAPI init_thread(LPVOID threadID) {
-
- ThreadsMgr.idle_loop(*(int*)threadID, NULL);
- return 0;
- }
-
-#endif
-
-
- /// The ThreadsManager class
-
-
- // idle_loop() is where the threads are parked when they have no work to do.
- // The parameter 'sp', if non-NULL, is a pointer to an active SplitPoint
- // object for which the current thread is the master.
-
- void ThreadsManager::idle_loop(int threadID, SplitPoint* sp) {
-
- assert(threadID >= 0 && threadID < MAX_THREADS);
-
- while (true)
- {
- // Slave threads can exit as soon as AllThreadsShouldExit raises,
- // master should exit as last one.
- if (AllThreadsShouldExit)
- {
- assert(!sp);
- threads[threadID].state = THREAD_TERMINATED;
- return;
- }
-
- // If we are not thinking, wait for a condition to be signaled
- // instead of wasting CPU time polling for work.
- while (threadID >= ActiveThreads || threads[threadID].state == THREAD_INITIALIZING)
- {
- assert(!sp);
- assert(threadID != 0);
-
- if (AllThreadsShouldExit)
- break;
-
- threads[threadID].state = THREAD_AVAILABLE;
-
- lock_grab(&WaitLock);
-
- if (threadID >= ActiveThreads || threads[threadID].state == THREAD_INITIALIZING)
- cond_wait(&WaitCond[threadID], &WaitLock);
-
- lock_release(&WaitLock);
- }
-
- // If this thread has been assigned work, launch a search
- if (threads[threadID].state == THREAD_WORKISWAITING)
- {
- assert(!AllThreadsShouldExit);
-
- threads[threadID].state = THREAD_SEARCHING;
-
- // Here we call search() with SplitPoint template parameter set to true
- SplitPoint* tsp = threads[threadID].splitPoint;
- Position pos(*tsp->pos, threadID);
- SearchStack* ss = tsp->sstack[threadID] + 1;
- ss->sp = tsp;
-
- if (tsp->pvNode)
- search<PV, true>(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
- else {
- search<NonPV, true>(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
- }
- assert(threads[threadID].state == THREAD_SEARCHING);
-
- threads[threadID].state = THREAD_AVAILABLE;
- }
-
- // If this thread is the master of a split point and all slaves have
- // finished their work at this split point, return from the idle loop.
- int i = 0;
- for ( ; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
-
- if (i == ActiveThreads)
- {
- // Because sp->slaves[] is reset under lock protection,
- // be sure sp->lock has been released before to return.
- lock_grab(&(sp->lock));
- lock_release(&(sp->lock));
-
- // In helpful master concept a master can help only a sub-tree, and
- // because here is all finished is not possible master is booked.
- assert(threads[threadID].state == THREAD_AVAILABLE);
-
- threads[threadID].state = THREAD_SEARCHING;
- return;
- }
- }
- }
-
-
- // init_threads() is called during startup. It launches all helper threads,
- // and initializes the split point stack and the global locks and condition
- // objects.
-
- void ThreadsManager::init_threads() {
-
- int i, arg[MAX_THREADS];
- bool ok;
-
- // Initialize global locks
- lock_init(&MPLock);
- lock_init(&WaitLock);
-
- for (i = 0; i < MAX_THREADS; i++)
- cond_init(&WaitCond[i]);
-
- // Initialize splitPoints[] locks
- for (i = 0; i < MAX_THREADS; i++)
- for (int j = 0; j < MAX_ACTIVE_SPLIT_POINTS; j++)
- lock_init(&(threads[i].splitPoints[j].lock));
-
- // Will be set just before program exits to properly end the threads
- AllThreadsShouldExit = false;
-
- // Threads will be put all threads to sleep as soon as created
- ActiveThreads = 1;
-
- // All threads except the main thread should be initialized to THREAD_INITIALIZING
- threads[0].state = THREAD_SEARCHING;
- for (i = 1; i < MAX_THREADS; i++)
- threads[i].state = THREAD_INITIALIZING;
-
- // Launch the helper threads
- for (i = 1; i < MAX_THREADS; i++)
- {
- arg[i] = i;
-
-#if !defined(_MSC_VER)
- pthread_t pthread[1];
- ok = (pthread_create(pthread, NULL, init_thread, (void*)(&arg[i])) == 0);
- pthread_detach(pthread[0]);
-#else
- ok = (CreateThread(NULL, 0, init_thread, (LPVOID)(&arg[i]), 0, NULL) != NULL);
-#endif
- if (!ok)
- {
- cout << "Failed to create thread number " << i << endl;
- exit(EXIT_FAILURE);
- }
-
- // Wait until the thread has finished launching and is gone to sleep
- while (threads[i].state == THREAD_INITIALIZING) {}
- }
- }