summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2015-12-19 05:12:07 +0000
committerMehdi Amini <mehdi.amini@apple.com>2015-12-19 05:12:07 +0000
commitbf9cc1bd9344ccc86e1f8173811c5d37edca8cdb (patch)
tree4eac7880aabd079c3335e2e234f6ce85a9af2fc5
parent62663ee66ebb56c586e55b7342546f3bd74c279f (diff)
ThreadPool unittest: reimplement concurrency test, deterministically this time.
Follow-up to r256056. From: Mehdi Amini <mehdi.amini@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256087 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--unittests/Support/ThreadPool.cpp41
1 files changed, 36 insertions, 5 deletions
diff --git a/unittests/Support/ThreadPool.cpp b/unittests/Support/ThreadPool.cpp
index b0e33c10876..ca55237d491 100644
--- a/unittests/Support/ThreadPool.cpp
+++ b/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);
}