Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atomic signals #474

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

namespace Search {

volatile SignalsType Signals;
SignalsType Signals;
LimitsType Limits;
StateStackPtr SetupStates;
}
Expand Down Expand Up @@ -581,7 +581,7 @@ namespace {
if (!RootNode)
{
// Step 2. Check for aborted search and immediate draw
if (Signals.stop || pos.is_draw() || ss->ply >= MAX_PLY)
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
Expand Down Expand Up @@ -835,7 +835,7 @@ namespace {

if (RootNode && thisThread == Threads.main())
{
Signals.firstRootMove = (moveCount == 1);
Signals.firstRootMove = moveCount == 1;

if (Time.elapsed() > 3000)
sync_cout << "info depth " << depth / ONE_PLY
Expand Down Expand Up @@ -996,7 +996,7 @@ namespace {
// 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)
Expand Down Expand Up @@ -1559,7 +1559,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)
Expand Down
9 changes: 5 additions & 4 deletions src/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
#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>

Expand Down Expand Up @@ -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<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;

Expand Down
9 changes: 4 additions & 5 deletions src/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<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; });
Expand All @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions src/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool>& b);
void wait_while(std::atomic<bool>& b);

Mutex mutex;
ConditionVariable sleepCondition;
volatile bool exit = false;
std::atomic<bool> exit;
};


Expand All @@ -72,7 +73,7 @@ struct Thread : public ThreadBase {
Endgames endgames;
size_t idx, PVIdx;
int maxPly;
volatile bool searching;
std::atomic<bool> searching;

Position rootPos;
Search::RootMoveVector rootMoves;
Expand All @@ -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<bool> thinking;
};

struct TimerThread : public ThreadBase {
Expand Down