static storage duration are automatically set to zero before enter main()
*/
public:
+ Thread& operator[](int threadID) { return threads[threadID]; }
void init_threads();
void exit_threads();
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 <bool Fake>
void extract_pv_from_tt(Position& pos);
void insert_pv_in_tt(Position& pos);
- std::string pv_info_to_uci(Position& pos, int depth, 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;
ThreadsMgr.read_uci_options();
init_eval(ThreadsMgr.active_threads());
- // Wake up needed threads. Main thread, with threadID == 0, is always active
- for (int i = 1; i < ThreadsMgr.active_threads(); i++)
- ThreadsMgr.wake_sleeping_thread(i);
+ // Wake up needed threads and reset maxPly counter
+ for (int i = 0; i < ThreadsMgr.active_threads(); i++)
+ {
+ ThreadsMgr[i].wake_up();
+ ThreadsMgr[i].maxPly = 0;
+ }
// Set thinking time
int myTime = time[pos.side_to_move()];
SearchStack ss[PLY_MAX_PLUS_2];
Value bestValues[PLY_MAX_PLUS_2];
int bestMoveChanges[PLY_MAX_PLUS_2];
- int depth, aspirationDelta;
+ int depth, selDepth, aspirationDelta;
Value value, alpha, beta;
Move bestMove, easyMove, skillBest, skillPonder;
if (SkillLevelEnabled && depth == 1 + SkillLevel)
do_skill_level(&skillBest, &skillPonder);
+ // Retrieve max searched depth among threads
+ selDepth = 0;
+ for (int i = 0; i < ThreadsMgr.active_threads(); i++)
+ if (ThreadsMgr[i].maxPly > selDepth)
+ selDepth = ThreadsMgr[i].maxPly;
+
// Send PV line to GUI and to log file
for (int i = 0; i < Min(UCIMultiPV, (int)Rml.size()); i++)
- cout << Rml[i].pv_info_to_uci(pos, depth, alpha, beta, i) << endl;
+ cout << Rml[i].pv_info_to_uci(pos, depth, selDepth, alpha, beta, i) << endl;
if (UseLogFile)
LogFile << pretty_pv(pos, depth, value, current_search_time(), Rml[0].pv) << endl;
isCheck = pos.is_check();
ss->ply = (ss-1)->ply + 1;
+ // Used to send selDepth info to GUI
+ if (PvNode && ThreadsMgr[threadID].maxPly < ss->ply)
+ ThreadsMgr[threadID].maxPly = ss->ply;
+
if (SpNode)
{
sp = ss->sp;
// 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);
+ threads[tsp->master].wake_up();
}
// If this thread is the master of a split point and all slaves have
// Wake up all the threads and waits for termination
for (int i = 1; i < MAX_THREADS; i++)
{
- wake_sleeping_thread(i);
+ threads[i].wake_up();
while (threads[i].state != THREAD_TERMINATED) {}
}
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
}
- // 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() {
// pv_info_to_uci() returns a string with information on the current PV line
// formatted according to UCI specification.
- std::string RootMove::pv_info_to_uci(Position& pos, int depth, Value alpha,
+ std::string RootMove::pv_info_to_uci(Position& pos, int depth, int selDepth, Value alpha,
Value beta, int pvIdx) {
- std::stringstream s, l;
- Move* m = pv;
-
- while (*m != MOVE_NONE)
- l << *m++ << " ";
+ std::stringstream s;
s << "info depth " << depth
- << " seldepth " << int(m - pv)
+ << " seldepth " << selDepth
<< " multipv " << pvIdx + 1
<< " score " << value_to_uci(pv_score)
<< (pv_score >= beta ? " lowerbound" : pv_score <= alpha ? " upperbound" : "")
<< speed_to_uci(pos.nodes_searched())
- << " pv " << l.str();
+ << " pv ";
+
+ for (Move* m = pv; *m != MOVE_NONE; m++)
+ s << *m << " ";
return s.str();
}