1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 00:33:09 +00:00

Derive ThreadPool from std::vector

Prefer sub-classing to composition in this case.

No functional change.
This commit is contained in:
Marco Costalba 2013-02-04 22:38:42 +01:00
parent 91427c8242
commit 1a414cd9cb
3 changed files with 32 additions and 36 deletions

View file

@ -229,22 +229,22 @@ void Search::think() {
// Reset the threads, still sleeping: will be wake up at split time // Reset the threads, still sleeping: will be wake up at split time
for (size_t i = 0; i < Threads.size(); i++) for (size_t i = 0; i < Threads.size(); i++)
Threads[i].maxPly = 0; Threads[i]->maxPly = 0;
Threads.sleepWhileIdle = Options["Use Sleeping Threads"]; Threads.sleepWhileIdle = Options["Use Sleeping Threads"];
// Set best timer interval to avoid lagging under time pressure. Timer is // Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time. // used to check for remaining available thinking time.
Threads.timer_thread()->msec = Threads.timer->msec =
Limits.use_time_management() ? std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)) : Limits.use_time_management() ? std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)) :
Limits.nodes ? 2 * TimerResolution Limits.nodes ? 2 * TimerResolution
: 100; : 100;
Threads.timer_thread()->notify_one(); // Wake up the recurring timer Threads.timer->notify_one(); // Wake up the recurring timer
id_loop(RootPos); // Let's start searching ! id_loop(RootPos); // Let's start searching !
Threads.timer_thread()->msec = 0; // Stop the timer Threads.timer->msec = 0; // Stop the timer
Threads.sleepWhileIdle = true; // Send idle threads to sleep Threads.sleepWhileIdle = true; // Send idle threads to sleep
if (Options["Use Search Log"]) if (Options["Use Search Log"])
@ -1513,8 +1513,8 @@ split_point_start: // At split points actual search starts from here
int selDepth = 0; int selDepth = 0;
for (size_t i = 0; i < Threads.size(); i++) for (size_t i = 0; i < Threads.size(); i++)
if (Threads[i].maxPly > selDepth) if (Threads[i]->maxPly > selDepth)
selDepth = Threads[i].maxPly; selDepth = Threads[i]->maxPly;
for (size_t i = 0; i < uciPVSize; i++) for (size_t i = 0; i < uciPVSize; i++)
{ {
@ -1744,9 +1744,9 @@ void check_time() {
// Loop across all split points and sum accumulated SplitPoint nodes plus // Loop across all split points and sum accumulated SplitPoint nodes plus
// all the currently active slaves positions. // all the currently active slaves positions.
for (size_t i = 0; i < Threads.size(); i++) for (size_t i = 0; i < Threads.size(); i++)
for (int j = 0; j < Threads[i].splitPointsSize; j++) for (int j = 0; j < Threads[i]->splitPointsSize; j++)
{ {
SplitPoint& sp = Threads[i].splitPoints[j]; SplitPoint& sp = Threads[i]->splitPoints[j];
sp.mutex.lock(); sp.mutex.lock();

View file

@ -186,7 +186,7 @@ void ThreadPool::init() {
sleepWhileIdle = true; sleepWhileIdle = true;
timer = new TimerThread(); timer = new TimerThread();
threads.push_back(new MainThread()); push_back(new MainThread());
read_uci_options(); read_uci_options();
} }
@ -197,8 +197,8 @@ void ThreadPool::exit() {
delete timer; // As first because check_time() accesses threads data delete timer; // As first because check_time() accesses threads data
for (size_t i = 0; i < threads.size(); i++) for (iterator it = begin(); it != end(); ++it)
delete threads[i]; delete *it;
} }
@ -215,13 +215,13 @@ void ThreadPool::read_uci_options() {
assert(requested > 0); assert(requested > 0);
while (threads.size() < requested) while (size() < requested)
threads.push_back(new Thread()); push_back(new Thread());
while (threads.size() > requested) while (size() > requested)
{ {
delete threads.back(); delete back();
threads.pop_back(); pop_back();
} }
} }
@ -231,8 +231,8 @@ void ThreadPool::read_uci_options() {
bool ThreadPool::slave_available(Thread* master) const { bool ThreadPool::slave_available(Thread* master) const {
for (size_t i = 0; i < threads.size(); i++) for (const_iterator it = begin(); it != end(); ++it)
if (threads[i]->is_available_to(master)) if ((*it)->is_available_to(master))
return true; return true;
return false; return false;
@ -290,16 +290,20 @@ Value Thread::split(Position& pos, Stack* ss, Value alpha, Value beta,
splitPointsSize++; splitPointsSize++;
activeSplitPoint = &sp; activeSplitPoint = &sp;
size_t slavesCnt = 1; // Master is always included size_t slavesCnt = 1; // This thread is always included
for (size_t i = 0; i < Threads.size() && !Fake; ++i) for (ThreadPool::iterator it = Threads.begin(); it != Threads.end() && !Fake; ++it)
if (Threads[i].is_available_to(this) && ++slavesCnt <= Threads.maxThreadsPerSplitPoint) {
Thread* slave = *it;
if (slave->is_available_to(this) && ++slavesCnt <= Threads.maxThreadsPerSplitPoint)
{ {
sp.slavesMask |= 1ULL << Threads[i].idx; sp.slavesMask |= 1ULL << slave->idx;
Threads[i].activeSplitPoint = &sp; slave->activeSplitPoint = &sp;
Threads[i].searching = true; // Slave leaves idle_loop() slave->searching = true; // Slave leaves idle_loop()
Threads[i].notify_one(); // Could be sleeping slave->notify_one(); // Could be sleeping
} }
}
sp.mutex.unlock(); sp.mutex.unlock();
Threads.mutex.unlock(); Threads.mutex.unlock();

View file

@ -138,21 +138,16 @@ struct TimerThread : public Thread {
}; };
/// ThreadPool class handles all the threads related stuff like init, starting, /// ThreadPool struct handles all the threads related stuff like init, starting,
/// parking and, the most important, launching a slave thread at a split point. /// parking and, the most important, launching a slave thread at a split point.
/// All the access to shared thread data is done through this class. /// All the access to shared thread data is done through this class.
class ThreadPool { struct ThreadPool : public std::vector<Thread*> {
public:
void init(); // No c'tor and d'tor, threads rely on globals that should void init(); // No c'tor and d'tor, threads rely on globals that should
void exit(); // be initialized and valid during the whole thread lifetime. void exit(); // be initialized and valid during the whole thread lifetime.
Thread& operator[](size_t id) { return *threads[id]; } MainThread* main_thread() { return static_cast<MainThread*>((*this)[0]); }
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(); void read_uci_options();
bool slave_available(Thread* master) const; bool slave_available(Thread* master) const;
void wait_for_think_finished(); void wait_for_think_finished();
@ -164,9 +159,6 @@ public:
size_t maxThreadsPerSplitPoint; size_t maxThreadsPerSplitPoint;
Mutex mutex; Mutex mutex;
ConditionVariable sleepCondition; ConditionVariable sleepCondition;
private:
std::vector<Thread*> threads;
TimerThread* timer; TimerThread* timer;
}; };