void ThreadsManager::init() {
+ read_uci_options();
+
cond_init(sleepCond);
lock_init(splitLock);
template <bool Fake>
Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
- Value bestValue, Depth depth, Move threatMove,
- int moveCount, MovePicker* mp, int nodeType) {
+ Value bestValue, Move* bestMove, Depth depth,
+ Move threatMove, int moveCount, MovePicker *mp, int nodeType) {
assert(pos.pos_is_ok());
assert(bestValue > -VALUE_INFINITE);
assert(bestValue <= alpha);
return bestValue;
// Pick the next available split point from the split point stack
- SplitPoint* sp = &masterThread.splitPoints[masterThread.splitPointsCnt];
+ SplitPoint* sp = &masterThread.splitPoints[masterThread.splitPointsCnt++];
sp->parent = masterThread.curSplitPoint;
sp->master = master;
sp->cutoff = false;
sp->slavesMask = 1ULL << master;
sp->depth = depth;
+ sp->bestMove = *bestMove;
sp->threatMove = threatMove;
sp->alpha = alpha;
sp->beta = beta;
assert(masterThread.is_searching);
+ masterThread.curSplitPoint = sp;
int slavesCnt = 0;
// Try to allocate available threads and ask them to start searching setting
break;
}
- masterThread.curSplitPoint = sp;
- masterThread.splitPointsCnt++;
-
lock_release(splitLock);
lock_release(sp->lock);
// the thread will return from the idle loop when all slaves have finished
// their work at this split point.
if (slavesCnt || Fake)
+ {
masterThread.idle_loop(sp);
+ // In helpful master concept a master can help only a sub-tree of its split
+ // point, and because here is all finished is not possible master is booked.
+ assert(!masterThread.is_searching);
+ }
+
// We have returned from the idle loop, which means that all threads are
- // finished. Note that setting is_searching and decreasing activeSplitPoints is
+ // finished. Note that setting is_searching and decreasing splitPointsCnt is
// done under lock protection to avoid a race with Thread::is_available_to().
lock_grab(sp->lock); // To protect sp->nodes
lock_grab(splitLock);
masterThread.splitPointsCnt--;
masterThread.curSplitPoint = sp->parent;
pos.set_nodes_searched(pos.nodes_searched() + sp->nodes);
+ *bestMove = sp->bestMove;
lock_release(splitLock);
lock_release(sp->lock);
}
// Explicit template instantiations
-template Value ThreadsManager::split<false>(Position&, Stack*, Value, Value, Value, Depth, Move, int, MovePicker*, int);
-template Value ThreadsManager::split<true>(Position&, Stack*, Value, Value, Value, Depth, Move, int, MovePicker*, int);
+template Value ThreadsManager::split<false>(Position&, Stack*, Value, Value, Value, Move*, Depth, Move, int, MovePicker*, int);
+template Value ThreadsManager::split<true>(Position&, Stack*, Value, Value, Value, Move*, Depth, Move, int, MovePicker*, int);
// ThreadsManager::set_timer() is used to set the timer to trigger after msec