namespace Search {
- volatile SignalsType Signals;
+ SignalsType Signals;
LimitsType Limits;
StateStackPtr SetupStates;
}
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
if (RootNode && thisThread == Threads.main())
{
- Signals.firstRootMove = (moveCount == 1);
+ Signals.firstRootMove = moveCount == 1;
if (Time.elapsed() > 3000)
sync_cout << "info depth " << depth / ONE_PLY
// 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)
{
bool stillAtFirstMove = Signals.firstRootMove
&& !Signals.failedLowAtRoot
- && elapsed > Time.available() * 75 / 100;
+ && elapsed > Time.available() * 3 / 4;
if ( stillAtFirstMove
|| elapsed > Time.maximum() - 2 * TimerThread::Resolution)
#ifndef SEARCH_H_INCLUDED
#define SEARCH_H_INCLUDED
-#include <memory> // For std::auto_ptr
+#include <atomic>
+#include <memory> // For std::unique_ptr
#include <stack>
#include <vector>
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<bool> stop, stopOnPonderhit, firstRootMove, failedLowAtRoot;
};
typedef std::unique_ptr<std::stack<StateInfo>> StateStackPtr;
-extern volatile SignalsType Signals;
+extern SignalsType Signals;
extern LimitsType Limits;
extern StateStackPtr SetupStates;
// ThreadBase::wait() set the thread to sleep until 'condition' turns true
-void ThreadBase::wait(volatile const bool& condition) {
+void ThreadBase::wait(std::atomic<bool>& condition) {
std::unique_lock<Mutex> 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<bool>& condition) {
std::unique_lock<Mutex> 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.
-Thread::Thread() /* : splitPoints() */ { // Initialization of non POD broken in MSVC
+Thread::Thread() {
searching = false;
maxPly = 0;
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<bool>& b);
+ void wait_while(std::atomic<bool>& b);
Mutex mutex;
ConditionVariable sleepCondition;
- volatile bool exit = false;
+ std::atomic<bool> exit;
};
Endgames endgames;
size_t idx, PVIdx;
int maxPly;
- volatile bool searching;
+ std::atomic<bool> searching;
Position rootPos;
Search::RootMoveVector rootMoves;
/// 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<bool> thinking;
};
struct TimerThread : public ThreadBase {