From b1cf1acb93532248fb10c2ca983d80389d5aeb84 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Fri, 3 Feb 2012 16:07:13 +0100 Subject: [PATCH] Move wait_for_stop_or_ponderhit() under Thread This method belongs to Thread, not to ThreadsManager. Reshuffle stuff in thread.cpp while there. No functional change. Signed-off-by: Marco Costalba --- src/search.cpp | 6 +- src/thread.cpp | 146 ++++++++++++++++++++++++------------------------- src/thread.h | 4 +- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 8823e98f..8adbfd92 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -348,7 +348,7 @@ finalize: // but if we are pondering or in infinite search, we shouldn't print the best // move before we are told to do so. if (!Signals.stop && (Limits.ponder || Limits.infinite)) - Threads.wait_for_stop_or_ponderhit(); + Threads[pos.thread()].wait_for_stop_or_ponderhit(); // Best move could be MOVE_NONE when searching on a stalemate position cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960) @@ -1061,7 +1061,9 @@ split_point_start: // At split points actual search starts from here sp->bestValue = value; sp->ss->bestMove = move; sp->alpha = alpha; - sp->is_betaCutoff = (value >= beta); + + if (value >= beta) + sp->cutoff = true; } } diff --git a/src/thread.cpp b/src/thread.cpp index 3eb393bc..457a9278 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -59,8 +59,54 @@ namespace { extern "C" { } } -// wake_up() wakes up the thread, normally at the beginning of the search or, -// if "sleeping threads" is used, when there is some work to do. +// Thread::timer_loop() is where the timer thread waits maxPly milliseconds and +// then calls do_timer_event(). If maxPly is 0 thread sleeps until is woken up. +extern void check_time(); + +void Thread::timer_loop() { + + while (!do_exit) + { + lock_grab(sleepLock); + timed_wait(sleepCond, sleepLock, maxPly ? maxPly : INT_MAX); + lock_release(sleepLock); + check_time(); + } +} + + +// Thread::main_loop() is where the main thread is parked waiting to be started +// when there is a new search. Main thread will launch all the slave threads. + +void Thread::main_loop() { + + while (true) + { + lock_grab(sleepLock); + + do_sleep = true; // Always return to sleep after a search + is_searching = false; + + while (do_sleep && !do_exit) + { + cond_signal(Threads.sleepCond); // Wake up UI thread if needed + cond_wait(sleepCond, sleepLock); + } + + lock_release(sleepLock); + + if (do_exit) + return; + + is_searching = true; + + Search::think(); + } +} + + +// Thread::wake_up() wakes up the thread, normally at the beginning of the search +// or, if "sleeping threads" is used, when there is some work to do. void Thread::wake_up() { @@ -70,13 +116,33 @@ void Thread::wake_up() { } +// Thread::wait_for_stop_or_ponderhit() 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 StopRequest) is sent and +// then return, after which the bestmove and pondermove will be printed. + +void Thread::wait_for_stop_or_ponderhit() { + + Signals.stopOnPonderhit = true; + + lock_grab(sleepLock); + + while (!Signals.stop) + cond_wait(sleepCond, sleepLock); + + lock_release(sleepLock); +} + + // cutoff_occurred() checks whether a beta cutoff has occurred in the current // active split point, or in some ancestor of the split point. bool Thread::cutoff_occurred() const { for (SplitPoint* sp = splitPoint; sp; sp = sp->parent) - if (sp->is_betaCutoff) + if (sp->cutoff) return true; return false; @@ -184,10 +250,10 @@ void ThreadsManager::init() { void ThreadsManager::exit() { - assert(threads[0].is_searching == false); - for (int i = 0; i <= MAX_THREADS; i++) { + assert(threads[i].do_sleep); + threads[i].do_exit = true; // Search must be already finished threads[i].wake_up(); @@ -253,7 +319,7 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta, sp->parent = masterThread.splitPoint; sp->master = master; - sp->is_betaCutoff = false; + sp->cutoff = false; sp->slavesMask = 1ULL << master; sp->depth = depth; sp->threatMove = threatMove; @@ -327,22 +393,6 @@ template Value ThreadsManager::split(Position&, Stack*, Value, Value, Val template Value ThreadsManager::split(Position&, Stack*, Value, Value, Value, Depth, Move, int, MovePicker*, int); -// Thread::timer_loop() is where the timer thread waits maxPly milliseconds and -// then calls do_timer_event(). If maxPly is 0 thread sleeps until is woken up. -extern void check_time(); - -void Thread::timer_loop() { - - while (!do_exit) - { - lock_grab(sleepLock); - timed_wait(sleepCond, sleepLock, maxPly ? maxPly : INT_MAX); - lock_release(sleepLock); - check_time(); - } -} - - // ThreadsManager::set_timer() is used to set the timer to trigger after msec // milliseconds. If msec is 0 then timer is stopped. @@ -357,36 +407,6 @@ void ThreadsManager::set_timer(int msec) { } -// Thread::main_loop() is where the main thread is parked waiting to be started -// when there is a new search. Main thread will launch all the slave threads. - -void Thread::main_loop() { - - while (true) - { - lock_grab(sleepLock); - - do_sleep = true; // Always return to sleep after a search - is_searching = false; - - while (do_sleep && !do_exit) - { - cond_signal(Threads.sleepCond); // Wake up UI thread if needed - cond_wait(sleepCond, sleepLock); - } - - is_searching = true; - - lock_release(sleepLock); - - if (do_exit) - return; - - Search::think(); - } -} - - // ThreadsManager::start_thinking() is used by UI thread to wake up the main // thread parked in main_loop() and starting a new search. If asyncMode is true // then function returns immediately, otherwise caller is blocked waiting for @@ -447,25 +467,3 @@ void ThreadsManager::stop_thinking() { lock_release(main.sleepLock); } - - -// ThreadsManager::wait_for_stop_or_ponderhit() 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 StopRequest) is sent and -// then return, after which the bestmove and pondermove will be printed. - -void ThreadsManager::wait_for_stop_or_ponderhit() { - - Signals.stopOnPonderhit = true; - - Thread& main = threads[0]; - - lock_grab(main.sleepLock); - - while (!Signals.stop) - cond_wait(main.sleepCond, main.sleepLock); - - lock_release(main.sleepLock); -} diff --git a/src/thread.h b/src/thread.h index c93bcb4d..dea9d797 100644 --- a/src/thread.h +++ b/src/thread.h @@ -54,7 +54,7 @@ struct SplitPoint { volatile Value alpha; volatile Value bestValue; volatile int moveCount; - volatile bool is_betaCutoff; + volatile bool cutoff; }; @@ -71,6 +71,7 @@ struct Thread { void idle_loop(SplitPoint* sp_master); void main_loop(); void timer_loop(); + void wait_for_stop_or_ponderhit(); SplitPoint splitPoints[MAX_ACTIVE_SPLIT_POINTS]; MaterialInfoTable materialTable; @@ -110,7 +111,6 @@ public: void read_uci_options(); bool available_slave_exists(int master) const; void set_timer(int msec); - void wait_for_stop_or_ponderhit(); void stop_thinking(); void start_thinking(const Position& pos, const Search::LimitsType& limits, const std::set& = std::set(), bool async = false); -- 2.39.2