X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fthread.cpp;h=007ed46e10c54bb85e12955f835b3ba6c8d79ede;hp=6ddbf3f2e85f82ee085cf82db5f46cf76657b78d;hb=e5da0e4b79b405da5bdc42f6fb4c2ba49afba00a;hpb=8725494966f91af42c77d2f81d2c8a7fe1864316 diff --git a/src/thread.cpp b/src/thread.cpp index 6ddbf3f2..007ed46e 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -144,6 +144,8 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes // Pick and init the next available split point SplitPoint& sp = splitPoints[splitPointsSize]; + sp.mutex.lock(); // No contention here until we don't increment splitPointsSize + sp.master = this; sp.parentSplitPoint = activeSplitPoint; sp.slavesMask = 0, sp.slavesMask.set(idx); @@ -160,26 +162,29 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes sp.nodes = 0; sp.cutoff = false; sp.ss = ss; - - // 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(); - sp.allSlavesSearching = true; // Must be set under lock protection + ++splitPointsSize; activeSplitPoint = &sp; activePosition = nullptr; + // Try to allocate available threads Thread* slave; while ( sp.slavesMask.count() < MAX_SLAVES_PER_SPLITPOINT - && (slave = Threads.available_slave(activeSplitPoint)) != nullptr) + && (slave = Threads.available_slave(&sp)) != nullptr) { - sp.slavesMask.set(slave->idx); - slave->activeSplitPoint = activeSplitPoint; - slave->searching = true; // Slave leaves idle_loop() + slave->allocMutex.lock(); + + if (slave->can_join(activeSplitPoint)) + { + activeSplitPoint->slavesMask.set(slave->idx); + slave->activeSplitPoint = activeSplitPoint; + slave->searching = true; + } + + slave->allocMutex.unlock(); + slave->notify_one(); // Could be sleeping } @@ -187,8 +192,7 @@ 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(); Thread::idle_loop(); // Force a call to base class idle_loop() @@ -198,13 +202,13 @@ void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bes assert(!searching); assert(!activePosition); + searching = true; + // 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(); + // finished. Note that decreasing splitPointsSize must be done under lock + // protection to avoid a race with Thread::can_join(). + sp.mutex.lock(); - searching = true; --splitPointsSize; activeSplitPoint = sp.parentSplitPoint; activePosition = &pos; @@ -212,8 +216,7 @@ 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(); }