X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=dd3030a0dd4f1390b0ef8b1043ff70bfa73afb19;hp=371144086898bf417e16af7d17a261e8b5849870;hb=c645aca199ac7db2ffcfc229b3cda8dafa6fb835;hpb=e1919384a23fe728422f995369161efa192380db diff --git a/src/search.cpp b/src/search.cpp index 37114408..dd3030a0 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -265,7 +265,7 @@ void Search::think() { goto finalize; } - if (Options["OwnBook"]) + if (Options["OwnBook"] && !Limits.infinite) { Move bookMove = book.probe(pos, Options["Book File"], Options["Best Book Move"]); @@ -332,7 +332,7 @@ finalize: // but if we are pondering or in infinite search, we shouldn't print the best // move before we are told to do so. if (!Signals.stop && (Limits.ponder || Limits.infinite)) - Threads.this_thread()->wait_for_stop_or_ponderhit(); + pos.this_thread()->wait_for_stop_or_ponderhit(); // Best move could be MOVE_NONE when searching on a stalemate position cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960) @@ -531,7 +531,7 @@ namespace { assert((alpha == beta - 1) || PvNode); assert(depth > DEPTH_ZERO); - Move movesSearched[MAX_MOVES]; + Move movesSearched[64]; StateInfo st; const TTEntry *tte; Key posKey; @@ -543,7 +543,7 @@ namespace { bool isPvMove, inCheck, singularExtensionNode, givesCheck; bool captureOrPromotion, dangerous, doFullDepthSearch; int moveCount = 0, playedMoveCount = 0; - Thread* thisThread = Threads.this_thread(); + Thread* thisThread = pos.this_thread(); SplitPoint* sp = NULL; refinedValue = bestValue = value = -VALUE_INFINITE; @@ -944,7 +944,7 @@ split_point_start: // At split points actual search starts from here } ss->currentMove = move; - if (!SpNode && !captureOrPromotion) + if (!SpNode && !captureOrPromotion && playedMoveCount < 64) movesSearched[playedMoveCount++] = move; // Step 14. Make the move @@ -1825,8 +1825,7 @@ void Thread::idle_loop(SplitPoint* sp_master) { lock_release(Threads.splitLock); Stack ss[MAX_PLY_PLUS_2]; - Position pos(*sp->pos); - Thread* master = sp->master; + Position pos(*sp->pos, this); memcpy(ss, sp->ss - 1, 4 * sizeof(Stack)); (ss+1)->sp = sp; @@ -1848,17 +1847,57 @@ void Thread::idle_loop(SplitPoint* sp_master) { sp->slavesMask &= ~(1ULL << idx); sp->nodes += pos.nodes_searched(); - // After releasing the lock we cannot access anymore any SplitPoint - // related data in a reliably way becuase it could have been released - // under our feet by the sp master. - lock_release(sp->lock); - // Wake up master thread so to allow it to return from the idle loop in // case we are the last slave of the split point. if ( Threads.use_sleeping_threads() - && this != master - && !master->is_searching) - master->wake_up(); + && this != sp->master + && !sp->master->is_searching) + sp->master->wake_up(); + + // After releasing the lock we cannot access anymore any SplitPoint + // related data in a safe way becuase it could have been released under + // our feet by the sp master. Also accessing other Thread objects is + // unsafe because if we are exiting there is a chance are already freed. + lock_release(sp->lock); + + // Try to reparent to another split point. Only for slave threads + // that are not master of any active split point. + if (!splitPointsCnt) + for (int i = 0; i < Threads.size(); i++) + { + Thread* th = &Threads[i]; + SplitPoint* oldest = &th->splitPoints[0]; + + // Find the first split point with still all slaves running + // where we are available as a possible slave. + if ( !is_searching + && th->splitPointsCnt + && !oldest->cutoff + && oldest->slavesMask == oldest->allSlavesMask + && !single_bit(oldest->allSlavesMask)) + { + lock_grab(oldest->lock); + lock_grab(Threads.splitLock); + + // Retest all under lock protection, we are in the middle + // of a race storm here ! + if ( !is_searching + && th->splitPointsCnt + && !oldest->cutoff + && oldest->slavesMask == oldest->allSlavesMask + && !single_bit(oldest->allSlavesMask)) + { + oldest->slavesMask |= 1ULL << idx; // allSlavesMask is not updated + curSplitPoint = oldest; + is_searching = true; + } + + lock_release(Threads.splitLock); + lock_release(oldest->lock); + + break; // Exit anyhow, only one try (enough in 99% of cases) + } + } } } }