summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/ThreadPool.cpp
diff options
context:
space:
mode:
authorJustin Lebar <jlebar@google.com>2016-04-06 23:46:40 +0000
committerJustin Lebar <jlebar@google.com>2016-04-06 23:46:40 +0000
commit9e479e4763df7801a7da3209f69dcb4875645552 (patch)
tree784cf2a65ef7fd5358d64e8ac1d67e78c2e64e5c /llvm/lib/Support/ThreadPool.cpp
parentdd11ee7452beae10875e7690ea5dccda0ee52444 (diff)
downloadbcm5719-llvm-9e479e4763df7801a7da3209f69dcb4875645552.tar.gz
bcm5719-llvm-9e479e4763df7801a7da3209f69dcb4875645552.zip
Fix a race condition in support library ThreadPool.
By running TSAN on the ThreadPool unit tests it was discovered that the threads in the pool can pop tasks off the queue at the same time the "wait" routine is trying to check if the task queue is empty. This patch fixes this problem by checking for active threads in the waiter before checking whether the queue is empty. Patch by Jason Henline. Differential Revision: http://reviews.llvm.org/D18811 Reviewers: joker.eph, jlebar llvm-svn: 265618
Diffstat (limited to 'llvm/lib/Support/ThreadPool.cpp')
-rw-r--r--llvm/lib/Support/ThreadPool.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/llvm/lib/Support/ThreadPool.cpp b/llvm/lib/Support/ThreadPool.cpp
index d4dcb2ee96d..db03a4d6240 100644
--- a/llvm/lib/Support/ThreadPool.cpp
+++ b/llvm/lib/Support/ThreadPool.cpp
@@ -75,8 +75,11 @@ ThreadPool::ThreadPool(unsigned ThreadCount)
void ThreadPool::wait() {
// Wait for all threads to complete and the queue to be empty
std::unique_lock<std::mutex> LockGuard(CompletionLock);
+ // The order of the checks for ActiveThreads and Tasks.empty() matters because
+ // any active threads might be modifying the Tasks queue, and this would be a
+ // race.
CompletionCondition.wait(LockGuard,
- [&] { return Tasks.empty() && !ActiveThreads; });
+ [&] { return !ActiveThreads && Tasks.empty(); });
}
std::shared_future<ThreadPool::VoidTy> ThreadPool::asyncImpl(TaskTy Task) {
OpenPOWER on IntegriCloud