mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
Do not return from idle_loop() with lock held
Master thread returns from idle_loop() when sp->cpus == 0, but cpus is decremented by slave threads under sp->lock, so it could happen that we return in split(), where we release the split point, with sp->lock still held. This patch guarantees that sp->lock is released when returning to split(). Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
b89733b46c
commit
f16c231bc9
1 changed files with 11 additions and 6 deletions
|
@ -82,7 +82,7 @@ namespace {
|
||||||
bool thread_should_stop(int threadID) const;
|
bool thread_should_stop(int threadID) const;
|
||||||
void wake_sleeping_threads();
|
void wake_sleeping_threads();
|
||||||
void put_threads_to_sleep();
|
void put_threads_to_sleep();
|
||||||
void idle_loop(int threadID, SplitPoint* waitSp);
|
void idle_loop(int threadID, SplitPoint* sp);
|
||||||
bool split(const Position& pos, SearchStack* ss, int ply, Value* alpha, const Value beta, Value* bestValue,
|
bool split(const Position& pos, SearchStack* ss, int ply, Value* alpha, const Value beta, Value* bestValue,
|
||||||
Depth depth, bool mateThreat, int* moves, MovePicker* mp, int master, bool pvNode);
|
Depth depth, bool mateThreat, int* moves, MovePicker* mp, int master, bool pvNode);
|
||||||
|
|
||||||
|
@ -2636,10 +2636,10 @@ namespace {
|
||||||
|
|
||||||
|
|
||||||
// idle_loop() is where the threads are parked when they have no work to do.
|
// idle_loop() is where the threads are parked when they have no work to do.
|
||||||
// The parameter "waitSp", if non-NULL, is a pointer to an active SplitPoint
|
// The parameter 'sp', if non-NULL, is a pointer to an active SplitPoint
|
||||||
// object for which the current thread is the master.
|
// object for which the current thread is the master.
|
||||||
|
|
||||||
void ThreadsManager::idle_loop(int threadID, SplitPoint* waitSp) {
|
void ThreadsManager::idle_loop(int threadID, SplitPoint* sp) {
|
||||||
|
|
||||||
assert(threadID >= 0 && threadID < MAX_THREADS);
|
assert(threadID >= 0 && threadID < MAX_THREADS);
|
||||||
|
|
||||||
|
@ -2649,7 +2649,7 @@ namespace {
|
||||||
// master should exit as last one.
|
// master should exit as last one.
|
||||||
if (AllThreadsShouldExit)
|
if (AllThreadsShouldExit)
|
||||||
{
|
{
|
||||||
assert(!waitSp);
|
assert(!sp);
|
||||||
threads[threadID].state = THREAD_TERMINATED;
|
threads[threadID].state = THREAD_TERMINATED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2658,7 +2658,7 @@ namespace {
|
||||||
// instead of wasting CPU time polling for work.
|
// instead of wasting CPU time polling for work.
|
||||||
while (AllThreadsShouldSleep || threadID >= ActiveThreads)
|
while (AllThreadsShouldSleep || threadID >= ActiveThreads)
|
||||||
{
|
{
|
||||||
assert(!waitSp);
|
assert(!sp);
|
||||||
assert(threadID != 0);
|
assert(threadID != 0);
|
||||||
threads[threadID].state = THREAD_SLEEPING;
|
threads[threadID].state = THREAD_SLEEPING;
|
||||||
|
|
||||||
|
@ -2695,8 +2695,13 @@ namespace {
|
||||||
|
|
||||||
// If this thread is the master of a split point and all threads have
|
// If this thread is the master of a split point and all threads have
|
||||||
// finished their work at this split point, return from the idle loop.
|
// finished their work at this split point, return from the idle loop.
|
||||||
if (waitSp != NULL && waitSp->cpus == 0)
|
if (sp && sp->cpus == 0)
|
||||||
{
|
{
|
||||||
|
// Because sp->cpus is decremented under lock protection,
|
||||||
|
// be sure sp->lock has been released before to proceed.
|
||||||
|
lock_grab(&(sp->lock));
|
||||||
|
lock_release(&(sp->lock));
|
||||||
|
|
||||||
assert(threads[threadID].state == THREAD_AVAILABLE);
|
assert(threads[threadID].state == THREAD_AVAILABLE);
|
||||||
|
|
||||||
threads[threadID].state = THREAD_SEARCHING;
|
threads[threadID].state = THREAD_SEARCHING;
|
||||||
|
|
Loading…
Add table
Reference in a new issue