mutex.lock();
// If we are master and all slaves have finished then exit idle_loop
- if (this_sp && !this_sp->slavesMask)
+ if (this_sp && this_sp->slavesMask.none())
{
mutex.unlock();
break;
searching = false;
activePosition = NULL;
- sp->slavesMask &= ~(1ULL << idx);
+ sp->slavesMask.reset(idx);
sp->nodes += pos.nodes_searched();
// Wake up the master thread so to allow it to return from the idle
// loop in case we are the last slave of the split point.
if ( Threads.sleepWhileIdle
&& this != sp->masterThread
- && !sp->slavesMask)
+ && sp->slavesMask.none())
{
assert(!sp->masterThread->searching);
sp->masterThread->notify_one();
// 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.
- if (this_sp && !this_sp->slavesMask)
+ if (this_sp && this_sp->slavesMask.none())
{
this_sp->mutex.lock();
- bool finished = !this_sp->slavesMask; // Retest under lock protection
+ bool finished = this_sp->slavesMask.none(); // Retest under lock protection
this_sp->mutex.unlock();
if (finished)
return;
sp.mutex.lock();
nodes += sp.nodes;
- Bitboard sm = sp.slavesMask;
- while (sm)
- {
- Position* pos = Threads[pop_lsb(&sm)]->activePosition;
- if (pos)
- nodes += pos->nodes_searched();
- }
+
+ for (size_t idx = 0; idx < Threads.size(); ++idx)
+ if (sp.slavesMask.test(idx) && Threads[idx]->activePosition)
+ nodes += Threads[idx]->activePosition->nodes_searched();
sp.mutex.unlock();
}
// No split points means that the thread is available as a slave for any
// other thread otherwise apply the "helpful master" concept if possible.
- return !size || (splitPoints[size - 1].slavesMask & (1ULL << master->idx));
+ return !size || splitPoints[size - 1].slavesMask.test(master->idx);
}
sp.masterThread = this;
sp.parentSplitPoint = activeSplitPoint;
- sp.slavesMask = 1ULL << idx;
+ sp.slavesMask = 0, sp.slavesMask.set(idx);
sp.depth = depth;
sp.bestValue = *bestValue;
sp.bestMove = *bestMove;
if (!Fake)
for (Thread* slave; (slave = Threads.available_slave(this)) != NULL; )
{
- sp.slavesMask |= 1ULL << slave->idx;
+ sp.slavesMask.set(slave->idx);
slave->activeSplitPoint = &sp;
slave->searching = true; // Slave leaves idle_loop()
slave->notify_one(); // Could be sleeping
#ifndef THREAD_H_INCLUDED
#define THREAD_H_INCLUDED
+#include <bitset>
#include <vector>
#include "material.h"
#include "position.h"
#include "search.h"
-const int MAX_THREADS = 64; // Because SplitPoint::slavesMask is a uint64_t
+const int MAX_THREADS = 128;
const int MAX_SPLITPOINTS_PER_THREAD = 8;
struct Mutex {
// Shared data
Mutex mutex;
- volatile uint64_t slavesMask;
+ std::bitset<MAX_THREADS> slavesMask;
volatile uint64_t nodes;
volatile Value alpha;
volatile Value bestValue;