From 11b1a76f35108316ee37d9d7056f4d621305a7ed Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Wed, 14 Aug 2013 08:29:57 +0200 Subject: [PATCH] Use exceptions to stop the search Instead of classical flags, throw an exception when we want to immediately halt the search. Currently only one type is used for both UCI stop and threads cut off. No functional change. --- src/Makefile | 2 +- src/search.cpp | 52 ++++++++++++++++++++++++++++---------------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/Makefile b/src/Makefile index f8d65ccb..91286988 100644 --- a/src/Makefile +++ b/src/Makefile @@ -232,7 +232,7 @@ ifeq ($(COMP),clang) endif ### 3.2 General compiler settings -CXXFLAGS = -Wall -Wcast-qual -fno-exceptions -fno-rtti $(EXTRACXXFLAGS) +CXXFLAGS = -Wall -Wcast-qual -fno-rtti $(EXTRACXXFLAGS) ifeq ($(comp),gcc) CXXFLAGS += -ansi -pedantic -Wno-long-long -Wextra -Wshadow diff --git a/src/search.cpp b/src/search.cpp index 9143f669..89ddfef6 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -104,6 +105,8 @@ namespace { bool refutes(const Position& pos, Move first, Move second); string uci_pv(const Position& pos, int depth, Value alpha, Value beta); + class stop : public std::exception {}; + struct Skill { Skill(int l) : level(l), best(MOVE_NONE) {} ~Skill() { @@ -356,7 +359,9 @@ namespace { // research with bigger window until not failing high/low anymore. while (true) { - bestValue = search(pos, ss, alpha, beta, depth * ONE_PLY, false); + try { + bestValue = search(pos, ss, alpha, beta, depth * ONE_PLY, false); + } catch (stop&) {} // Bring to front the best move. It is critical that sorting is // done with a stable algorithm because all the values but the first @@ -541,10 +546,13 @@ namespace { if (PvNode && thisThread->maxPly < ss->ply) thisThread->maxPly = ss->ply; + if (Signals.stop || thisThread->cutoff_occurred()) + throw stop(); + if (!RootNode) { // Step 2. Check for aborted search and immediate draw - if (Signals.stop || pos.is_draw() || ss->ply > MAX_PLY) + if (pos.is_draw() || ss->ply > MAX_PLY) return DrawValue[pos.side_to_move()]; // Step 3. Mate distance pruning. Even if we mate at the next move our score @@ -999,13 +1007,6 @@ moves_loop: // When in check and at SpNode search starts from here alpha = splitPoint->alpha; } - // Finished searching the move. If Signals.stop is true, the search - // was aborted because the user interrupted the search or because we - // ran out of time. In this case, the return value of the search cannot - // be trusted, and we don't update the best move and/or PV. - if (Signals.stop || thisThread->cutoff_occurred()) - return value; // To avoid returning VALUE_INFINITE - if (RootNode) { RootMove& rm = *std::find(RootMoves.begin(), RootMoves.end(), move); @@ -1696,21 +1697,26 @@ void Thread::idle_loop() { activePosition = &pos; - switch (sp->nodeType) { - case Root: - search(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode); - break; - case PV: - search(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode); - break; - case NonPV: - search(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode); - break; - default: - assert(false); - } + try { + switch (sp->nodeType) { + case Root: + search(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode); + break; + case PV: + search(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode); + break; + case NonPV: + search(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode); + break; + default: + assert(false); + } - assert(searching); + assert(searching); + } + catch (stop&) { + sp->mutex.lock(); // Exception is thrown out of lock + } searching = false; activePosition = NULL; -- 2.39.2