These functions are used in just one place.
And generalize wait_for_stop()
No functional change.
<< std::endl;
}
- Threads.wake_up();
+ // Reset and wake up the threads
+ for (size_t i = 0; i < Threads.size(); i++)
+ {
+ Threads[i].maxPly = 0;
+ Threads[i].do_sleep = false;
+
+ if (!Threads.use_sleeping_threads())
+ Threads[i].notify_one();
+ }
// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
id_loop(RootPos); // Let's start searching !
Threads.set_timer(0); // Stop timer
- Threads.sleep();
+
+ // Main thread will go to sleep by itself to avoid a race with start_searching()
+ for (size_t i = 0; i < Threads.size(); i++)
+ if (&Threads[i] != Threads.main_thread())
+ Threads[i].do_sleep = true;
if (Options["Use Search Log"])
{
finalize:
// When we reach max depth we arrive here even without Signals.stop is raised,
- // but if we are pondering or in infinite search, we shouldn't print the best
- // move before we are told to do so.
+ // but if we are pondering or in infinite search, according to UCI protocol,
+ // we shouldn't print the best move before the GUI sends a "stop" or "ponderhit"
+ // command. We simply wait here until GUI sends one of those commands (that
+ // raise Signals.stop).
if (!Signals.stop && (Limits.ponder || Limits.infinite))
{
Signals.stopOnPonderhit = true;
- RootPos.this_thread()->wait_for_stop();
+ RootPos.this_thread()->wait_for(Signals.stop);
}
// Best move could be MOVE_NONE when searching on a stalemate position
}
-// Thread::wait_for_stop() is called when the maximum depth is reached while
-// the program is pondering. The point is to work around a wrinkle in the UCI
-// protocol: When pondering, the engine is not allowed to give a "bestmove"
-// before the GUI sends it a "stop" or "ponderhit" command. We simply wait here
-// until one of these commands (that raise Signals.stop) is sent and
-// then return, after which the bestmove and pondermove will be printed.
+// Thread::wait_for() set the thread to sleep until condition 'b' turns true
-void Thread::wait_for_stop() {
+void Thread::wait_for(volatile const bool& b) {
mutex.lock();
- while (!Signals.stop) sleepCondition.wait(mutex);
+ while (!b) sleepCondition.wait(mutex);
mutex.unlock();
}
}
-// wake_up() is called before a new search to start the threads that are waiting
-// on the sleep condition and to reset maxPly. When useSleepingThreads is set
-// threads will be woken up at split time.
-
-void ThreadPool::wake_up() const {
-
- for (size_t i = 0; i < threads.size(); i++)
- {
- threads[i]->maxPly = 0;
- threads[i]->do_sleep = false;
-
- if (!useSleepingThreads)
- threads[i]->notify_one();
- }
-}
-
-
-// sleep() is called after the search finishes to ask all the threads but the
-// main one to go waiting on a sleep condition.
-
-void ThreadPool::sleep() const {
-
- // Main thread will go to sleep by itself to avoid a race with start_searching()
- for (size_t i = 1; i < threads.size(); i++)
- threads[i]->do_sleep = true;
-}
-
-
// available_slave_exists() tries to find an idle thread which is available as
// a slave for the thread 'master'.
void idle_loop();
void main_loop();
void timer_loop();
- void wait_for_stop();
+ void wait_for(volatile const bool& b);
SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
Material::Table materialTable;
size_t size() const { return threads.size(); }
Thread* main_thread() { return threads[0]; }
- void wake_up() const;
- void sleep() const;
void read_uci_options();
bool available_slave_exists(Thread* master) const;
void set_timer(int msec);