diff options
author | Mehdi Amini <mehdi.amini@apple.com> | 2015-12-19 05:12:07 +0000 |
---|---|---|
committer | Mehdi Amini <mehdi.amini@apple.com> | 2015-12-19 05:12:07 +0000 |
commit | 0129fca17f50f3345d8dc094fc81275d36f5043f (patch) | |
tree | 1907394d085268b4b7a3451e90332b75ada4e56d | |
parent | 550e9c80a604d6ecc0b60f2f9832d7e95765cb72 (diff) | |
download | bcm5719-llvm-0129fca17f50f3345d8dc094fc81275d36f5043f.tar.gz bcm5719-llvm-0129fca17f50f3345d8dc094fc81275d36f5043f.zip |
ThreadPool unittest: reimplement concurrency test, deterministically this time.
Follow-up to r256056.
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 256087
-rw-r--r-- | llvm/unittests/Support/ThreadPool.cpp | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/llvm/unittests/Support/ThreadPool.cpp b/llvm/unittests/Support/ThreadPool.cpp index b0e33c10876..ca55237d491 100644 --- a/llvm/unittests/Support/ThreadPool.cpp +++ b/llvm/unittests/Support/ThreadPool.cpp @@ -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); } |