Skip to content

Commit 26dabb1

Browse files
committed
Use only one ConditionVariable to sync UI
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.
1 parent 35b6079 commit 26dabb1

File tree

4 files changed

+14
-15
lines changed

4 files changed

+14
-15
lines changed

src/benchmark.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ void benchmark(const Position& current, istream& is) {
158158
else
159159
{
160160
Threads.start_thinking(pos, limits, st);
161-
Threads.wait_for_think_finished();
161+
Threads.main()->join();
162162
nodes += Search::RootPos.nodes_searched();
163163
}
164164
}

src/thread.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ void MainThread::idle_loop() {
251251

252252
while (!thinking && !exit)
253253
{
254-
Threads.sleepCondition.notify_one(); // Wake up the UI thread if needed
254+
sleepCondition.notify_one(); // Wake up the UI thread if needed
255255
sleepCondition.wait(lk);
256256
}
257257

@@ -271,6 +271,15 @@ void MainThread::idle_loop() {
271271
}
272272

273273

274+
// MainThread::join() waits for main thread to finish the search
275+
276+
void MainThread::join() {
277+
278+
std::unique_lock<Mutex> lk(mutex);
279+
sleepCondition.wait(lk, [&]{ return !thinking; });
280+
}
281+
282+
274283
// ThreadPool::init() is called at startup to create and launch requested threads,
275284
// that will go immediately to sleep. We cannot use a c'tor because Threads is a
276285
// 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 {
337346
}
338347

339348

340-
// ThreadPool::wait_for_think_finished() waits for main thread to finish the search
341-
342-
void ThreadPool::wait_for_think_finished() {
343-
344-
std::unique_lock<Mutex> lk(main()->mutex);
345-
sleepCondition.wait(lk, [&]{ return !main()->thinking; });
346-
}
347-
348-
349349
// ThreadPool::start_thinking() wakes up the main thread sleeping in
350350
// MainThread::idle_loop() and starts a new search, then returns immediately.
351351

352352
void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits,
353353
StateStackPtr& states) {
354-
wait_for_think_finished();
354+
main()->join();
355355

356356
SearchTime = now(); // As early as possible
357357

src/thread.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ struct Thread : public ThreadBase {
137137

138138
struct MainThread : public Thread {
139139
virtual void idle_loop();
140+
void join();
140141
volatile bool thinking = true; // Avoid a race with start_thinking()
141142
};
142143

@@ -162,11 +163,9 @@ struct ThreadPool : public std::vector<Thread*> {
162163
MainThread* main() { return static_cast<MainThread*>(at(0)); }
163164
void read_uci_options();
164165
Thread* available_slave(const SplitPoint* sp) const;
165-
void wait_for_think_finished();
166166
void start_thinking(const Position&, const Search::LimitsType&, Search::StateStackPtr&);
167167

168168
Depth minimumSplitDepth;
169-
ConditionVariable sleepCondition;
170169
TimerThread* timer;
171170
};
172171

src/uci.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ void UCI::loop(int argc, char* argv[]) {
205205

206206
} while (token != "quit" && argc == 1); // Passed args have one-shot behaviour
207207

208-
Threads.wait_for_think_finished(); // Cannot quit whilst the search is running
208+
Threads.main()->join(); // Cannot quit whilst the search is running
209209
}
210210

211211

0 commit comments

Comments
 (0)