And update master->splitPointsCnt under lock
protection. Not stricly necessary because
single_bit() condition takes care of false
positives anyhow, but it is a bit tricky and
moving under lock is the most natural thing
to do to avoid races with "reparenting".
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
// Try to reparent to another split point. Only for slave threads
// that are not master of any active split point.
// Try to reparent to another split point. Only for slave threads
// that are not master of any active split point.
- if ( !sp_master
- && !is_searching
- && !do_sleep
- && !do_exit
- && !splitPointsCnt
- && Threads.size() > 2)
- {
for (int i = 0; i < Threads.size(); i++)
{
for (int i = 0; i < Threads.size(); i++)
{
- SplitPoint* oldest = &Threads[i].splitPoints[0];
-
- // Find the first oldest split point with still all slaves running
- if ( Threads[i].splitPointsCnt
- && oldest->slavesMask == oldest->allSlavesMask
+ Thread* th = &Threads[i];
+ SplitPoint* oldest = &th->splitPoints[0];
+
+ // Find the first split point with still all slaves running
+ // where we are available as a possible slave.
+ if ( !is_searching
+ && th->splitPointsCnt
+ && !oldest->cutoff
+ && oldest->slavesMask == oldest->allSlavesMask
&& !single_bit(oldest->allSlavesMask))
{
lock_grab(oldest->lock);
&& !single_bit(oldest->allSlavesMask))
{
lock_grab(oldest->lock);
- lock_grab(Threads.splitLock); // Needed by is_searching
+ lock_grab(Threads.splitLock);
// Retest all under lock protection, we are in the middle
// Retest all under lock protection, we are in the middle
+ // of a race storm here !
- && !do_sleep
- && !do_exit
- && Threads[i].splitPointsCnt
- && oldest->slavesMask == oldest->allSlavesMask
+ && th->splitPointsCnt
+ && !oldest->cutoff
+ && oldest->slavesMask == oldest->allSlavesMask
&& !single_bit(oldest->allSlavesMask))
{
oldest->slavesMask |= 1ULL << idx; // allSlavesMask is not updated
&& !single_bit(oldest->allSlavesMask))
{
oldest->slavesMask |= 1ULL << idx; // allSlavesMask is not updated
break; // Exit anyhow, only one try (enough in 99% of cases)
}
}
break; // Exit anyhow, only one try (enough in 99% of cases)
}
}
return bestValue;
// Pick the next available split point from the split point stack
return bestValue;
// Pick the next available split point from the split point stack
- SplitPoint* sp = &master->splitPoints[master->splitPointsCnt++];
+ SplitPoint* sp = &master->splitPoints[master->splitPointsCnt];
sp->parent = master->curSplitPoint;
sp->master = master;
sp->parent = master->curSplitPoint;
sp->master = master;
+ master->splitPointsCnt++;
+
lock_release(splitLock);
lock_release(sp->lock);
lock_release(splitLock);
lock_release(sp->lock);