Also assure in Thread::timer_loop() that when
timer interval is 0 (timer is disabled) we
never call check_time()
No functional change.
// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
- if (Limits.use_time_management())
- Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 16,
- TimerResolution)));
- else if (Limits.nodes)
- Threads.set_timer(2 * TimerResolution);
- else
- Threads.set_timer(100);
+ Threads.timer_thread()->maxPly = /* Hack: we use maxPly to set timer interval */
+ Limits.use_time_management() ? std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)) :
+ Limits.nodes ? 2 * TimerResolution
+ : 100;
+
+ Threads.timer_thread()->notify_one(); // Wake up the recurring timer
id_loop(RootPos); // Let's start searching !
id_loop(RootPos); // Let's start searching !
- Threads.set_timer(0); // Stop timer
+ Threads.timer_thread()->maxPly = 0; // Stop the timer
// Main thread will go to sleep by itself to avoid a race with start_searching()
for (size_t i = 0; i < Threads.size(); i++)
// Main thread will go to sleep by itself to avoid a race with start_searching()
for (size_t i = 0; i < Threads.size(); i++)
while (!do_exit)
{
mutex.lock();
while (!do_exit)
{
mutex.lock();
- sleepCondition.wait_for(mutex, maxPly ? maxPly : INT_MAX);
+ while (!maxPly && !do_exit)
+ sleepCondition.wait_for(mutex, maxPly ? maxPly : INT_MAX);
mutex.unlock();
check_time();
}
mutex.unlock();
check_time();
}
-// set_timer() is used to set the timer to trigger after msec milliseconds.
-// If msec is 0 then timer is stopped.
-
-void ThreadPool::set_timer(int msec) {
-
- timer->maxPly = msec;
- timer->notify_one(); // Wake up and restart the timer
-}
-
-
// split() does the actual work of distributing the work at a node between
// several available threads. If it does not succeed in splitting the node
// (because no idle threads are available, or because we have no unused split
// split() does the actual work of distributing the work at a node between
// several available threads. If it does not succeed in splitting the node
// (because no idle threads are available, or because we have no unused split
int min_split_depth() const { return minimumSplitDepth; }
size_t size() const { return threads.size(); }
Thread* main_thread() { return threads[0]; }
int min_split_depth() const { return minimumSplitDepth; }
size_t size() const { return threads.size(); }
Thread* main_thread() { return threads[0]; }
+ Thread* timer_thread() { return timer; }
void read_uci_options();
bool available_slave_exists(Thread* master) const;
void read_uci_options();
bool available_slave_exists(Thread* master) const;
- void set_timer(int msec);
void wait_for_search_finished();
void start_searching(const Position&, const Search::LimitsType&,
const std::vector<Move>&, Search::StateStackPtr&);
void wait_for_search_finished();
void start_searching(const Position&, const Search::LimitsType&,
const std::vector<Move>&, Search::StateStackPtr&);