diff --git a/src/benchmark.cpp b/src/benchmark.cpp index e27e81fe..fbf7b0e3 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -158,7 +158,7 @@ void benchmark(const Position& current, istream& is) { else { Threads.start_thinking(pos, limits, st); - Threads.wait_for_think_finished(); + Threads.main()->join(); nodes += Search::RootPos.nodes_searched(); } } diff --git a/src/thread.cpp b/src/thread.cpp index b4958ea3..a715d44e 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -251,7 +251,7 @@ void MainThread::idle_loop() { while (!thinking && !exit) { - Threads.sleepCondition.notify_one(); // Wake up the UI thread if needed + sleepCondition.notify_one(); // Wake up the UI thread if needed sleepCondition.wait(lk); } @@ -271,6 +271,15 @@ void MainThread::idle_loop() { } +// MainThread::join() waits for main thread to finish the search + +void MainThread::join() { + + std::unique_lock lk(mutex); + sleepCondition.wait(lk, [&]{ return !thinking; }); +} + + // ThreadPool::init() is called at startup to create and launch requested threads, // that will go immediately to sleep. We cannot use a c'tor because Threads is a // static object and we need a fully initialized engine at this point due to @@ -337,21 +346,12 @@ Thread* ThreadPool::available_slave(const SplitPoint* sp) const { } -// ThreadPool::wait_for_think_finished() waits for main thread to finish the search - -void ThreadPool::wait_for_think_finished() { - - std::unique_lock lk(main()->mutex); - sleepCondition.wait(lk, [&]{ return !main()->thinking; }); -} - - // ThreadPool::start_thinking() wakes up the main thread sleeping in // MainThread::idle_loop() and starts a new search, then returns immediately. void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits, StateStackPtr& states) { - wait_for_think_finished(); + main()->join(); SearchTime = now(); // As early as possible diff --git a/src/thread.h b/src/thread.h index 7932ad45..215b27c6 100644 --- a/src/thread.h +++ b/src/thread.h @@ -137,6 +137,7 @@ struct Thread : public ThreadBase { struct MainThread : public Thread { virtual void idle_loop(); + void join(); volatile bool thinking = true; // Avoid a race with start_thinking() }; @@ -162,11 +163,9 @@ struct ThreadPool : public std::vector { MainThread* main() { return static_cast(at(0)); } void read_uci_options(); Thread* available_slave(const SplitPoint* sp) const; - void wait_for_think_finished(); void start_thinking(const Position&, const Search::LimitsType&, Search::StateStackPtr&); Depth minimumSplitDepth; - ConditionVariable sleepCondition; TimerThread* timer; }; diff --git a/src/uci.cpp b/src/uci.cpp index b7127b75..7a0ead60 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -205,7 +205,7 @@ void UCI::loop(int argc, char* argv[]) { } while (token != "quit" && argc == 1); // Passed args have one-shot behaviour - Threads.wait_for_think_finished(); // Cannot quit whilst the search is running + Threads.main()->join(); // Cannot quit whilst the search is running }