+ return true;
+}
+
+
+// Thread::idle_loop() is where the thread is parked when it has no work to do.
+// The parameter 'sp', if non-NULL, is a pointer to an active SplitPoint object
+// for which the thread is the master.
+
+void Thread::idle_loop(SplitPoint* sp) {
+
+ while (true)
+ {
+ // If we are not searching, wait for a condition to be signaled
+ // instead of wasting CPU time polling for work.
+ while ( do_sleep
+ || do_terminate
+ || (Threads.use_sleeping_threads() && !is_searching))
+ {
+ assert((!sp && threadID) || Threads.use_sleeping_threads());
+
+ // Slave thread should exit as soon as do_terminate flag raises
+ if (do_terminate)
+ {
+ assert(!sp);
+ return;
+ }
+
+ // Grab the lock to avoid races with Thread::wake_up()
+ lock_grab(&sleepLock);
+
+ // If we are master and all slaves have finished don't go to sleep
+ if (sp && all_slaves_finished(sp))
+ {
+ lock_release(&sleepLock);
+ break;
+ }
+
+ // Do sleep after retesting sleep conditions under lock protection, in
+ // particular we need to avoid a deadlock in case a master thread has,
+ // in the meanwhile, allocated us and sent the wake_up() call before we
+ // had the chance to grab the lock.
+ if (do_sleep || !is_searching)
+ cond_wait(&sleepCond, &sleepLock);
+
+ lock_release(&sleepLock);
+ }
+
+ // If this thread has been assigned work, launch a search
+ if (is_searching)
+ {
+ assert(!do_terminate);
+
+ // Copy split point position and search stack and call search()
+ SearchStack ss[PLY_MAX_PLUS_2];
+ SplitPoint* tsp = splitPoint;
+ Position pos(*tsp->pos, threadID);
+
+ memcpy(ss, tsp->ss - 1, 4 * sizeof(SearchStack));
+ (ss+1)->sp = tsp;
+
+ if (tsp->nodeType == Root)
+ search<SplitPointRoot>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
+ else if (tsp->nodeType == PV)
+ search<SplitPointPV>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
+ else if (tsp->nodeType == NonPV)
+ search<SplitPointNonPV>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
+ else
+ assert(false);
+
+ assert(is_searching);
+
+ is_searching = false;
+
+ // 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 ( Threads.use_sleeping_threads()
+ && threadID != tsp->master
+ && !Threads[tsp->master].is_searching)
+ Threads[tsp->master].wake_up();
+ }
+
+ // 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.
+ if (sp && all_slaves_finished(sp))
+ {
+ // Because sp->is_slave[] is reset under lock protection,
+ // be sure sp->lock has been released before to return.
+ lock_grab(&(sp->lock));
+ lock_release(&(sp->lock));
+ return;
+ }