fix a race in jobsystem (2nd attempt)

We were decrementing activeJobCount after removing the job from the
queue, which could cause other threads in the pool to preempt us before
the decrement, causing them to spin forever trying to get a non-existant
job, until the decrement actually happened.

Now we always decrement first and fix-up the count if we couldn't get
a job from the queues. The race is inverted, and doesn't cause threads
to spin a long time.


fixes b/201100123
This commit is contained in:
Mathias Agopian
2021-09-13 14:20:08 -07:00
committed by Mathias Agopian
parent 6e7af103d3
commit 19b0ad2605
2 changed files with 64 additions and 33 deletions

View File

@@ -350,24 +350,9 @@ private:
Job* steal(JobSystem::ThreadState& state) noexcept;
void finish(Job* job) noexcept;
void put(WorkQueue& workQueue, Job* job) noexcept {
assert(job);
size_t index = job - mJobStorageBase;
assert(index >= 0 && index < MAX_JOB_COUNT);
workQueue.push(uint16_t(index + 1));
}
Job* pop(WorkQueue& workQueue) noexcept {
size_t index = workQueue.pop();
assert(index <= MAX_JOB_COUNT);
return !index ? nullptr : &mJobStorageBase[index - 1];
}
Job* steal(WorkQueue& workQueue) noexcept {
size_t index = workQueue.steal();
assert(index <= MAX_JOB_COUNT);
return !index ? nullptr : &mJobStorageBase[index - 1];
}
void put(WorkQueue& workQueue, Job* job) noexcept;
Job* pop(WorkQueue& workQueue) noexcept;
Job* steal(WorkQueue& workQueue) noexcept;
void wait(std::unique_lock<Mutex>& lock, Job* job = nullptr) noexcept;
void wakeAll() noexcept;