Instead of having Signals in the search namespace,
make the stop variables part of the Threads structure.
This moves more of the shared (atomic) variables towards
the thread-related structures, making their role more clear.
No functional change
Closes #1149
Time.availableNodes += Limits.inc[us] - Threads.nodes_searched();
// When we reach the maximum depth, we can arrive here without a raise of
Time.availableNodes += Limits.inc[us] - Threads.nodes_searched();
// When we reach the maximum depth, we can arrive here without a raise of
- // Signals.stop. However, if we are pondering or in an infinite search,
+ // Threads.stop. However, if we are pondering or in an infinite search,
// the UCI protocol states that we shouldn't print the best move before the
// GUI sends a "stop" or "ponderhit" command. We therefore simply wait here
// the UCI protocol states that we shouldn't print the best move before the
// GUI sends a "stop" or "ponderhit" command. We therefore simply wait here
- // until the GUI sends one of those commands (which also raises Signals.stop).
- if (!Signals.stop && (Limits.ponder || Limits.infinite))
+ // until the GUI sends one of those commands (which also raises Threads.stop).
+ if (!Threads.stop && (Limits.ponder || Limits.infinite))
- Signals.stopOnPonderhit = true;
- wait(Signals.stop);
+ Threads.stopOnPonderhit = true;
+ wait(Threads.stop);
}
// Stop the threads if not already stopped
}
// Stop the threads if not already stopped
// Wait until all threads have finished
for (Thread* th : Threads)
// Wait until all threads have finished
for (Thread* th : Threads)
// Iterative deepening loop until requested to stop or the target depth is reached
while ( (rootDepth += ONE_PLY) < DEPTH_MAX
// Iterative deepening loop until requested to stop or the target depth is reached
while ( (rootDepth += ONE_PLY) < DEPTH_MAX
&& !(Limits.depth && mainThread && rootDepth / ONE_PLY > Limits.depth))
{
// Distribute search depths across the threads
&& !(Limits.depth && mainThread && rootDepth / ONE_PLY > Limits.depth))
{
// Distribute search depths across the threads
rm.previousScore = rm.score;
// MultiPV loop. We perform a full root search for each PV line
rm.previousScore = rm.score;
// MultiPV loop. We perform a full root search for each PV line
- for (PVIdx = 0; PVIdx < multiPV && !Signals.stop; ++PVIdx)
+ for (PVIdx = 0; PVIdx < multiPV && !Threads.stop; ++PVIdx)
{
// Reset aspiration window starting size
if (rootDepth >= 5 * ONE_PLY)
{
// Reset aspiration window starting size
if (rootDepth >= 5 * ONE_PLY)
// If search has been stopped, we break immediately. Sorting and
// writing PV back to TT is safe because RootMoves is still
// valid, although it refers to the previous iteration.
// If search has been stopped, we break immediately. Sorting and
// writing PV back to TT is safe because RootMoves is still
// valid, although it refers to the previous iteration.
break;
// When failing high/low give some update (without cluttering
break;
// When failing high/low give some update (without cluttering
if (mainThread)
{
mainThread->failedLow = true;
if (mainThread)
{
mainThread->failedLow = true;
- Signals.stopOnPonderhit = false;
+ Threads.stopOnPonderhit = false;
}
}
else if (bestValue >= beta)
}
}
else if (bestValue >= beta)
if (!mainThread)
continue;
if (!mainThread)
continue;
- if (Signals.stop || PVIdx + 1 == multiPV || Time.elapsed() > 3000)
+ if (Threads.stop || PVIdx + 1 == multiPV || Time.elapsed() > 3000)
sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
}
sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
}
completedDepth = rootDepth;
if (!mainThread)
completedDepth = rootDepth;
if (!mainThread)
if ( Limits.mate
&& bestValue >= VALUE_MATE_IN_MAX_PLY
&& VALUE_MATE - bestValue <= 2 * Limits.mate)
if ( Limits.mate
&& bestValue >= VALUE_MATE_IN_MAX_PLY
&& VALUE_MATE - bestValue <= 2 * Limits.mate)
// Do we have time for the next iteration? Can we stop searching now?
if (Limits.use_time_management())
{
// Do we have time for the next iteration? Can we stop searching now?
if (Limits.use_time_management())
{
- if (!Signals.stop && !Signals.stopOnPonderhit)
+ if (!Threads.stop && !Threads.stopOnPonderhit)
{
// Stop the search if only one legal move is available, or if all
// of the available time has been used, or if we matched an easyMove
{
// Stop the search if only one legal move is available, or if all
// of the available time has been used, or if we matched an easyMove
// If we are allowed to ponder do not stop the search now but
// keep pondering until the GUI sends "ponderhit" or "stop".
if (Limits.ponder)
// If we are allowed to ponder do not stop the search now but
// keep pondering until the GUI sends "ponderhit" or "stop".
if (Limits.ponder)
- Signals.stopOnPonderhit = true;
+ Threads.stopOnPonderhit = true;
if (!rootNode)
{
// Step 2. Check for aborted search and immediate draw
if (!rootNode)
{
// Step 2. Check for aborted search and immediate draw
- if (Signals.stop.load(std::memory_order_relaxed) || pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
+ if (Threads.stop.load(std::memory_order_relaxed) || pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos)
: DrawValue[pos.side_to_move()];
return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos)
: DrawValue[pos.side_to_move()];
// 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.
// 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.load(std::memory_order_relaxed))
+ if (Threads.stop.load(std::memory_order_relaxed))
return VALUE_ZERO;
if (rootNode)
return VALUE_ZERO;
if (rootNode)
// completed. But in this case bestValue is valid because we have fully
// searched our subtree, and we can anyhow save the result in TT.
/*
// completed. But in this case bestValue is valid because we have fully
// searched our subtree, and we can anyhow save the result in TT.
/*
if ( (Limits.use_time_management() && elapsed > Time.maximum() - 10)
|| (Limits.movetime && elapsed >= Limits.movetime)
|| (Limits.nodes && Threads.nodes_searched() >= (uint64_t)Limits.nodes))
if ( (Limits.use_time_management() && elapsed > Time.maximum() - 10)
|| (Limits.movetime && elapsed >= Limits.movetime)
|| (Limits.nodes && Threads.nodes_searched() >= (uint64_t)Limits.nodes))
#ifndef SEARCH_H_INCLUDED
#define SEARCH_H_INCLUDED
#ifndef SEARCH_H_INCLUDED
#define SEARCH_H_INCLUDED
#include <vector>
#include "misc.h"
#include <vector>
#include "misc.h"
-
-/// 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 {
- std::atomic_bool stop, stopOnPonderhit;
-};
-
-extern SignalsType Signals;
extern LimitsType Limits;
void init();
extern LimitsType Limits;
void init();
main()->wait_for_search_finished();
main()->wait_for_search_finished();
- Search::Signals.stopOnPonderhit = Search::Signals.stop = false;
+ stopOnPonderhit = stop = false;
Search::Limits = limits;
Search::RootMoves rootMoves;
Search::Limits = limits;
Search::RootMoves rootMoves;
uint64_t nodes_searched() const;
uint64_t tb_hits() const;
uint64_t nodes_searched() const;
uint64_t tb_hits() const;
+ std::atomic_bool stop, stopOnPonderhit;
+
private:
StateListPtr setupStates;
};
private:
StateListPtr setupStates;
};
is >> skipws >> token;
// The GUI sends 'ponderhit' to tell us to ponder on the same move the
is >> skipws >> token;
// The GUI sends 'ponderhit' to tell us to ponder on the same move the
- // opponent has played. In case Signals.stopOnPonderhit is set we are
+ // opponent has played. In case Threads.stopOnPonderhit is set we are
// waiting for 'ponderhit' to stop the search (for instance because we
// already ran out of time), otherwise we should continue searching but
// switching from pondering to normal search.
if ( token == "quit"
|| token == "stop"
// waiting for 'ponderhit' to stop the search (for instance because we
// already ran out of time), otherwise we should continue searching but
// switching from pondering to normal search.
if ( token == "quit"
|| token == "stop"
- || (token == "ponderhit" && Search::Signals.stopOnPonderhit))
+ || (token == "ponderhit" && Threads.stopOnPonderhit))
- Search::Signals.stop = true;
Threads.main()->start_searching(true); // Could be sleeping
}
else if (token == "ponderhit")
Threads.main()->start_searching(true); // Could be sleeping
}
else if (token == "ponderhit")