From 8fa53a5b92bdfce4613ef04b88715ec9ccd9864c Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 6 Nov 2011 11:59:07 +0100 Subject: [PATCH] Better define wait_for_stop_or_ponderhit() Use do_uci_async_cmd() instead of process input commands directly and clarify that what we are waiting for is something that is able to raise StopRequest flag. Also fix some stale comments in do_uci_async_cmd(). Here we need to reset Limits.ponder only upon receiving "ponderhit". In the case of "quit" or "stop" resetting Limits.ponder has no effect because the search is going to be stopped anyway. No functional change. Signed-off-by: Marco Costalba --- src/search.cpp | 51 +++++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index fefc8864..bdb64ab5 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -353,7 +353,7 @@ int64_t perft(Position& pos, Depth depth) { bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { - static Book book; // Define static to initialize the PRNG only once + static Book book; // Defined static to initialize the PRNG only once // Initialize global search-related variables StopOnPonderhit = StopRequest = QuitRequest = AspirationFailLow = false; @@ -361,7 +361,7 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { Limits = limits; TimeMgr.init(Limits, pos.startpos_ply_counter()); - // Set output steram in normal or chess960 mode + // Set output stream in normal or chess960 mode cout << set960(pos.is_chess960()); // Look for a book move @@ -381,7 +381,8 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { } } - // Set best timer interval to avoid lagging under time pressure + // Set best timer interval to avoid lagging under time pressure. Timer is + // used to check for remaining available thinking time. if (TimeMgr.available_time()) Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 8, 20))); else @@ -415,7 +416,11 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { Threads[i].maxPly = 0; } - // Write to log file and keep it open to be accessed during the search + // Start async mode to catch UCI commands sent to us while searching, + // like "quit", "stop", etc. + Threads.start_listener(); + + // Write current search header to log file if (Options["Use Search Log"].value()) { Log log(Options["Search Log Filename"].value()); @@ -428,17 +433,11 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { << endl; } - // Start async mode to catch UCI commands sent to us while searching, - // like "quit", "stop", etc. - Threads.start_listener(); - // We're ready to start thinking. Call the iterative deepening loop function Move ponderMove = MOVE_NONE; Move bestMove = id_loop(pos, searchMoves, &ponderMove); - Threads.set_timer(0); - - // Write final search statistics and close log file + // Write current search final statistics to log file if (Options["Use Search Log"].value()) { int e = elapsed_search_time(); @@ -460,9 +459,12 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { // From now on any UCI command will be read in-sync with Threads.getline() Threads.stop_listener(); + // Stop timer, no need to check for available time any more + Threads.set_timer(0); + // If we are pondering or in infinite search, we shouldn't print the // best move before we are told to do so. - if (!StopRequest && (Limits.ponder || Limits.infinite)) + if (Limits.ponder || Limits.infinite) wait_for_stop_or_ponderhit(); // Could be MOVE_NONE when searching on a stalemate position @@ -1900,19 +1902,19 @@ split_point_start: // At split points actual search starts from here // while the program is pondering. The point is to work around a wrinkle in // the UCI protocol: When pondering, the engine is not allowed to give a // "bestmove" before the GUI sends it a "stop" or "ponderhit" command. - // We simply wait here until one of these commands is sent, and return, - // after which the bestmove and pondermove will be printed. + // We simply wait here until one of these commands (that raise StopRequest) is + // sent, and return, after which the bestmove and pondermove will be printed. void wait_for_stop_or_ponderhit() { string cmd; + StopOnPonderhit = true; - // Wait for a command from stdin - while (cmd != "ponderhit" && cmd != "stop" && cmd != "quit") + while (!StopRequest) + { Threads.getline(cmd); - - if (cmd == "quit") - QuitRequest = true; + do_uci_async_cmd(cmd); + } } @@ -2173,18 +2175,11 @@ void Thread::idle_loop(SplitPoint* sp) { void do_uci_async_cmd(const std::string& cmd) { if (cmd == "quit") - { - // Quit the program as soon as possible - Limits.ponder = false; QuitRequest = StopRequest = true; - } + else if (cmd == "stop") - { - // Stop calculating as soon as possible, but still send the "bestmove" - // and possibly the "ponder" token when finishing the search. - Limits.ponder = false; StopRequest = true; - } + else if (cmd == "ponderhit") { // The opponent has played the expected move. GUI sends "ponderhit" if -- 2.39.2