mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
Re-apply the fix for Limits::ponder race
But this time correctly set Threads.ponder We avoid using 'limits' for passing pondering flag because we don't want to have 2 ponder variables in search scope: Search::Limits.ponder and Threads.ponder. This would be confusing also because limits.ponder is set at the beginning of the search and never changes, instead Threads.ponder can change value asynchronously during search. No functional change.
This commit is contained in:
parent
44236f4ed9
commit
66c5eaebd8
5 changed files with 19 additions and 18 deletions
|
@ -277,7 +277,7 @@ void MainThread::search() {
|
||||||
// the UCI protocol states that we shouldn't print the best move before the
|
// the UCI protocol states that we shouldn't print the best move before the
|
||||||
// GUI sends a "stop" or "ponderhit" command. We therefore simply wait here
|
// GUI sends a "stop" or "ponderhit" command. We therefore simply wait here
|
||||||
// until the GUI sends one of those commands (which also raises Threads.stop).
|
// until the GUI sends one of those commands (which also raises Threads.stop).
|
||||||
if (!Threads.stop && (Limits.ponder || Limits.infinite))
|
if (!Threads.stop && (Threads.ponder || Limits.infinite))
|
||||||
{
|
{
|
||||||
Threads.stopOnPonderhit = true;
|
Threads.stopOnPonderhit = true;
|
||||||
wait(Threads.stop);
|
wait(Threads.stop);
|
||||||
|
@ -499,7 +499,7 @@ void Thread::search() {
|
||||||
{
|
{
|
||||||
// If we are allowed to ponder do not stop the search now but
|
// If we are allowed to ponder do not stop the search now but
|
||||||
// keep pondering until the GUI sends "ponderhit" or "stop".
|
// keep pondering until the GUI sends "ponderhit" or "stop".
|
||||||
if (Limits.ponder)
|
if (Threads.ponder)
|
||||||
Threads.stopOnPonderhit = true;
|
Threads.stopOnPonderhit = true;
|
||||||
else
|
else
|
||||||
Threads.stop = true;
|
Threads.stop = true;
|
||||||
|
@ -1489,7 +1489,7 @@ moves_loop: // When in check search starts from here
|
||||||
}
|
}
|
||||||
|
|
||||||
// An engine may not stop pondering until told so by the GUI
|
// An engine may not stop pondering until told so by the GUI
|
||||||
if (Limits.ponder)
|
if (Threads.ponder)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( (Limits.use_time_management() && elapsed > Time.maximum() - 10)
|
if ( (Limits.use_time_management() && elapsed > Time.maximum() - 10)
|
||||||
|
|
|
@ -72,14 +72,13 @@ typedef std::vector<RootMove> RootMoves;
|
||||||
|
|
||||||
|
|
||||||
/// LimitsType struct stores information sent by GUI about available time to
|
/// LimitsType struct stores information sent by GUI about available time to
|
||||||
/// search the current move, maximum depth/time, if we are in analysis mode or
|
/// search the current move, maximum depth/time, or if we are in analysis mode.
|
||||||
/// if we have to ponder while it's our opponent's turn to move.
|
|
||||||
|
|
||||||
struct LimitsType {
|
struct LimitsType {
|
||||||
|
|
||||||
LimitsType() { // Init explicitly due to broken value-initialization of non POD in MSVC
|
LimitsType() { // Init explicitly due to broken value-initialization of non POD in MSVC
|
||||||
nodes = time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] =
|
nodes = time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] =
|
||||||
npmsec = movestogo = depth = movetime = mate = infinite = ponder = 0;
|
npmsec = movestogo = depth = movetime = mate = infinite = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool use_time_management() const {
|
bool use_time_management() const {
|
||||||
|
@ -87,7 +86,7 @@ struct LimitsType {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Move> searchmoves;
|
std::vector<Move> searchmoves;
|
||||||
int time[COLOR_NB], inc[COLOR_NB], npmsec, movestogo, depth, movetime, mate, infinite, ponder;
|
int time[COLOR_NB], inc[COLOR_NB], npmsec, movestogo, depth, movetime, mate, infinite;
|
||||||
int64_t nodes;
|
int64_t nodes;
|
||||||
TimePoint startTime;
|
TimePoint startTime;
|
||||||
};
|
};
|
||||||
|
|
|
@ -183,11 +183,12 @@ uint64_t ThreadPool::tb_hits() const {
|
||||||
/// and starts a new search, then returns immediately.
|
/// and starts a new search, then returns immediately.
|
||||||
|
|
||||||
void ThreadPool::start_thinking(Position& pos, StateListPtr& states,
|
void ThreadPool::start_thinking(Position& pos, StateListPtr& states,
|
||||||
const Search::LimitsType& limits) {
|
const Search::LimitsType& limits, bool ponderMode) {
|
||||||
|
|
||||||
main()->wait_for_search_finished();
|
main()->wait_for_search_finished();
|
||||||
|
|
||||||
stopOnPonderhit = stop = false;
|
stopOnPonderhit = stop = false;
|
||||||
|
ponder = ponderMode;
|
||||||
Search::Limits = limits;
|
Search::Limits = limits;
|
||||||
Search::RootMoves rootMoves;
|
Search::RootMoves rootMoves;
|
||||||
|
|
||||||
|
|
|
@ -96,12 +96,12 @@ struct ThreadPool : public std::vector<Thread*> {
|
||||||
void exit(); // be initialized and valid during the whole thread lifetime.
|
void exit(); // be initialized and valid during the whole thread lifetime.
|
||||||
|
|
||||||
MainThread* main() { return static_cast<MainThread*>(at(0)); }
|
MainThread* main() { return static_cast<MainThread*>(at(0)); }
|
||||||
void start_thinking(Position&, StateListPtr&, const Search::LimitsType&);
|
void start_thinking(Position&, StateListPtr&, const Search::LimitsType&, bool = false);
|
||||||
void read_uci_options();
|
void read_uci_options();
|
||||||
uint64_t nodes_searched() const;
|
uint64_t nodes_searched() const;
|
||||||
uint64_t tb_hits() const;
|
uint64_t tb_hits() const;
|
||||||
|
|
||||||
std::atomic_bool stop, stopOnPonderhit;
|
std::atomic_bool stop, ponder, stopOnPonderhit;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StateListPtr setupStates;
|
StateListPtr setupStates;
|
||||||
|
|
17
src/uci.cpp
17
src/uci.cpp
|
@ -115,6 +115,7 @@ namespace {
|
||||||
|
|
||||||
Search::LimitsType limits;
|
Search::LimitsType limits;
|
||||||
string token;
|
string token;
|
||||||
|
bool ponderMode = false;
|
||||||
|
|
||||||
limits.startTime = now(); // As early as possible!
|
limits.startTime = now(); // As early as possible!
|
||||||
|
|
||||||
|
@ -133,9 +134,9 @@ namespace {
|
||||||
else if (token == "movetime") is >> limits.movetime;
|
else if (token == "movetime") is >> limits.movetime;
|
||||||
else if (token == "mate") is >> limits.mate;
|
else if (token == "mate") is >> limits.mate;
|
||||||
else if (token == "infinite") limits.infinite = 1;
|
else if (token == "infinite") limits.infinite = 1;
|
||||||
else if (token == "ponder") limits.ponder = 1;
|
else if (token == "ponder") ponderMode = true;
|
||||||
|
|
||||||
Threads.start_thinking(pos, States, limits);
|
Threads.start_thinking(pos, States, limits, ponderMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -167,11 +168,11 @@ void UCI::loop(int argc, char* argv[]) {
|
||||||
token.clear(); // getline() could return empty or blank line
|
token.clear(); // getline() could return empty or blank line
|
||||||
is >> skipws >> token;
|
is >> skipws >> token;
|
||||||
|
|
||||||
// The GUI sends 'ponderhit' to tell us to ponder on the same move the
|
// The GUI sends 'ponderhit' to tell us the user has played the expected move.
|
||||||
// opponent has played. In case Threads.stopOnPonderhit is set we are
|
// So 'ponderhit' will be sent if we were told to ponder on the same move the
|
||||||
// waiting for 'ponderhit' to stop the search (for instance because we
|
// user has played. We should continue searching but switch from pondering to
|
||||||
// already ran out of time), otherwise we should continue searching but
|
// normal search. In case Threads.stopOnPonderhit is set we are waiting for
|
||||||
// switching from pondering to normal search.
|
// 'ponderhit' to stop the search, for instance if max search depth is reached.
|
||||||
if ( token == "quit"
|
if ( token == "quit"
|
||||||
|| token == "stop"
|
|| token == "stop"
|
||||||
|| (token == "ponderhit" && Threads.stopOnPonderhit))
|
|| (token == "ponderhit" && Threads.stopOnPonderhit))
|
||||||
|
@ -180,7 +181,7 @@ void UCI::loop(int argc, char* argv[]) {
|
||||||
Threads.main()->start_searching(true); // Could be sleeping
|
Threads.main()->start_searching(true); // Could be sleeping
|
||||||
}
|
}
|
||||||
else if (token == "ponderhit")
|
else if (token == "ponderhit")
|
||||||
Search::Limits.ponder = 0; // Switch to normal search
|
Threads.ponder = false; // Switch to normal search
|
||||||
|
|
||||||
else if (token == "uci")
|
else if (token == "uci")
|
||||||
sync_cout << "id name " << engine_info(true)
|
sync_cout << "id name " << engine_info(true)
|
||||||
|
|
Loading…
Add table
Reference in a new issue