mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 19:49:14 +00:00
Big renaming in thread stuff
No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
c465f4c4df
commit
588670e8d2
6 changed files with 62 additions and 59 deletions
|
@ -130,8 +130,8 @@ void benchmark(const Position& current, istream& is) {
|
|||
}
|
||||
else
|
||||
{
|
||||
Threads.start_searching(pos, limits, vector<Move>(), st);
|
||||
Threads.wait_for_search_finished();
|
||||
Threads.start_thinking(pos, limits, vector<Move>(), st);
|
||||
Threads.wait_for_think_finished();
|
||||
nodes += Search::RootPos.nodes_searched();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
/// The checkInfo struct is initialized at c'tor time and keeps info used
|
||||
/// to detect if a move gives check.
|
||||
class Position;
|
||||
class Thread;
|
||||
struct Thread;
|
||||
|
||||
struct CheckInfo {
|
||||
|
||||
|
|
|
@ -1007,7 +1007,7 @@ split_point_start: // At split points actual search starts from here
|
|||
|
||||
// Step 19. Check for splitting the search
|
||||
if ( !SpNode
|
||||
&& depth >= Threads.min_split_depth()
|
||||
&& depth >= Threads.minimumSplitDepth
|
||||
&& Threads.available_slave_exists(thisThread))
|
||||
{
|
||||
assert(bestValue < beta);
|
||||
|
@ -1558,7 +1558,7 @@ void Thread::idle_loop() {
|
|||
// object for which the thread is the master.
|
||||
const SplitPoint* sp_master = splitPointsCnt ? curSplitPoint : NULL;
|
||||
|
||||
assert(!sp_master || (sp_master->master == this && is_searching));
|
||||
assert(!sp_master || (sp_master->master == this && searching));
|
||||
|
||||
// If this thread is the master of a split point and all slaves have
|
||||
// finished their work at this split point, return from the idle loop.
|
||||
|
@ -1566,9 +1566,9 @@ void Thread::idle_loop() {
|
|||
{
|
||||
// If we are not searching, wait for a condition to be signaled
|
||||
// instead of wasting CPU time polling for work.
|
||||
while (do_exit || (!is_searching && Threads.sleepWhileIdle))
|
||||
while ((!searching && Threads.sleepWhileIdle) || exit)
|
||||
{
|
||||
if (do_exit)
|
||||
if (exit)
|
||||
{
|
||||
assert(!sp_master);
|
||||
return;
|
||||
|
@ -1588,20 +1588,20 @@ void Thread::idle_loop() {
|
|||
// particular we need to avoid a deadlock in case a master thread has,
|
||||
// in the meanwhile, allocated us and sent the wake_up() call before we
|
||||
// had the chance to grab the lock.
|
||||
if (!is_searching && !do_exit)
|
||||
if (!searching && !exit)
|
||||
sleepCondition.wait(mutex);
|
||||
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
// If this thread has been assigned work, launch a search
|
||||
if (is_searching)
|
||||
if (searching)
|
||||
{
|
||||
assert(!do_exit);
|
||||
assert(!exit);
|
||||
|
||||
Threads.mutex.lock();
|
||||
|
||||
assert(is_searching);
|
||||
assert(searching);
|
||||
SplitPoint* sp = curSplitPoint;
|
||||
|
||||
Threads.mutex.unlock();
|
||||
|
@ -1627,9 +1627,9 @@ void Thread::idle_loop() {
|
|||
else
|
||||
assert(false);
|
||||
|
||||
assert(is_searching);
|
||||
assert(searching);
|
||||
|
||||
is_searching = false;
|
||||
searching = false;
|
||||
sp->activePositions[idx] = NULL;
|
||||
sp->slavesMask &= ~(1ULL << idx);
|
||||
sp->nodes += pos.nodes_searched();
|
||||
|
@ -1640,7 +1640,7 @@ void Thread::idle_loop() {
|
|||
&& this != sp->master
|
||||
&& !sp->slavesMask)
|
||||
{
|
||||
assert(!sp->master->is_searching);
|
||||
assert(!sp->master->searching);
|
||||
sp->master->notify_one();
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace { extern "C" {
|
|||
|
||||
Thread::Thread() : splitPoints() {
|
||||
|
||||
is_searching = do_exit = false;
|
||||
searching = exit = false;
|
||||
maxPly = splitPointsCnt = 0;
|
||||
curSplitPoint = NULL;
|
||||
idx = Threads.size();
|
||||
|
@ -61,7 +61,7 @@ Thread::Thread() : splitPoints() {
|
|||
|
||||
Thread::~Thread() {
|
||||
|
||||
do_exit = true; // Search must be already finished
|
||||
exit = true; // Search must be already finished
|
||||
notify_one();
|
||||
thread_join(handle); // Wait for thread termination
|
||||
}
|
||||
|
@ -73,11 +73,11 @@ extern void check_time();
|
|||
|
||||
void TimerThread::idle_loop() {
|
||||
|
||||
while (!do_exit)
|
||||
while (!exit)
|
||||
{
|
||||
mutex.lock();
|
||||
|
||||
if (!do_exit)
|
||||
if (!exit)
|
||||
sleepCondition.wait_for(mutex, msec ? msec : INT_MAX);
|
||||
|
||||
mutex.unlock();
|
||||
|
@ -97,10 +97,9 @@ void MainThread::idle_loop() {
|
|||
{
|
||||
mutex.lock();
|
||||
|
||||
is_finished = true; // Always return to sleep after a search
|
||||
is_searching = false;
|
||||
thinking = false;
|
||||
|
||||
while (is_finished && !do_exit)
|
||||
while (!thinking && !exit)
|
||||
{
|
||||
Threads.sleepCondition.notify_one(); // Wake up UI thread if needed
|
||||
sleepCondition.wait(mutex);
|
||||
|
@ -108,19 +107,21 @@ void MainThread::idle_loop() {
|
|||
|
||||
mutex.unlock();
|
||||
|
||||
if (do_exit)
|
||||
if (exit)
|
||||
return;
|
||||
|
||||
is_searching = true;
|
||||
searching = true;
|
||||
|
||||
Search::think();
|
||||
|
||||
assert(is_searching);
|
||||
assert(searching);
|
||||
|
||||
searching = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Thread::notify_one() wakes up the thread, normally at split time
|
||||
// Thread::notify_one() wakes up the thread when there is some search to do
|
||||
|
||||
void Thread::notify_one() {
|
||||
|
||||
|
@ -162,7 +163,7 @@ bool Thread::cutoff_occurred() const {
|
|||
|
||||
bool Thread::is_available_to(Thread* master) const {
|
||||
|
||||
if (is_searching)
|
||||
if (searching)
|
||||
return false;
|
||||
|
||||
// Make a local copy to be sure doesn't become zero under our feet while
|
||||
|
@ -283,7 +284,7 @@ Value ThreadPool::split(Position& pos, Stack* ss, Value alpha, Value beta,
|
|||
sp.nodes = 0;
|
||||
sp.ss = ss;
|
||||
|
||||
assert(master->is_searching);
|
||||
assert(master->searching);
|
||||
|
||||
master->curSplitPoint = &sp;
|
||||
int slavesCnt = 0;
|
||||
|
@ -299,7 +300,7 @@ Value ThreadPool::split(Position& pos, Stack* ss, Value alpha, Value beta,
|
|||
{
|
||||
sp.slavesMask |= 1ULL << i;
|
||||
threads[i]->curSplitPoint = &sp;
|
||||
threads[i]->is_searching = true; // Slave leaves idle_loop()
|
||||
threads[i]->searching = true; // Slave leaves idle_loop()
|
||||
threads[i]->notify_one(); // Could be sleeping
|
||||
|
||||
if (++slavesCnt + 1 >= maxThreadsPerSplitPoint) // Master is always included
|
||||
|
@ -321,7 +322,7 @@ Value ThreadPool::split(Position& pos, Stack* ss, Value alpha, Value beta,
|
|||
|
||||
// In helpful master concept a master can help only a sub-tree of its split
|
||||
// point, and because here is all finished is not possible master is booked.
|
||||
assert(!master->is_searching);
|
||||
assert(!master->searching);
|
||||
}
|
||||
|
||||
// We have returned from the idle loop, which means that all threads are
|
||||
|
@ -330,7 +331,7 @@ Value ThreadPool::split(Position& pos, Stack* ss, Value alpha, Value beta,
|
|||
mutex.lock();
|
||||
sp.mutex.lock();
|
||||
|
||||
master->is_searching = true;
|
||||
master->searching = true;
|
||||
master->splitPointsCnt--;
|
||||
master->curSplitPoint = sp.parent;
|
||||
pos.set_nodes_searched(pos.nodes_searched() + sp.nodes);
|
||||
|
@ -347,24 +348,23 @@ template Value ThreadPool::split<false>(Position&, Stack*, Value, Value, Value,
|
|||
template Value ThreadPool::split<true>(Position&, Stack*, Value, Value, Value, Move*, Depth, Move, int, MovePicker&, int);
|
||||
|
||||
|
||||
// wait_for_search_finished() waits for main thread to go to sleep, this means
|
||||
// search is finished. Then returns.
|
||||
// wait_for_think_finished() waits for main thread to go to sleep then returns
|
||||
|
||||
void ThreadPool::wait_for_search_finished() {
|
||||
void ThreadPool::wait_for_think_finished() {
|
||||
|
||||
MainThread* t = main_thread();
|
||||
t->mutex.lock();
|
||||
while (!t->is_finished) sleepCondition.wait(t->mutex);
|
||||
while (t->thinking) sleepCondition.wait(t->mutex);
|
||||
t->mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
// start_searching() wakes up the main thread sleeping in main_loop() so to start
|
||||
// start_thinking() wakes up the main thread sleeping in main_loop() so to start
|
||||
// a new search, then returns immediately.
|
||||
|
||||
void ThreadPool::start_searching(const Position& pos, const LimitsType& limits,
|
||||
void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits,
|
||||
const std::vector<Move>& searchMoves, StateStackPtr& states) {
|
||||
wait_for_search_finished();
|
||||
wait_for_think_finished();
|
||||
|
||||
SearchTime = Time::now(); // As early as possible
|
||||
|
||||
|
@ -380,6 +380,6 @@ void ThreadPool::start_searching(const Position& pos, const LimitsType& limits,
|
|||
if (searchMoves.empty() || count(searchMoves.begin(), searchMoves.end(), ml.move()))
|
||||
RootMoves.push_back(RootMove(ml.move()));
|
||||
|
||||
main_thread()->is_finished = false;
|
||||
main_thread()->thinking = true;
|
||||
main_thread()->notify_one(); // Starts main thread
|
||||
}
|
||||
|
|
39
src/thread.h
39
src/thread.h
|
@ -56,7 +56,7 @@ private:
|
|||
WaitCondition c;
|
||||
};
|
||||
|
||||
class Thread;
|
||||
struct Thread;
|
||||
|
||||
struct SplitPoint {
|
||||
|
||||
|
@ -91,9 +91,8 @@ struct SplitPoint {
|
|||
/// tables so that once we get a pointer to an entry its life time is unlimited
|
||||
/// and we don't have to care about someone changing the entry under our feet.
|
||||
|
||||
class Thread {
|
||||
struct Thread {
|
||||
|
||||
public:
|
||||
Thread();
|
||||
virtual ~Thread();
|
||||
|
||||
|
@ -114,8 +113,18 @@ public:
|
|||
NativeHandle handle;
|
||||
SplitPoint* volatile curSplitPoint;
|
||||
volatile int splitPointsCnt;
|
||||
volatile bool is_searching;
|
||||
volatile bool do_exit;
|
||||
volatile bool searching;
|
||||
volatile bool exit;
|
||||
};
|
||||
|
||||
|
||||
/// MainThread and TimerThread are sublassed from Thread to charaterize the two
|
||||
/// special threads: the main one and the recurring timer.
|
||||
|
||||
struct MainThread : public Thread {
|
||||
MainThread() : thinking(true) {} // Avoid a race with start_thinking()
|
||||
virtual void idle_loop();
|
||||
volatile bool thinking;
|
||||
};
|
||||
|
||||
struct TimerThread : public Thread {
|
||||
|
@ -124,12 +133,6 @@ struct TimerThread : public Thread {
|
|||
int msec;
|
||||
};
|
||||
|
||||
struct MainThread : public Thread {
|
||||
MainThread() : is_finished(false) {} // Avoid a race with start_searching()
|
||||
virtual void idle_loop();
|
||||
volatile bool is_finished;
|
||||
};
|
||||
|
||||
|
||||
/// ThreadPool class handles all the threads related stuff like init, starting,
|
||||
/// parking and, the most important, launching a slave thread at a split point.
|
||||
|
@ -142,22 +145,25 @@ public:
|
|||
void exit(); // be initialized and valid during the whole thread lifetime.
|
||||
|
||||
Thread& operator[](size_t id) { return *threads[id]; }
|
||||
int min_split_depth() const { return minimumSplitDepth; }
|
||||
size_t size() const { return threads.size(); }
|
||||
MainThread* main_thread() { return static_cast<MainThread*>(threads[0]); }
|
||||
TimerThread* timer_thread() { return timer; }
|
||||
|
||||
void read_uci_options();
|
||||
bool available_slave_exists(Thread* master) const;
|
||||
void wait_for_search_finished();
|
||||
void start_searching(const Position&, const Search::LimitsType&,
|
||||
void wait_for_think_finished();
|
||||
void start_thinking(const Position&, const Search::LimitsType&,
|
||||
const std::vector<Move>&, Search::StateStackPtr&);
|
||||
|
||||
template <bool Fake>
|
||||
Value split(Position& pos, Search::Stack* ss, Value alpha, Value beta, Value bestValue, Move* bestMove,
|
||||
Depth depth, Move threatMove, int moveCount, MovePicker& mp, int nodeType);
|
||||
|
||||
bool sleepWhileIdle;
|
||||
Depth minimumSplitDepth;
|
||||
|
||||
private:
|
||||
friend class Thread;
|
||||
friend struct Thread;
|
||||
friend struct MainThread;
|
||||
friend void check_time();
|
||||
|
||||
|
@ -165,10 +171,7 @@ private:
|
|||
TimerThread* timer;
|
||||
Mutex mutex;
|
||||
ConditionVariable sleepCondition;
|
||||
Depth minimumSplitDepth;
|
||||
int maxThreadsPerSplitPoint;
|
||||
public:
|
||||
bool sleepWhileIdle;
|
||||
};
|
||||
|
||||
extern ThreadPool Threads;
|
||||
|
|
|
@ -113,7 +113,7 @@ void UCI::loop(const string& args) {
|
|||
|
||||
} while (token != "quit" && args.empty()); // Args have one-shot behaviour
|
||||
|
||||
Threads.wait_for_search_finished(); // Cannot quit while search is running
|
||||
Threads.wait_for_think_finished(); // Cannot quit while search is running
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,6 +207,6 @@ namespace {
|
|||
else if (token == "ponder") limits.ponder = true;
|
||||
}
|
||||
|
||||
Threads.start_searching(pos, limits, searchMoves, SetupStates);
|
||||
Threads.start_thinking(pos, limits, searchMoves, SetupStates);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue