X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fsearch.cpp;h=df1c9b506d7c8e79f957bf90e1d9dcfe3f5c0aa4;hb=c9d7e99de682516c560009b550c41da9ae2008b8;hp=21db685285972f12c571078dec42751d76201228;hpb=2c317d7b28161e74f0cdc0a00922b48cb996321f;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index 21db6852..df1c9b50 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -76,13 +76,11 @@ namespace { bool available_thread_exists(int master) const; bool thread_is_available(int slave, int master) const; bool cutoff_at_splitpoint(int threadID) const; - void wake_sleeping_thread(int threadID); void idle_loop(int threadID, SplitPoint* sp); template void split(Position& pos, SearchStack* ss, Value* alpha, const Value beta, Value* bestValue, Depth depth, Move threatMove, int moveCount, MovePicker* mp, bool pvNode); - private: Lock mpLock; Depth minimumSplitDepth; @@ -118,8 +116,8 @@ namespace { void extract_pv_from_tt(Position& pos); void insert_pv_in_tt(Position& pos); - std::string pv_info_to_uci(Position& pos, int depth, int selDepth, Value alpha, Value beta, int pvIdx); - + std::string pv_info_to_uci(Position& pos, int depth, int selDepth, + Value alpha, Value beta, int pvIdx); int64_t nodes; Value pv_score; Value non_pv_score; @@ -127,7 +125,7 @@ namespace { }; - // RootMoveList struct is just a std::vector<> of RootMove objects, + // RootMoveList struct is just a vector of RootMove objects, // with an handful of methods above the standard ones. struct RootMoveList : public std::vector { @@ -182,7 +180,7 @@ namespace { // Step 9. Internal iterative deepening // Minimum depth for use of internal iterative deepening - const Depth IIDDepth[2] = { 8 * ONE_PLY /* non-PV */, 5 * ONE_PLY /* PV */}; + const Depth IIDDepth[] = { 8 * ONE_PLY, 5 * ONE_PLY }; // At Non-PV nodes we do an internal iterative deepening search // when the static evaluation is bigger then beta - IIDMargin. @@ -190,13 +188,14 @@ namespace { // Step 11. Decide the new search depth - // Extensions. Configurable UCI options - // Array index 0 is used at non-PV nodes, index 1 at PV nodes. - Depth CheckExtension[2], PawnPushTo7thExtension[2]; - Depth PassedPawnExtension[2], PawnEndgameExtension[2]; + // Extensions. Array index 0 is used for non-PV nodes, index 1 for PV nodes + const Depth CheckExtension[] = { ONE_PLY / 2, ONE_PLY / 1 }; + const Depth PawnEndgameExtension[] = { ONE_PLY / 1, ONE_PLY / 1 }; + const Depth PawnPushTo7thExtension[] = { ONE_PLY / 2, ONE_PLY / 2 }; + const Depth PassedPawnExtension[] = { DEPTH_ZERO, ONE_PLY / 2 }; // Minimum depth for use of singular extension - const Depth SingularExtensionDepth[2] = { 8 * ONE_PLY /* non-PV */, 6 * ONE_PLY /* PV */}; + const Depth SingularExtensionDepth[] = { 8 * ONE_PLY, 6 * ONE_PLY }; // Step 12. Futility pruning @@ -205,14 +204,22 @@ namespace { // Futility lookup tables (initialized at startup) and their access functions Value FutilityMarginsMatrix[16][64]; // [depth][moveNumber] - int FutilityMoveCountArray[32]; // [depth] + int FutilityMoveCountArray[32]; // [depth] + + inline Value futility_margin(Depth d, int mn) { + + return d < 7 * ONE_PLY ? FutilityMarginsMatrix[Max(d, 1)][Min(mn, 63)] + : 2 * VALUE_INFINITE; + } + + inline int futility_move_count(Depth d) { - inline Value futility_margin(Depth d, int mn) { return d < 7 * ONE_PLY ? FutilityMarginsMatrix[Max(d, 1)][Min(mn, 63)] : 2 * VALUE_INFINITE; } - inline int futility_move_count(Depth d) { return d < 16 * ONE_PLY ? FutilityMoveCountArray[d] : 512; } + return d < 16 * ONE_PLY ? FutilityMoveCountArray[d] : MAX_MOVES; + } // Step 14. Reduced search - // Reduction lookup tables (initialized at startup) and their getter functions + // Reduction lookup tables (initialized at startup) and their access function int8_t ReductionMatrix[2][64][64]; // [pv][depth][moveNumber] template @@ -235,13 +242,11 @@ namespace { int MultiPV, UCIMultiPV; // Time management variables - int SearchStartTime, MaxNodes, MaxDepth, ExactMaxTime; - bool UseTimeManagement, InfiniteSearch, Pondering, StopOnPonderhit; - bool FirstRootMove, StopRequest, QuitRequest, AspirationFailLow; + bool StopOnPonderhit, FirstRootMove, StopRequest, QuitRequest, AspirationFailLow; TimeManager TimeMgr; + SearchLimits Limits; // Log file - bool UseLogFile; std::ofstream LogFile; // Skill level adjustment @@ -293,7 +298,7 @@ namespace { void update_gains(const Position& pos, Move move, Value before, Value after); void do_skill_level(Move* best, Move* ponder); - int current_search_time(); + int current_search_time(int set = 0); std::string value_to_uci(Value v); std::string speed_to_uci(int64_t nodes); void poll(const Position& pos); @@ -306,7 +311,7 @@ namespace { #endif - // MovePickerExt is an extended MovePicker used to choose at compile time + // MovePickerExt is an extended MovePicker class used to choose at compile time // the proper move source according to the type of node. template struct MovePickerExt; @@ -413,7 +418,7 @@ void exit_threads() { ThreadsMgr.exit_threads(); } int64_t perft(Position& pos, Depth depth) { - MoveStack mlist[MOVES_MAX]; + MoveStack mlist[MAX_MOVES]; StateInfo st; Move m; int64_t sum = 0; @@ -441,25 +446,30 @@ int64_t perft(Position& pos, Depth depth) { /// think() is the external interface to Stockfish's search, and is called when /// the program receives the UCI 'go' command. It initializes various global -/// variables, and calls id_loop(). It returns false when a quit command is +/// variables, and calls id_loop(). It returns false when a "quit" command is /// received during the search. -bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[], - int movesToGo, int maxDepth, int maxNodes, int maxTime, Move searchMoves[]) { +bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { // Initialize global search-related variables StopOnPonderhit = StopRequest = QuitRequest = AspirationFailLow = SendSearchedNodes = false; NodesSincePoll = 0; - SearchStartTime = get_system_time(); - ExactMaxTime = maxTime; - MaxDepth = maxDepth; - MaxNodes = maxNodes; - InfiniteSearch = infinite; - Pondering = ponder; - UseTimeManagement = !ExactMaxTime && !MaxDepth && !MaxNodes && !InfiniteSearch; + current_search_time(get_system_time()); + Limits = limits; + TimeMgr.init(Limits, pos.startpos_ply_counter()); + + // Set best NodesBetweenPolls interval to avoid lagging under time pressure + if (Limits.maxNodes) + NodesBetweenPolls = Min(Limits.maxNodes, 30000); + else if (Limits.time && Limits.time < 1000) + NodesBetweenPolls = 1000; + else if (Limits.time && Limits.time < 5000) + NodesBetweenPolls = 5000; + else + NodesBetweenPolls = 30000; // Look for a book move, only during games, not tests - if (UseTimeManagement && Options["OwnBook"].value()) + if (Limits.useTimeManagement() && Options["OwnBook"].value()) { if (Options["Book File"].value() != OpeningBook.name()) OpeningBook.open(Options["Book File"].value()); @@ -467,7 +477,7 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ Move bookMove = OpeningBook.get_move(pos, Options["Best Book Move"].value()); if (bookMove != MOVE_NONE) { - if (Pondering) + if (Limits.ponder) wait_for_stop_or_ponderhit(); cout << "bestmove " << bookMove << endl; @@ -476,17 +486,8 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ } // Read UCI options - CheckExtension[1] = Options["Check Extension (PV nodes)"].value(); - CheckExtension[0] = Options["Check Extension (non-PV nodes)"].value(); - PawnPushTo7thExtension[1] = Options["Pawn Push to 7th Extension (PV nodes)"].value(); - PawnPushTo7thExtension[0] = Options["Pawn Push to 7th Extension (non-PV nodes)"].value(); - PassedPawnExtension[1] = Options["Passed Pawn Extension (PV nodes)"].value(); - PassedPawnExtension[0] = Options["Passed Pawn Extension (non-PV nodes)"].value(); - PawnEndgameExtension[1] = Options["Pawn Endgame Extension (PV nodes)"].value(); - PawnEndgameExtension[0] = Options["Pawn Endgame Extension (non-PV nodes)"].value(); - UCIMultiPV = Options["MultiPV"].value(); - SkillLevel = Options["Skill level"].value(); - UseLogFile = Options["Use Search Log"].value(); + UCIMultiPV = Options["MultiPV"].value(); + SkillLevel = Options["Skill level"].value(); read_evaluation_uci_options(pos.side_to_move()); @@ -509,54 +510,39 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ // Wake up needed threads and reset maxPly counter for (int i = 0; i < ThreadsMgr.active_threads(); i++) { - ThreadsMgr.wake_sleeping_thread(i); + ThreadsMgr[i].wake_up(); ThreadsMgr[i].maxPly = 0; } - // Set thinking time - int myTime = time[pos.side_to_move()]; - int myIncrement = increment[pos.side_to_move()]; - if (UseTimeManagement) - TimeMgr.init(myTime, myIncrement, movesToGo, pos.startpos_ply_counter()); - - // Set best NodesBetweenPolls interval to avoid lagging under time pressure - if (MaxNodes) - NodesBetweenPolls = Min(MaxNodes, 30000); - else if (myTime && myTime < 1000) - NodesBetweenPolls = 1000; - else if (myTime && myTime < 5000) - NodesBetweenPolls = 5000; - else - NodesBetweenPolls = 30000; - - // Write search information to log file - if (UseLogFile) + // Write to log file and keep it open to be accessed during the search + if (Options["Use Search Log"].value()) { std::string name = Options["Search Log Filename"].value(); LogFile.open(name.c_str(), std::ios::out | std::ios::app); - LogFile << "\nSearching: " << pos.to_fen() - << "\ninfinite: " << infinite - << " ponder: " << ponder - << " time: " << myTime - << " increment: " << myIncrement - << " moves to go: " << movesToGo - << endl; + if (LogFile.is_open()) + LogFile << "\nSearching: " << pos.to_fen() + << "\ninfinite: " << Limits.infinite + << " ponder: " << Limits.ponder + << " time: " << Limits.time + << " increment: " << Limits.increment + << " moves to go: " << Limits.movesToGo + << endl; } // We're ready to start thinking. Call the iterative deepening loop function Move ponderMove = MOVE_NONE; Move bestMove = id_loop(pos, searchMoves, &ponderMove); - // Print final search statistics cout << "info" << speed_to_uci(pos.nodes_searched()) << endl; - if (UseLogFile) + // Write final search statistics and close log file + if (LogFile.is_open()) { int t = current_search_time(); LogFile << "Nodes: " << pos.nodes_searched() - << "\nNodes/second: " << (t > 0 ? int(pos.nodes_searched() * 1000 / t) : 0) + << "\nNodes/second: " << (t > 0 ? pos.nodes_searched() * 1000 / t : 0) << "\nBest move: " << move_to_san(pos, bestMove); StateInfo st; @@ -571,7 +557,7 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ // If we are pondering or in infinite search, we shouldn't print the // best move before we are told to do so. - if (!StopRequest && (Pondering || InfiniteSearch)) + if (!StopRequest && (Limits.ponder || Limits.infinite)) wait_for_stop_or_ponderhit(); // Could be MOVE_NONE when searching on a stalemate position @@ -625,8 +611,8 @@ namespace { return MOVE_NONE; } - // Iterative deepening loop - while (++depth <= PLY_MAX && (!MaxDepth || depth <= MaxDepth) && !StopRequest) + // Iterative deepening loop until requested to stop or target depth reached + while (!StopRequest && ++depth <= PLY_MAX && (!Limits.maxDepth || depth <= Limits.maxDepth)) { Rml.bestMoveChanges = 0; cout << set960(pos.is_chess960()) << "info depth " << depth << endl; @@ -701,7 +687,7 @@ namespace { for (int i = 0; i < Min(UCIMultiPV, (int)Rml.size()); i++) cout << Rml[i].pv_info_to_uci(pos, depth, selDepth, alpha, beta, i) << endl; - if (UseLogFile) + if (LogFile.is_open()) LogFile << pretty_pv(pos, depth, value, current_search_time(), Rml[0].pv) << endl; // Init easyMove after first iteration or drop if differs from the best move @@ -710,20 +696,18 @@ namespace { else if (bestMove != easyMove) easyMove = MOVE_NONE; - if (UseTimeManagement && !StopRequest) + // Check for some early stop condition + if (!StopRequest && Limits.useTimeManagement()) { - // Time to stop? - bool noMoreTime = false; - // Stop search early when the last two iterations returned a mate score if ( depth >= 5 - && abs(bestValues[depth]) >= abs(VALUE_MATE) - 100 - && abs(bestValues[depth - 1]) >= abs(VALUE_MATE) - 100) - noMoreTime = true; + && abs(bestValues[depth]) >= VALUE_MATE_IN_PLY_MAX + && abs(bestValues[depth - 1]) >= VALUE_MATE_IN_PLY_MAX) + StopRequest = true; // Stop search early if one move seems to be much better than the - // others or if there is only a single legal move. In this latter - // case we search up to Iteration 8 anyway to get a proper score. + // others or if there is only a single legal move. Also in the latter + // case we search up to some depth anyway to get a proper score. if ( depth >= 7 && easyMove == bestMove && ( Rml.size() == 1 @@ -731,29 +715,27 @@ namespace { && current_search_time() > TimeMgr.available_time() / 16) ||( Rml[0].nodes > (pos.nodes_searched() * 98) / 100 && current_search_time() > TimeMgr.available_time() / 32))) - noMoreTime = true; + StopRequest = true; - // Add some extra time if the best move has changed during the last two iterations + // Take in account some extra time if the best move has changed if (depth > 4 && depth < 50) - TimeMgr.pv_instability(bestMoveChanges[depth], bestMoveChanges[depth-1]); + TimeMgr.pv_instability(bestMoveChanges[depth], bestMoveChanges[depth - 1]); - // Stop search if most of MaxSearchTime is consumed at the end of the - // iteration. We probably don't have enough time to search the first - // move at the next iteration anyway. - if (current_search_time() > (TimeMgr.available_time() * 80) / 128) - noMoreTime = true; + // Stop search if most of available time is already consumed. We probably don't + // have enough time to search the first move at the next iteration anyway. + if (current_search_time() > (TimeMgr.available_time() * 62) / 100) + StopRequest = true; - if (noMoreTime) + // If we are allowed to ponder do not stop the search now but keep pondering + if (StopRequest && Limits.ponder) { - if (Pondering) - StopOnPonderhit = true; - else - break; + StopRequest = false; + StopOnPonderhit = true; } } } - // When using skills fake best and ponder moves with the sub-optimal ones + // When using skills overwrite best and ponder moves with the sub-optimal ones if (SkillLevelEnabled) { if (skillBest == MOVE_NONE) // Still unassigned ? @@ -782,7 +764,7 @@ namespace { assert(PvNode || alpha == beta - 1); assert(pos.thread() >= 0 && pos.thread() < ThreadsMgr.active_threads()); - Move movesSearched[MOVES_MAX]; + Move movesSearched[MAX_MOVES]; int64_t nodes; StateInfo st; const TTEntry *tte; @@ -1722,8 +1704,7 @@ split_point_start: // At split points actual search starts from here && pos.type_of_piece_on(move_to(m)) != PAWN && ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) - pos.midgame_value_of_piece_on(move_to(m)) == VALUE_ZERO) - && !move_is_promotion(m) - && !move_is_ep(m)) + && !move_is_special(m)) { result += PawnEndgameExtension[PvNode]; *dangerous = true; @@ -1845,9 +1826,14 @@ split_point_start: // At split points actual search starts from here // current_search_time() returns the number of milliseconds which have passed // since the beginning of the current search. - int current_search_time() { + int current_search_time(int set) { + + static int searchStartTime; + + if (set) + searchStartTime = set; - return get_system_time() - SearchStartTime; + return get_system_time() - searchStartTime; } @@ -1863,9 +1849,9 @@ split_point_start: // At split points actual search starts from here std::stringstream s; if (abs(v) < VALUE_MATE - PLY_MAX * ONE_PLY) - s << "cp " << int(v) * 100 / int(PawnValueMidgame); // Scale to centipawns + s << "cp " << int(v) * 100 / int(PawnValueMidgame); // Scale to centipawns else - s << "mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2; + s << "mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2; return s.str(); } @@ -1905,7 +1891,7 @@ split_point_start: // At split points actual search starts from here if (!std::getline(std::cin, command) || command == "quit") { // Quit the program as soon as possible - Pondering = false; + Limits.ponder = false; QuitRequest = StopRequest = true; return; } @@ -1913,7 +1899,7 @@ split_point_start: // At split points actual search starts from here { // Stop calculating as soon as possible, but still send the "bestmove" // and possibly the "ponder" token when finishing the search. - Pondering = false; + Limits.ponder = false; StopRequest = true; } else if (command == "ponderhit") @@ -1921,7 +1907,7 @@ split_point_start: // At split points actual search starts from here // The opponent has played the expected move. GUI sends "ponderhit" if // we were told to ponder on the same move the opponent has played. We // should continue searching but switching from pondering to normal search. - Pondering = false; + Limits.ponder = false; if (StopOnPonderhit) StopRequest = true; @@ -1949,7 +1935,7 @@ split_point_start: // At split points actual search starts from here } // Should we stop the search? - if (Pondering) + if (Limits.ponder) return; bool stillAtFirstMove = FirstRootMove @@ -1959,9 +1945,9 @@ split_point_start: // At split points actual search starts from here bool noMoreTime = t > TimeMgr.maximum_time() || stillAtFirstMove; - if ( (UseTimeManagement && noMoreTime) - || (ExactMaxTime && t >= ExactMaxTime) - || (MaxNodes && pos.nodes_searched() >= MaxNodes)) // FIXME + if ( (Limits.useTimeManagement() && noMoreTime) + || (Limits.maxTime && t >= Limits.maxTime) + || (Limits.maxNodes && pos.nodes_searched() >= Limits.maxNodes)) // FIXME StopRequest = true; } @@ -2035,7 +2021,7 @@ split_point_start: // At split points actual search starts from here assert(threadID >= 0 && threadID < MAX_THREADS); int i; - bool allFinished = false; + bool allFinished; while (true) { @@ -2050,7 +2036,8 @@ split_point_start: // At split points actual search starts from here // If we are not thinking, wait for a condition to be signaled // instead of wasting CPU time polling for work. - while ( threadID >= activeThreads || threads[threadID].state == THREAD_INITIALIZING + while ( threadID >= activeThreads + || threads[threadID].state == THREAD_INITIALIZING || (useSleepingThreads && threads[threadID].state == THREAD_AVAILABLE)) { assert(!sp || useSleepingThreads); @@ -2059,7 +2046,7 @@ split_point_start: // At split points actual search starts from here if (threads[threadID].state == THREAD_INITIALIZING) threads[threadID].state = THREAD_AVAILABLE; - // Grab the lock to avoid races with wake_sleeping_thread() + // Grab the lock to avoid races with Thread::wake_up() lock_grab(&threads[threadID].sleepLock); // If we are master and all slaves have finished do not go to sleep @@ -2086,7 +2073,7 @@ split_point_start: // At split points actual search starts from here threads[threadID].state = THREAD_SEARCHING; - // Copy SplitPoint position and search stack and call search() + // Copy split point position and search stack and call search() // with SplitPoint template parameter set to true. SearchStack ss[PLY_MAX_PLUS_2]; SplitPoint* tsp = threads[threadID].splitPoint; @@ -2106,8 +2093,10 @@ split_point_start: // At split points actual search starts from here // 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 (useSleepingThreads && threadID != tsp->master && threads[tsp->master].state == THREAD_AVAILABLE) - wake_sleeping_thread(tsp->master); + if ( useSleepingThreads + && threadID != tsp->master + && threads[tsp->master].state == THREAD_AVAILABLE) + threads[tsp->master].wake_up(); } // If this thread is the master of a split point and all slaves have @@ -2133,41 +2122,36 @@ split_point_start: // At split points actual search starts from here } - // init_threads() is called during startup. It launches all helper threads, - // and initializes the split point stack and the global locks and condition - // objects. + // init_threads() is called during startup. Initializes locks and condition + // variables and launches all threads sending them immediately to sleep. void ThreadsManager::init_threads() { int i, arg[MAX_THREADS]; bool ok; - // Initialize global locks + // This flag is needed to properly end the threads when program exits + allThreadsShouldExit = false; + + // Threads will sent to sleep as soon as created, only main thread is kept alive + activeThreads = 1; + lock_init(&mpLock); for (i = 0; i < MAX_THREADS; i++) { + // Initialize thread and split point locks lock_init(&threads[i].sleepLock); cond_init(&threads[i].sleepCond); - } - // Initialize splitPoints[] locks - for (i = 0; i < MAX_THREADS; i++) for (int j = 0; j < MAX_ACTIVE_SPLIT_POINTS; j++) lock_init(&(threads[i].splitPoints[j].lock)); - // Will be set just before program exits to properly end the threads - allThreadsShouldExit = false; - - // Threads will be put all threads to sleep as soon as created - activeThreads = 1; - - // All threads except the main thread should be initialized to THREAD_INITIALIZING - threads[0].state = THREAD_SEARCHING; - for (i = 1; i < MAX_THREADS; i++) - threads[i].state = THREAD_INITIALIZING; + // All threads but first should be set to THREAD_INITIALIZING + threads[i].state = (i == 0 ? THREAD_SEARCHING : THREAD_INITIALIZING); + } - // Launch the helper threads + // Create and startup the threads for (i = 1; i < MAX_THREADS; i++) { arg[i] = i; @@ -2196,28 +2180,27 @@ split_point_start: // At split points actual search starts from here void ThreadsManager::exit_threads() { - allThreadsShouldExit = true; // Let the woken up threads to exit idle_loop() + // Force the woken up threads to exit idle_loop() and hence terminate + allThreadsShouldExit = true; - // Wake up all the threads and waits for termination - for (int i = 1; i < MAX_THREADS; i++) + for (int i = 0; i < MAX_THREADS; i++) { - wake_sleeping_thread(i); - while (threads[i].state != THREAD_TERMINATED) {} - } + // Wake up all the threads and waits for termination + if (i != 0) + { + threads[i].wake_up(); + while (threads[i].state != THREAD_TERMINATED) {} + } + + // Now we can safely destroy the locks and wait conditions + lock_destroy(&threads[i].sleepLock); + cond_destroy(&threads[i].sleepCond); - // Now we can safely destroy the locks - for (int i = 0; i < MAX_THREADS; i++) for (int j = 0; j < MAX_ACTIVE_SPLIT_POINTS; j++) lock_destroy(&(threads[i].splitPoints[j].lock)); + } lock_destroy(&mpLock); - - // Now we can safely destroy the wait conditions - for (int i = 0; i < MAX_THREADS; i++) - { - lock_destroy(&threads[i].sleepLock); - cond_destroy(&threads[i].sleepCond); - } } @@ -2376,7 +2359,7 @@ split_point_start: // At split points actual search starts from here threads[i].state = THREAD_WORKISWAITING; // This makes the slave to exit from idle_loop() if (useSleepingThreads && i != master) - wake_sleeping_thread(i); + threads[i].wake_up(); } // Everything is set up. The master thread enters the idle loop, from @@ -2400,17 +2383,6 @@ split_point_start: // At split points actual search starts from here } - // wake_sleeping_thread() wakes up the thread with the given threadID - // when it is time to start a new search. - - void ThreadsManager::wake_sleeping_thread(int threadID) { - - lock_grab(&threads[threadID].sleepLock); - cond_signal(&threads[threadID].sleepCond); - lock_release(&threads[threadID].sleepLock); - } - - /// RootMove and RootMoveList method's definitions RootMove::RootMove() { @@ -2518,7 +2490,7 @@ split_point_start: // At split points actual search starts from here void RootMoveList::init(Position& pos, Move searchMoves[]) { - MoveStack mlist[MOVES_MAX]; + MoveStack mlist[MAX_MOVES]; Move* sm; clear();