[llvm] r256087 - ThreadPool unittest: reimplement concurrency test, deterministically this time.

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 18 21:12:08 PST 2015


Author: mehdi_amini
Date: Fri Dec 18 23:12:07 2015
New Revision: 256087

URL: http://llvm.org/viewvc/llvm-project?rev=256087&view=rev
Log:
ThreadPool unittest: reimplement concurrency test, deterministically this time.

Follow-up to r256056.

From: Mehdi Amini <mehdi.amini at apple.com>

Modified:
    llvm/trunk/unittests/Support/ThreadPool.cpp

Modified: llvm/trunk/unittests/Support/ThreadPool.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ThreadPool.cpp?rev=256087&r1=256086&r2=256087&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/ThreadPool.cpp (original)
+++ llvm/trunk/unittests/Support/ThreadPool.cpp Fri Dec 18 23:12:07 2015
@@ -54,6 +54,18 @@ protected:
     UnsupportedArchs.push_back(Triple::ppc64le);
     UnsupportedArchs.push_back(Triple::ppc64);
   }
+
+  /// Make sure this thread not progress faster than the main thread.
+  void waitForMainThread() {
+    while (!MainThreadReady) {
+      std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
+      WaitMainThread.wait(LockGuard, [&] { return MainThreadReady; });
+    }
+  }
+  std::condition_variable WaitMainThread;
+  std::mutex WaitMainThreadMutex;
+  bool MainThreadReady;
+
 };
 
 #define CHECK_UNSUPPORTED() \
@@ -68,12 +80,17 @@ TEST_F(ThreadPoolTest, AsyncBarrier) {
 
   std::atomic_int checked_in{0};
 
+  MainThreadReady = false;
   ThreadPool Pool;
   for (size_t i = 0; i < 5; ++i) {
-    Pool.async([&checked_in, i] {
+    Pool.async([this, &checked_in, i] {
+      waitForMainThread();
       ++checked_in;
     });
   }
+  ASSERT_EQ(0, checked_in);
+  MainThreadReady = true;
+  WaitMainThread.notify_all();
   Pool.wait();
   ASSERT_EQ(5, checked_in);
 }
@@ -97,10 +114,15 @@ TEST_F(ThreadPoolTest, Async) {
   CHECK_UNSUPPORTED();
   ThreadPool Pool;
   std::atomic_int i{0};
-  Pool.async([&i] {
+  MainThreadReady = false;
+  Pool.async([this, &i] {
+    waitForMainThread();
     ++i;
   });
   Pool.async([&i] { ++i; });
+  ASSERT_NE(2, i.load());
+  MainThreadReady = true;
+  WaitMainThread.notify_all();
   Pool.wait();
   ASSERT_EQ(2, i.load());
 }
@@ -109,11 +131,16 @@ TEST_F(ThreadPoolTest, GetFuture) {
   CHECK_UNSUPPORTED();
   ThreadPool Pool;
   std::atomic_int i{0};
-  Pool.async([&i] {
+  MainThreadReady = false;
+  Pool.async([this, &i] {
+    waitForMainThread();
     ++i;
   });
   // Force the future using get()
   Pool.async([&i] { ++i; }).get();
+  ASSERT_NE(2, i.load());
+  MainThreadReady = true;
+  WaitMainThread.notify_all();
   Pool.wait();
   ASSERT_EQ(2, i.load());
 }
@@ -122,14 +149,18 @@ TEST_F(ThreadPoolTest, PoolDestruction)
   CHECK_UNSUPPORTED();
   // Test that we are waiting on destruction
   std::atomic_int checked_in{0};
-
   {
+    MainThreadReady = false;
     ThreadPool Pool;
     for (size_t i = 0; i < 5; ++i) {
-      Pool.async([&checked_in, i] {
+      Pool.async([this, &checked_in, i] {
+        waitForMainThread();
         ++checked_in;
       });
     }
+    ASSERT_EQ(0, checked_in);
+    MainThreadReady = true;
+    WaitMainThread.notify_all();
   }
   ASSERT_EQ(5, checked_in);
 }




More information about the llvm-commits mailing list