return DrawValue[pos.side_to_move()];
// Step 3. Mate distance pruning. Even if we mate at the next move our score
return DrawValue[pos.side_to_move()];
// Step 3. Mate distance pruning. Even if we mate at the next move our score
(ss+1)->skipNullMove = true;
nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
: - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R);
(ss+1)->skipNullMove = false;
(ss+1)->skipNullMove = true;
nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
: - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R);
(ss+1)->skipNullMove = false;
- && depth >= Threads.min_split_depth()
- && Threads.available_slave_exists(thisThread))
+ && depth >= Threads.minimumSplitDepth
+ && Threads.slave_available(thisThread)
+ && thisThread->splitPointsSize < MAX_SPLITPOINTS_PER_THREAD)
return DrawValue[pos.side_to_move()];
// Transposition table lookup. At PV nodes, we don't use the TT for
return DrawValue[pos.side_to_move()];
// Transposition table lookup. At PV nodes, we don't use the TT for
&& pos.is_pseudo_legal(m = tte->move()) // Local copy, TT could change
&& pos.pl_move_is_legal(m, pos.pinned_pieces())
&& ply < MAX_PLY
&& pos.is_pseudo_legal(m = tte->move()) // Local copy, TT could change
&& pos.pl_move_is_legal(m, pos.pinned_pieces())
&& ply < MAX_PLY
- // Pointer 'sp_master', if non-NULL, points to the active SplitPoint
- // object for which the thread is the master.
- const SplitPoint* sp_master = splitPointsCnt ? curSplitPoint : NULL;
+ // Pointer 'this_sp' is not null only if we are called from split(), and not
+ // at the thread creation. So it means we are the split point's master.
+ const SplitPoint* this_sp = splitPointsSize ? activeSplitPoint : NULL;
- // 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.
- while (!sp_master || sp_master->slavesMask)
+ // 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.
+ while (!this_sp || this_sp->slavesMask)
- // If we are not searching, wait for a condition to be signaled
- // instead of wasting CPU time polling for work.
- while (do_exit || (!is_searching && Threads.sleepWhileIdle))
+ // If we are not searching, wait for a condition to be signaled instead of
+ // wasting CPU time polling for work.
+ while ((!searching && Threads.sleepWhileIdle) || exit)
- // If we are master and all slaves have finished don't go to sleep
- if (sp_master && !sp_master->slavesMask)
+ // If we are master and all slaves have finished then exit idle_loop
+ if (this_sp && !this_sp->slavesMask)
// Do sleep after retesting sleep conditions under lock protection, in
// particular we need to avoid a deadlock in case a master thread has,
// 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 (!is_searching && Threads.sleepWhileIdle)
+ // in the meanwhile, allocated us and sent the notify_one() call before
+ // we had the chance to grab the lock.
+ if (!searching && !exit)
sleepCondition.wait(mutex);
mutex.unlock();
}
// If this thread has been assigned work, launch a search
sleepCondition.wait(mutex);
mutex.unlock();
}
// If this thread has been assigned work, launch a search
search<SplitPointRoot>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
search<SplitPointRoot>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
search<SplitPointPV>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
search<SplitPointPV>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
search<SplitPointNonPV>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
search<SplitPointNonPV>(pos, ss+1, sp->alpha, sp->beta, sp->depth);
- // 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.
+ // 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.
// Loop across all split points and sum accumulated SplitPoint nodes plus
// all the currently active slaves positions.
for (size_t i = 0; i < Threads.size(); i++)
// Loop across all split points and sum accumulated SplitPoint nodes plus
// all the currently active slaves positions.
for (size_t i = 0; i < Threads.size(); i++)