[PATCH] D18811: Fix a race condition in support library ThreadPool

Mehdi AMINI via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 6 14:47:42 PDT 2016


joker.eph added a comment.

One lock is simpler to understand, however it adds unnecessary contention, which is what I was trying to avoid originally.


================
Comment at: include/llvm/Support/ThreadPool.h:130
@@ -131,3 +129,3 @@
   /// Signal for the destruction of the pool, asking thread to exit.
-  bool EnableFlag;
+  bool InDestructorFlag;
 #endif
----------------
Is this related to the changes here? If not then split it out to a separate NFC patch, reducing the change in this patch to the bug it is actually fixing. Same for renaming `QueueCondition ` to `SubmissionCondition`.

================
Comment at: lib/Support/ThreadPool.cpp:79
@@ -78,3 +70,3 @@
   CompletionCondition.wait(LockGuard,
                            [&] { return Tasks.empty() && !ActiveThreads; });
 }
----------------
Would just reversing the check solve the race?

```
 [&] { return !ActiveThreads && Tasks.empty(); });
```

If not can you elaborate a little?


================
Comment at: lib/Support/ThreadPool.cpp:83-84
@@ -90,3 +82,4 @@
     // Don't allow enqueueing after disabling the pool
-    assert(EnableFlag && "Queuing a thread during ThreadPool destruction");
+    assert(!InDestructorFlag &&
+           "Queuing a thread during ThreadPool destruction");
 
----------------
I agree with jlebar that this scenario is sketchy:

```
{ 
  ThreadPool Pool;
  Pool.async([&] () {
     if (random()) Pool.async(doSomething);
  });
}
```

Technically it means that the client has to insert an explicit wait if a task can enqueue:

```
{ 
  ThreadPool Pool;
  Pool.async([&] () {
     if (random()) Pool.async(doSomething);
  });
  Pool.wait();
}
```

Synchronizing on a future inside a task would have the same kind of issue as well. 


http://reviews.llvm.org/D18811





More information about the llvm-commits mailing list