- assert(!allThreadsShouldExit);
-
- threads[threadID].state = THREAD_SEARCHING;
-
- // Copy SplitPoint position and search stack and call search()
- // with SplitPoint template parameter set to true.
- SearchStack ss[PLY_MAX_PLUS_2];
- SplitPoint* tsp = threads[threadID].splitPoint;
- Position pos(*tsp->pos, threadID);
-
- memcpy(ss, tsp->ss - 1, 4 * sizeof(SearchStack));
- (ss+1)->sp = tsp;
-
- if (tsp->pvNode)
- search<PV, true, false>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
- else
- search<NonPV, true, false>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
-
- assert(threads[threadID].state == THREAD_SEARCHING);
-
- threads[threadID].state = THREAD_AVAILABLE;
-
- // Wake up master thread so to allow it to return from the idle loop in
- // case we are the last slave of the split point.
- if (useSleepingThreads && threadID != tsp->master && threads[tsp->master].state == THREAD_AVAILABLE)
- wake_sleeping_thread(tsp->master);
- }
-
- // 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.
- for (i = 0; sp && i < activeThreads && !sp->slaves[i]; i++) {}
- allFinished = (i == activeThreads);
-
- if (allFinished)
- {
- // 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);
-
- for (i = 0; i < MAX_THREADS; i++)
- {
- lock_init(&sleepLock[i]);
- cond_init(&sleepCond[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);