From 9c587288da70b86d7f5eccbc9a9bb5891f121317 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Wed, 7 Oct 2015 15:38:39 +0200 Subject: [PATCH] Simplify locking Retire slavesMask. We don't need it. It si enough 'searching' and 'thinking' flags. Further simplification is still possible, perhaps we could use a single flag. No functional change. --- src/search.cpp | 22 +++++++--------------- src/thread.cpp | 18 ++++++++++++------ src/thread.h | 2 +- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 4dd459ae..45dc7e64 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -291,12 +291,13 @@ void Search::think() { { th->maxPly = 0; th->depth = DEPTH_ZERO; + th->searching = true; if (th != Threads.main()) { th->pos = Position(rootPos, th); th->rootMoves = rootMoves; + th->notify_one(); // Wake up the thread and start searching } - th->notify_one(); // Wake up all the threads } Threads.timer->run = true; @@ -306,10 +307,6 @@ void Search::think() { TT.new_search(); - // Start the threads - for (Thread* th : Threads) - th->searching = true; - Threads.main()->search(); // Stop the threads and timer @@ -317,7 +314,9 @@ void Search::think() { Threads.timer->run = false; // Wait until all threads have finished - while (Threads.main()->slavesMask != 0) {} + for (Thread* th : Threads) + if (th != Threads.main()) + th->wait_while(th->searching); // Clear any candidate easy move that wasn't stable for the last search // iterations; the second condition prevents consecutive fast moves. @@ -346,7 +345,7 @@ void Search::think() { if (!Signals.stop && (Limits.ponder || Limits.infinite)) { Signals.stopOnPonderhit = true; - rootPos.this_thread()->wait_for(Signals.stop); + Threads.main()->wait_for(Signals.stop); } sync_cout << "bestmove " << UCI::move(rootMoves[0].pv[0], rootPos.is_chess960()); @@ -364,10 +363,6 @@ void Search::think() { void Thread::search() { - Threads.main()->mutex.lock(); - Threads.main()->slavesMask.set(idx); - Threads.main()->mutex.unlock(); - Value bestValue, alpha, beta, delta; Move easyMove = MOVE_NONE; @@ -560,10 +555,7 @@ void Thread::search() { } searching = false; - - Threads.main()->mutex.lock(); - Threads.main()->slavesMask.reset(idx); - Threads.main()->mutex.unlock(); + notify_one(); // Wake up main if is sleeping waiting for us } diff --git a/src/thread.cpp b/src/thread.cpp index ac4c170e..558cc5ef 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -75,6 +75,15 @@ void ThreadBase::wait_for(volatile const bool& condition) { } +// ThreadBase::wait_while() set the thread to sleep until 'condition' turns false + +void ThreadBase::wait_while(volatile const bool& condition) { + + std::unique_lock lk(mutex); + sleepCondition.wait(lk, [&]{ return !condition; }); +} + + // Thread c'tor makes some init but does not launch any execution thread that // will be started only when c'tor returns. @@ -112,10 +121,6 @@ void Thread::idle_loop() { while (!exit) { - // If this thread has been assigned work, launch a search - if (searching) - this->search(); - // If search is finished then sleep if (!Threads.main()->thinking) { @@ -123,6 +128,9 @@ void Thread::idle_loop() { while (!exit && !Threads.main()->thinking) sleepCondition.wait(lk); } + + if (!exit && searching) + this->search(); } } @@ -147,9 +155,7 @@ void MainThread::idle_loop() { lk.unlock(); if (!exit) - { Search::think(); - } } } diff --git a/src/thread.h b/src/thread.h index 360a0c39..0ba76971 100644 --- a/src/thread.h +++ b/src/thread.h @@ -48,6 +48,7 @@ struct ThreadBase : public std::thread { virtual void idle_loop() = 0; void notify_one(); void wait_for(volatile const bool& b); + void wait_while(volatile const bool& b); Mutex mutex; ConditionVariable sleepCondition; @@ -89,7 +90,6 @@ struct MainThread : public Thread { virtual void idle_loop(); void join(); volatile bool thinking = true; // Avoid a race with start_thinking() - std::bitset slavesMask; }; struct TimerThread : public ThreadBase {