assert(!this_sp || (this_sp->masterThread == this && searching));
- // 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.
- while (!this_sp || this_sp->slavesMask)
+ while (true)
{
- if (this_sp)
- this_sp->mutex.unlock();
-
// If we are not searching, wait for a condition to be signaled instead of
// wasting CPU time polling for work.
while ((!searching && Threads.sleepWhileIdle) || exit)
sp->mutex.unlock();
}
- if(this_sp)
+ // 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)
+ {
this_sp->mutex.lock();
+ bool finished = !this_sp->slavesMask; // Retest under lock protection
+ this_sp->mutex.unlock();
+ if (finished)
+ return;
+ }
}
}
sp.mutex.unlock();
Threads.mutex.unlock();
- // Calling idle_loop with sp.mutex locked
Thread::idle_loop(); // Force a call to base class idle_loop()
// In helpful master concept a master can help only a sub-tree of its split
// We have returned from the idle loop, which means that all threads are
// finished. Note that setting 'searching' and decreasing splitPointsSize is
// done under lock protection to avoid a race with Thread::is_available_to().
- // idle_loop returns with sp.mutex locked but we must unlock it inorder to
- // lock Threads.mutex without conflicting with check_time() (threads holding
- // multiple locks must always acquired them in the same order to avoid deadlocks)
- sp.mutex.unlock();
Threads.mutex.lock();
sp.mutex.lock();
}