Use only one ConditionVariable to sync UI
authorMarco Costalba <mcostalba@gmail.com>
Fri, 20 Mar 2015 16:58:43 +0000 (17:58 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 21 Mar 2015 06:55:33 +0000 (07:55 +0100)
To sync UI with main thread it is enough a single
condition variable because here we have a single
producer / single consumer design pattern.

Two condition variables are strictly needed just for
many producers / many consumers case.

Note that this is possible because now we don't send to
sleep idle threads anymore while searching, so that now
only UI can wake up the main thread and we can use the
same ConditionVariable for both threads.

The natural consequence is to retire wait_for_think_finished()
and move all the logic under MainThread class, yielding the
rename of teh function to join()

No functional change.

src/benchmark.cpp
src/thread.cpp
src/thread.h
src/uci.cpp

index e27e81fee5a838142cccdce9b46622d76d8ef50b..fbf7b0e3a88990004ecbbe5ec54a02ecb20c1290 100644 (file)
@@ -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();
       }
   }
index b4958ea32e22417527357b2b734e90fb0bf4eae8..a715d44ee17b2e5844e4be101b246041e9bc9c7d 100644 (file)
@@ -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<Mutex> 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<Mutex> 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
 
index 7932ad45f6b0e967229b6557f69858a3abd94fcf..215b27c688b2823b11112a56e862645cd7c726d0 100644 (file)
@@ -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<Thread*> {
   MainThread* main() { return static_cast<MainThread*>(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;
 };
 
index b7127b758153c9fd008563f2f7412a5802ebdfad..7a0ead60c09de931b0275470501fdbae30c33e9c 100644 (file)
@@ -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
 }