[unittests] ThreadPool: Remove redundant loop, NFC
[oota-llvm.git] / unittests / Support / ThreadPool.cpp
index 118884134ea65da81bc35b7641af1e21a797dec9..b0307d1f16a4eb145e6697d99b26cb2a7dfc01ce 100644 (file)
 #include "gtest/gtest.h"
 
 using namespace llvm;
-using namespace std::chrono;
-
-/// Try best to make this thread not progress faster than the main thread
-static void yield() {
-#ifdef LLVM_ENABLE_THREADS
-  std::this_thread::yield();
-#endif
-  std::this_thread::sleep_for(milliseconds(200));
-#ifdef LLVM_ENABLE_THREADS
-  std::this_thread::yield();
-#endif
-}
 
 // Fixture for the unittests, allowing to *temporarily* disable the unittests
 // on a particular platform
@@ -61,7 +49,29 @@ protected:
   ThreadPoolTest() {
     // Add unsupported configuration here, example:
     //   UnsupportedArchs.push_back(Triple::x86_64);
+
+    // See https://llvm.org/bugs/show_bug.cgi?id=25829
+    UnsupportedArchs.push_back(Triple::ppc64le);
+    UnsupportedArchs.push_back(Triple::ppc64);
   }
+
+  /// Make sure this thread not progress faster than the main thread.
+  void waitForMainThread() {
+    std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
+    WaitMainThread.wait(LockGuard, [&] { return MainThreadReady; });
+  }
+
+  /// Set the readiness of the main thread.
+  void setMainThreadReadyState(bool Ready) {
+    std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
+    MainThreadReady = Ready;
+    WaitMainThread.notify_all();
+  }
+
+  std::condition_variable WaitMainThread;
+  std::mutex WaitMainThreadMutex;
+  bool MainThreadReady;
+
 };
 
 #define CHECK_UNSUPPORTED() \
@@ -76,14 +86,16 @@ TEST_F(ThreadPoolTest, AsyncBarrier) {
 
   std::atomic_int checked_in{0};
 
+  setMainThreadReadyState(false);
   ThreadPool Pool;
   for (size_t i = 0; i < 5; ++i) {
-    Pool.async([&checked_in, i] {
-      yield();
+    Pool.async([this, &checked_in, i] {
+      waitForMainThread();
       ++checked_in;
     });
   }
   ASSERT_EQ(0, checked_in);
+  setMainThreadReadyState(true);
   Pool.wait();
   ASSERT_EQ(5, checked_in);
 }
@@ -107,13 +119,14 @@ TEST_F(ThreadPoolTest, Async) {
   CHECK_UNSUPPORTED();
   ThreadPool Pool;
   std::atomic_int i{0};
-  // sleep here just to ensure that the not-equal is correct.
-  Pool.async([&i] {
-    yield();
+  setMainThreadReadyState(false);
+  Pool.async([this, &i] {
+    waitForMainThread();
     ++i;
   });
   Pool.async([&i] { ++i; });
   ASSERT_NE(2, i.load());
+  setMainThreadReadyState(true);
   Pool.wait();
   ASSERT_EQ(2, i.load());
 }
@@ -122,14 +135,15 @@ TEST_F(ThreadPoolTest, GetFuture) {
   CHECK_UNSUPPORTED();
   ThreadPool Pool;
   std::atomic_int i{0};
-  // sleep here just to ensure that the not-equal is correct.
-  Pool.async([&i] {
-    yield();
+  setMainThreadReadyState(false);
+  Pool.async([this, &i] {
+    waitForMainThread();
     ++i;
   });
   // Force the future using get()
   Pool.async([&i] { ++i; }).get();
   ASSERT_NE(2, i.load());
+  setMainThreadReadyState(true);
   Pool.wait();
   ASSERT_EQ(2, i.load());
 }
@@ -138,16 +152,17 @@ TEST_F(ThreadPoolTest, PoolDestruction) {
   CHECK_UNSUPPORTED();
   // Test that we are waiting on destruction
   std::atomic_int checked_in{0};
-
   {
+    setMainThreadReadyState(false);
     ThreadPool Pool;
     for (size_t i = 0; i < 5; ++i) {
-      Pool.async([&checked_in, i] {
-        yield();
+      Pool.async([this, &checked_in, i] {
+        waitForMainThread();
         ++checked_in;
       });
     }
     ASSERT_EQ(0, checked_in);
+    setMainThreadReadyState(true);
   }
   ASSERT_EQ(5, checked_in);
 }