X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=7c341f878f7200d321343567c249ec8fcd8964f0;hp=7ba64c44337dbe3de43276342f89670d03ed64ba;hb=5ca428402793b07b432b006056a1368f359c4ea0;hpb=c5e71f515045029f4d89f1302277217b878fa7a4 diff --git a/src/search.cpp b/src/search.cpp index 7ba64c44..7c341f87 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1643,7 +1643,7 @@ namespace { StateInfo st; Move ttMove, move; Value staticValue, bestValue, value, futilityBase, futilityValue; - bool isCheck, enoughMaterial, moveIsCheck; + bool isCheck, enoughMaterial, moveIsCheck, evasionPrunable; const TTEntry* tte = NULL; int moveCount = 0; bool pvNode = (beta - alpha != 1); @@ -1744,8 +1744,15 @@ namespace { } } - // Don't search captures and checks with negative SEE values - if ( !isCheck + // Detect blocking evasions that are candidate to be pruned + evasionPrunable = isCheck + && bestValue != -VALUE_INFINITE + && !pos.move_is_capture(move) + && pos.type_of_piece_on(move_from(move)) != KING + && !pos.can_castle(pos.side_to_move()); + + // Don't search moves with negative SEE values + if ( (!isCheck || evasionPrunable) && move != ttMove && !move_is_promotion(move) && pos.see_sign(move) < 0) @@ -2891,7 +2898,10 @@ namespace { if (!Threads[slave].idle || slave == master) return false; - if (Threads[slave].activeSplitPoints == 0) + // Make a local copy to be sure doesn't change under our feet + int localActiveSplitPoints = Threads[slave].activeSplitPoints; + + if (localActiveSplitPoints == 0) // No active split points means that the thread is available as // a slave for any other thread. return true; @@ -2899,8 +2909,10 @@ namespace { if (ActiveThreads == 2) return true; - // Apply the "helpful master" concept if possible - if (SplitPointStack[slave][Threads[slave].activeSplitPoints - 1].slaves[master]) + // Apply the "helpful master" concept if possible. Use localActiveSplitPoints + // that is known to be > 0, instead of Threads[slave].activeSplitPoints that + // could have been set to 0 by another thread leading to an out of bound access. + if (SplitPointStack[slave][localActiveSplitPoints - 1].slaves[master]) return true; return false; @@ -2986,6 +2998,7 @@ namespace { splitPoint->slaves[i] = 0; Threads[master].idle = false; + Threads[master].stop = false; Threads[master].splitPoint = splitPoint; // Allocate available threads setting idle flag to false @@ -2993,6 +3006,7 @@ namespace { if (thread_is_available(i, master)) { Threads[i].idle = false; + Threads[i].stop = false; Threads[i].splitPoint = splitPoint; splitPoint->slaves[i] = 1; splitPoint->cpus++; @@ -3003,22 +3017,14 @@ namespace { // We can release the lock because master and slave threads are already booked lock_release(&MPLock); - // Copy the tail of current search stack to the master thread - memcpy(splitPoint->sstack[master] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack)); - // Tell the threads that they have work to do. This will make them leave - // their idle loop. Also copy search stack tail for each slave thread. + // their idle loop. But before copy search stack tail for each thread. for (int i = 0; i < ActiveThreads; i++) - { - if (splitPoint->slaves[i]) - memcpy(splitPoint->sstack[i] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack)); - if (i == master || splitPoint->slaves[i]) { - Threads[i].stop = false; + memcpy(splitPoint->sstack[i] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack)); Threads[i].workIsWaiting = true; // This makes the slave to exit from idle_loop() } - } // Everything is set up. The master thread enters the idle loop, from // which it will instantly launch a search, because its workIsWaiting