<div dir="ltr">ouch! <div>Will it make sense to add a tsan bot to the sanitizer bot where we currently run asan, ubsan, and msan, but not tsan? </div><div>If yes, which tests to run? (if not all of "check-llvm")?</div><div><br></div><div>--kcc </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 6, 2016 at 4:46 PM, Justin Lebar via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jlebar<br>
Date: Wed Apr  6 18:46:40 2016<br>
New Revision: 265618<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=265618&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=265618&view=rev</a><br>
Log:<br>
Fix a race condition in support library ThreadPool.<br>
<br>
By running TSAN on the ThreadPool unit tests it was discovered that the<br>
threads in the pool can pop tasks off the queue at the same time the<br>
"wait" routine is trying to check if the task queue is empty. This patch<br>
fixes this problem by checking for active threads in the waiter before<br>
checking whether the queue is empty.<br>
<br>
Patch by Jason Henline.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D18811" rel="noreferrer" target="_blank">http://reviews.llvm.org/D18811</a><br>
<br>
Reviewers: joker.eph, jlebar<br>
<br>
Modified:<br>
    llvm/trunk/lib/Support/ThreadPool.cpp<br>
<br>
Modified: llvm/trunk/lib/Support/ThreadPool.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ThreadPool.cpp?rev=265618&r1=265617&r2=265618&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ThreadPool.cpp?rev=265618&r1=265617&r2=265618&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/ThreadPool.cpp (original)<br>
+++ llvm/trunk/lib/Support/ThreadPool.cpp Wed Apr  6 18:46:40 2016<br>
@@ -75,8 +75,11 @@ ThreadPool::ThreadPool(unsigned ThreadCo<br>
 void ThreadPool::wait() {<br>
   // Wait for all threads to complete and the queue to be empty<br>
   std::unique_lock<std::mutex> LockGuard(CompletionLock);<br>
+  // The order of the checks for ActiveThreads and Tasks.empty() matters because<br>
+  // any active threads might be modifying the Tasks queue, and this would be a<br>
+  // race.<br>
   CompletionCondition.wait(LockGuard,<br>
-                           [&] { return Tasks.empty() && !ActiveThreads; });<br>
+                           [&] { return !ActiveThreads && Tasks.empty(); });<br>
 }<br>
<br>
 std::shared_future<ThreadPool::VoidTy> ThreadPool::asyncImpl(TaskTy Task) {<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>