-/// ThreadPool::start_thinking() wakes up main thread waiting in idle_loop() and
-/// returns immediately. Main thread will wake up other threads and start the search.
-
-void ThreadPool::start_thinking(Position& pos, StateListPtr& states,
- const Search::LimitsType& limits, bool ponderMode) {
-
- main()->wait_for_search_finished();
+// Wakes up main thread waiting in idle_loop() and
+// returns immediately. Main thread will wake up other threads and start the search.
+void ThreadPool::start_thinking(Position& pos,
+ StateListPtr& states,
+ const Search::LimitsType& limits,
+ bool ponderMode) {
+
+ main()->wait_for_search_finished();
+
+ main()->stopOnPonderhit = stop = false;
+ increaseDepth = true;
+ main()->ponder = ponderMode;
+ Search::Limits = limits;
+ Search::RootMoves rootMoves;
+
+ for (const auto& m : MoveList<LEGAL>(pos))
+ if (limits.searchmoves.empty()
+ || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m))
+ rootMoves.emplace_back(m);
+
+ if (!rootMoves.empty())
+ Tablebases::rank_root_moves(pos, rootMoves);
+
+ // After ownership transfer 'states' becomes empty, so if we stop the search
+ // and call 'go' again without setting a new position states.get() == nullptr.
+ assert(states.get() || setupStates.get());
+
+ if (states.get())
+ setupStates = std::move(states); // Ownership transfer, states is now empty
+
+ // We use Position::set() to set root position across threads. But there are
+ // some StateInfo fields (previous, pliesFromNull, capturedPiece) that cannot
+ // be deduced from a fen string, so set() clears them and they are set from
+ // setupStates->back() later. The rootState is per thread, earlier states are shared
+ // since they are read-only.
+ for (Thread* th : threads)
+ {
+ th->nodes = th->tbHits = th->nmpMinPly = th->bestMoveChanges = 0;
+ th->rootDepth = th->completedDepth = 0;
+ th->rootMoves = rootMoves;
+ th->rootPos.set(pos.fen(), pos.is_chess960(), &th->rootState, th);
+ th->rootState = setupStates->back();
+ th->rootSimpleEval = Eval::simple_eval(pos, pos.side_to_move());
+ }
+
+ main()->start_searching();
+}