Fix a possible infinite loop

In the case where we have 2 cores, we would spawn only one thread in
the thread pool. If that thread got to try to steal() from another
thread before the main thread was adopted, it would end-up always
trying to steal from itself and enter an infinite loop.

This seems to happen during windows builds.
This commit is contained in:
Pixelflinger
2019-07-19 00:20:01 -07:00
committed by Mathias Agopian
parent 90792e7032
commit 261dafa924

View File

@@ -243,13 +243,17 @@ inline JobSystem::ThreadState* JobSystem::getStateToStealFrom(JobSystem::ThreadS
uint16_t const threadCount = mThreadCount + adopted;
JobSystem::ThreadState* stateToStealFrom = nullptr;
do {
// this is biased, but frankly, we don't care. it's fast.
uint16_t index = uint16_t(state.rndGen() % threadCount);
assert(index < threadStates.size());
stateToStealFrom = &threadStates[index];
// don't steal from our own queue
} while (stateToStealFrom == &state);
// don't try to steal from someone else if we're the only thread (infinite loop)
if (threadCount >= 2) {
do {
// this is biased, but frankly, we don't care. it's fast.
uint16_t index = uint16_t(state.rndGen() % threadCount);
assert(index < threadStates.size());
stateToStealFrom = &threadStates[index];
// don't steal from our own queue
} while (stateToStealFrom == &state);
}
return stateToStealFrom;
}
@@ -258,7 +262,9 @@ JobSystem::Job* JobSystem::steal(JobSystem::ThreadState& state) noexcept {
Job* job = nullptr;
do {
ThreadState* const stateToStealFrom = getStateToStealFrom(state);
job = steal(stateToStealFrom->workQueue);
if (UTILS_LIKELY(stateToStealFrom)) {
job = steal(stateToStealFrom->workQueue);
}
// nullptr -> nothing to steal in that queue either, if there are active jobs,
// continue to try stealing one.
} while (!job && hasActiveJobs());