From: Marco Costalba Date: Sun, 27 Nov 2011 11:16:23 +0000 (+0100) Subject: After a "stop" do not read new input until search finishes X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=6809b57cfc47321826f01253241afef8b4380612 After a "stop" do not read new input until search finishes Unfortunatly xboard sends immediately the new position to search after sending "stop" when we have a ponder miss. Becuase main thread position is not copied but is referenced directly from root position and the latter is modified by the "position.." UCI command we end up with the working position that changes under our feet while the search is still recovering after the "stop" and this causes a crash. This happens only with the (broken) xboard, native UCI does not have this problem. Reported by otello1984 No functional change. Signed-off-by: Marco Costalba --- diff --git a/src/thread.cpp b/src/thread.cpp index e48ea6fd..536f22c1 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -423,6 +423,23 @@ void Thread::main_loop() { } +// ThreadsManager::wait_end_of_search() blocks UI thread until main thread has +// returned to sleep in main_loop(). It is needed becuase xboard sends immediately +// new position to search after a "stop" due to ponder miss. + +void ThreadsManager::wait_end_of_search() { + + Thread& main = threads[0]; + + lock_grab(&main.sleepLock); + + while (!main.do_sleep) + cond_wait(&sleepCond, &main.sleepLock); + + lock_release(&main.sleepLock); +} + + // ThreadsManager::start_thinking() is used by UI thread to wake up the main // thread parked in main_loop() and starting a new search. If asyncMode is true // then function returns immediately, otherwise caller is blocked waiting for @@ -432,11 +449,10 @@ void ThreadsManager::start_thinking(bool asyncMode) { Thread& main = threads[0]; - lock_grab(&main.sleepLock); - // Wait main thread has finished before to launch a new search - while (!main.do_sleep) - cond_wait(&sleepCond, &main.sleepLock); + wait_end_of_search(); + + lock_grab(&main.sleepLock); // Reset signals before to start the search memset((void*)&Search::Signals, 0, sizeof(Search::Signals)); diff --git a/src/thread.h b/src/thread.h index df42c5aa..95ec1292 100644 --- a/src/thread.h +++ b/src/thread.h @@ -120,6 +120,7 @@ public: void start_thinking(bool asyncMode = true); void set_timer(int msec); void wait_for_stop_or_ponderhit(); + void wait_end_of_search(); template Value split(Position& pos, SearchStack* ss, Value alpha, Value beta, Value bestValue, diff --git a/src/uci.cpp b/src/uci.cpp index 72e3d0bd..57a31ad6 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -72,6 +72,7 @@ void uci_loop() { quit = (token == "quit"); Search::Signals.stop = true; Threads[0].wake_up(); // In case is waiting for stop or ponderhit + Threads.wait_end_of_search(); // Block here until search finishes } else if (cmd == "ponderhit")