diff --git a/src/search.cpp b/src/search.cpp index 78e4748f..902ba0fc 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -37,7 +37,7 @@ namespace Search { - volatile SignalsType Signals; + SignalsType Signals; LimitsType Limits; StateStackPtr SetupStates; } @@ -581,8 +581,8 @@ namespace { if (!RootNode) { // Step 2. Check for aborted search and immediate draw - if (Signals.stop || pos.is_draw() || ss->ply >= MAX_PLY) - return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos) + if (Signals.stop.load(std::memory_order_relaxed) || pos.is_draw() || ss->ply >= MAX_PLY) + return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos) : DrawValue[pos.side_to_move()]; // Step 3. Mate distance pruning. Even if we mate at the next move our score @@ -841,7 +841,7 @@ moves_loop: // When in check search starts from here if (RootNode && thisThread == Threads.main()) { - Signals.firstRootMove = (moveCount == 1); + Signals.firstRootMove = moveCount == 1; if (Time.elapsed() > 3000) sync_cout << "info depth " << depth / ONE_PLY @@ -1008,7 +1008,7 @@ moves_loop: // When in check search starts from here // Finished searching the move. If a stop occurred, the return value of // the search cannot be trusted, and we return immediately without // updating best move, PV and TT. - if (Signals.stop) + if (Signals.stop.load(std::memory_order_relaxed)) return VALUE_ZERO; if (RootNode) @@ -1577,7 +1577,7 @@ void check_time() { { bool stillAtFirstMove = Signals.firstRootMove && !Signals.failedLowAtRoot - && elapsed > Time.available() * 75 / 100; + && elapsed > Time.available() * 3 / 4; if ( stillAtFirstMove || elapsed > Time.maximum() - 2 * TimerThread::Resolution) diff --git a/src/search.h b/src/search.h index c7abb9dc..740063b9 100644 --- a/src/search.h +++ b/src/search.h @@ -20,7 +20,8 @@ #ifndef SEARCH_H_INCLUDED #define SEARCH_H_INCLUDED -#include // For std::auto_ptr +#include +#include // For std::unique_ptr #include #include @@ -91,16 +92,16 @@ struct LimitsType { TimePoint startTime; }; -/// The SignalsType struct stores volatile flags updated during the search +/// The SignalsType struct stores atomic flags updated during the search /// typically in an async fashion e.g. to stop the search by the GUI. struct SignalsType { - bool stop, stopOnPonderhit, firstRootMove, failedLowAtRoot; + std::atomic stop, stopOnPonderhit, firstRootMove, failedLowAtRoot; }; typedef std::unique_ptr> StateStackPtr; -extern volatile SignalsType Signals; +extern SignalsType Signals; extern LimitsType Limits; extern StateStackPtr SetupStates; diff --git a/src/thread.cpp b/src/thread.cpp index dd8c398c..eb64f7ee 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -68,16 +68,15 @@ void ThreadBase::notify_one() { // ThreadBase::wait() set the thread to sleep until 'condition' turns true -void ThreadBase::wait(volatile const bool& condition) { +void ThreadBase::wait(std::atomic& condition) { std::unique_lock lk(mutex); - sleepCondition.wait(lk, [&]{ return condition; }); + sleepCondition.wait(lk, [&]{ return bool(condition); }); } // ThreadBase::wait_while() set the thread to sleep until 'condition' turns false - -void ThreadBase::wait_while(volatile const bool& condition) { +void ThreadBase::wait_while(std::atomic& condition) { std::unique_lock lk(mutex); sleepCondition.wait(lk, [&]{ return !condition; }); @@ -87,7 +86,7 @@ void ThreadBase::wait_while(volatile const bool& condition) { // Thread c'tor makes some init but does not launch any execution thread that // will be started only when c'tor returns. -Thread::Thread() /* : splitPoints() */ { // Initialization of non POD broken in MSVC +Thread::Thread() { searching = false; maxPly = 0; diff --git a/src/thread.h b/src/thread.h index 459b1ddd..abb7a223 100644 --- a/src/thread.h +++ b/src/thread.h @@ -44,15 +44,16 @@ const size_t MAX_THREADS = 128; struct ThreadBase : public std::thread { + ThreadBase() { exit = false; } virtual ~ThreadBase() = default; virtual void idle_loop() = 0; void notify_one(); - void wait(volatile const bool& b); - void wait_while(volatile const bool& b); + void wait(std::atomic& b); + void wait_while(std::atomic& b); Mutex mutex; ConditionVariable sleepCondition; - volatile bool exit = false; + std::atomic exit; }; @@ -72,7 +73,7 @@ struct Thread : public ThreadBase { Endgames endgames; size_t idx, PVIdx; int maxPly; - volatile bool searching; + std::atomic searching; Position rootPos; Search::RootMoveVector rootMoves; @@ -87,10 +88,11 @@ struct Thread : public ThreadBase { /// special threads: the main one and the recurring timer. struct MainThread : public Thread { + MainThread() { thinking = true; } // Avoid a race with start_thinking() virtual void idle_loop(); void join(); void think(); - volatile bool thinking = true; // Avoid a race with start_thinking() + std::atomic thinking; }; struct TimerThread : public ThreadBase {