<< endl;
}
- for (int i = 0; i < Threads.size(); i++)
- {
- Threads[i].maxPly = 0;
- Threads[i].wake_up();
- }
+ Threads.set_size(Options["Threads"]);
// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
// but if we are pondering or in infinite search, we shouldn't print the best
// move before we are told to do so.
if (!Signals.stop && (Limits.ponder || Limits.infinite))
- Threads.wait_for_stop_or_ponderhit();
+ Threads[pos.thread()].wait_for_stop_or_ponderhit();
// Best move could be MOVE_NONE when searching on a stalemate position
cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960)
sp->bestValue = value;
sp->ss->bestMove = move;
sp->alpha = alpha;
- sp->is_betaCutoff = (value >= beta);
+
+ if (value >= beta)
+ sp->cutoff = true;
}
}
pos.do_move(m, *st++);
while ( (tte = TT.probe(pos.key())) != NULL
- && tte->move() != MOVE_NONE
- && pos.is_pseudo_legal(tte->move())
- && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
+ && (m = tte->move()) != MOVE_NONE // Local copy, TT entry could change
+ && pos.is_pseudo_legal(m)
+ && pos.pl_move_is_legal(m, pos.pinned_pieces())
&& ply < MAX_PLY
&& (!pos.is_draw<false>() || ply < 2))
{
- pv.push_back(tte->move());
- pos.do_move(tte->move(), *st++);
+ pv.push_back(m);
+ pos.do_move(m, *st++);
ply++;
}
pv.push_back(MOVE_NONE);
{
assert(!do_sleep && !do_exit);
- // Copy split point position and search stack and call search()
+ lock_grab(Threads.splitLock);
+
+ assert(is_searching);
+ SplitPoint* sp = curSplitPoint;
+
+ lock_release(Threads.splitLock);
+
Stack ss[MAX_PLY_PLUS_2];
- SplitPoint* sp = splitPoint;
Position pos(*sp->pos, threadID);
+ int master = sp->master;
memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
(ss+1)->sp = sp;
assert(is_searching);
- // We return from search with lock held
+ is_searching = false;
sp->slavesMask &= ~(1ULL << threadID);
sp->nodes += pos.nodes_searched();
- lock_release(sp->lock);
- is_searching = false;
+ // After releasing the lock we cannot access anymore any SplitPoint
+ // related data in a reliably way becuase it could have been released
+ // under our feet by the sp master.
+ lock_release(sp->lock);
// 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 != sp->master
- && !Threads[sp->master].is_searching)
- Threads[sp->master].wake_up();
+ && threadID != master
+ && !Threads[master].is_searching)
+ Threads[master].wake_up();
}
}
+ // 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(!is_searching);
}