Skip to content

Commit

Permalink
Retire spinlocks
Browse files Browse the repository at this point in the history
Use Mutex instead.

This is in preparaation for merging with master branch,
where we stilll don't have spinlocks.

Eventually spinlocks will be readded in some future
patch, once c++11 has been merged.

No functional change.
  • Loading branch information
mcostalba committed Mar 11, 2015
1 parent 6027652 commit 4b59347
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 39 deletions.
34 changes: 17 additions & 17 deletions src/search.cpp
Expand Up @@ -765,7 +765,7 @@ namespace {
continue;

moveCount = ++splitPoint->moveCount;
splitPoint->spinlock.release();
splitPoint->mutex.unlock();
}
else
++moveCount;
Expand Down Expand Up @@ -834,7 +834,7 @@ namespace {
&& moveCount >= FutilityMoveCounts[improving][depth])
{
if (SpNode)
splitPoint->spinlock.acquire();
splitPoint->mutex.lock();

continue;
}
Expand All @@ -853,7 +853,7 @@ namespace {

if (SpNode)
{
splitPoint->spinlock.acquire();
splitPoint->mutex.lock();
if (bestValue > splitPoint->bestValue)
splitPoint->bestValue = bestValue;
}
Expand All @@ -865,7 +865,7 @@ namespace {
if (predictedDepth < 4 * ONE_PLY && pos.see_sign(move) < VALUE_ZERO)
{
if (SpNode)
splitPoint->spinlock.acquire();
splitPoint->mutex.lock();

continue;
}
Expand Down Expand Up @@ -965,7 +965,7 @@ namespace {
// Step 18. Check for new best move
if (SpNode)
{
splitPoint->spinlock.acquire();
splitPoint->mutex.lock();
bestValue = splitPoint->bestValue;
alpha = splitPoint->alpha;
}
Expand Down Expand Up @@ -1526,21 +1526,21 @@ void Thread::idle_loop() {
// If this thread has been assigned work, launch a search
while (searching)
{
Threads.spinlock.acquire();
Threads.mutex.lock();

assert(activeSplitPoint);

SplitPoint* sp = activeSplitPoint;

Threads.spinlock.release();
Threads.mutex.unlock();

Stack stack[MAX_PLY+4], *ss = stack+2; // To allow referencing (ss-2) and (ss+2)
Position pos(*sp->pos, this);

std::memcpy(ss-2, sp->ss-2, 5 * sizeof(Stack));
ss->splitPoint = sp;

sp->spinlock.acquire();
sp->mutex.lock();

assert(activePosition == nullptr);

Expand Down Expand Up @@ -1578,7 +1578,7 @@ void Thread::idle_loop() {
// After releasing the lock we can't access any SplitPoint related data
// in a safe way because it could have been released under our feet by
// the sp master.
sp->spinlock.release();
sp->mutex.unlock();

// Try to late join to another split point if none of its slaves has
// already finished.
Expand Down Expand Up @@ -1618,8 +1618,8 @@ void Thread::idle_loop() {
sp = bestSp;

// Recheck the conditions under lock protection
Threads.spinlock.acquire();
sp->spinlock.acquire();
Threads.mutex.lock();
sp->mutex.lock();

if ( sp->allSlavesSearching
&& sp->slavesMask.count() < MAX_SLAVES_PER_SPLITPOINT
Expand All @@ -1630,8 +1630,8 @@ void Thread::idle_loop() {
searching = true;
}

sp->spinlock.release();
Threads.spinlock.release();
sp->mutex.unlock();
Threads.mutex.unlock();
}
}

Expand Down Expand Up @@ -1687,7 +1687,7 @@ void check_time() {

else if (Limits.nodes)
{
Threads.spinlock.acquire();
Threads.mutex.lock();

int64_t nodes = RootPos.nodes_searched();

Expand All @@ -1698,18 +1698,18 @@ void check_time() {
{
SplitPoint& sp = th->splitPoints[i];

sp.spinlock.acquire();
sp.mutex.lock();

nodes += sp.nodes;

for (size_t idx = 0; idx < Threads.size(); ++idx)
if (sp.slavesMask.test(idx) && Threads[idx]->activePosition)
nodes += Threads[idx]->activePosition->nodes_searched();

sp.spinlock.release();
sp.mutex.unlock();
}

Threads.spinlock.release();
Threads.mutex.unlock();

if (nodes >= Limits.nodes)
Signals.stop = true;
Expand Down
16 changes: 8 additions & 8 deletions src/thread.cpp
Expand Up @@ -164,8 +164,8 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes
// Try to allocate available threads and ask them to start searching setting
// 'searching' flag. This must be done under lock protection to avoid concurrent
// allocation of the same slave by another master.
Threads.spinlock.acquire();
sp.spinlock.acquire();
Threads.mutex.lock();
sp.mutex.lock();

sp.allSlavesSearching = true; // Must be set under lock protection
++splitPointsSize;
Expand All @@ -187,8 +187,8 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes
// it will instantly launch a search, because its 'searching' flag is set.
// The thread will return from the idle loop when all slaves have finished
// their work at this split point.
sp.spinlock.release();
Threads.spinlock.release();
sp.mutex.unlock();
Threads.mutex.unlock();

Thread::idle_loop(); // Force a call to base class idle_loop()

Expand All @@ -201,8 +201,8 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes
// We have returned from the idle loop, which means that all threads are
// finished. Note that setting 'searching' and decreasing splitPointsSize must
// be done under lock protection to avoid a race with Thread::available_to().
Threads.spinlock.acquire();
sp.spinlock.acquire();
Threads.mutex.lock();
sp.mutex.lock();

searching = true;
--splitPointsSize;
Expand All @@ -212,8 +212,8 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes
*bestMove = sp.bestMove;
*bestValue = sp.bestValue;

sp.spinlock.release();
Threads.spinlock.release();
sp.mutex.unlock();
Threads.mutex.unlock();
}


Expand Down
16 changes: 2 additions & 14 deletions src/thread.h
Expand Up @@ -41,18 +41,6 @@ const size_t MAX_SPLITPOINTS_PER_THREAD = 8;
const size_t MAX_SLAVES_PER_SPLITPOINT = 4;


/// Spinlock class wraps low level atomic operations to provide a spin lock

class Spinlock {

Mutex m; // WARNING: Diasabled spinlocks to test on fishtest

public:
void acquire() { m.lock(); }
void release() { m.unlock(); }
};


/// SplitPoint struct stores information shared by the threads searching in
/// parallel below the same split point. It is populated at splitting time.

Expand All @@ -72,7 +60,7 @@ struct SplitPoint {
SplitPoint* parentSplitPoint;

// Shared variable data
Spinlock spinlock;
Mutex mutex;
std::bitset<MAX_THREADS> slavesMask;
volatile bool allSlavesSearching;
volatile uint64_t nodes;
Expand Down Expand Up @@ -163,7 +151,7 @@ struct ThreadPool : public std::vector<Thread*> {
void start_thinking(const Position&, const Search::LimitsType&, Search::StateStackPtr&);

Depth minimumSplitDepth;
Spinlock spinlock;
Mutex mutex;
ConditionVariable sleepCondition;
TimerThread* timer;
};
Expand Down

0 comments on commit 4b59347

Please sign in to comment.