blob: ca55237d49102bcda5e61188262b5439b9564a7f [file] [log] [blame]
Mehdi Amini33a7ea42015-12-15 00:59:19 +00001//========- unittests/Support/ThreadPools.cpp - ThreadPools.h tests --========//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Support/ThreadPool.h"
11
12#include "llvm/ADT/STLExtras.h"
Mehdi Amini942e52c2015-12-15 09:10:25 +000013#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/Triple.h"
15#include "llvm/Support/Host.h"
16#include "llvm/Support/TargetSelect.h"
Mehdi Amini33a7ea42015-12-15 00:59:19 +000017
18#include "gtest/gtest.h"
19
20using namespace llvm;
Mehdi Amini33a7ea42015-12-15 00:59:19 +000021
Mehdi Amini942e52c2015-12-15 09:10:25 +000022// Fixture for the unittests, allowing to *temporarily* disable the unittests
23// on a particular platform
24class ThreadPoolTest : public testing::Test {
25 Triple Host;
26 SmallVector<Triple::ArchType, 4> UnsupportedArchs;
27 SmallVector<Triple::OSType, 4> UnsupportedOSs;
28 SmallVector<Triple::EnvironmentType, 1> UnsupportedEnvironments;
29protected:
30 // This is intended for platform as a temporary "XFAIL"
31 bool isUnsupportedOSOrEnvironment() {
32 Triple Host(Triple::normalize(sys::getProcessTriple()));
33
34 if (std::find(UnsupportedEnvironments.begin(), UnsupportedEnvironments.end(),
35 Host.getEnvironment()) != UnsupportedEnvironments.end())
36 return true;
37
38 if (std::find(UnsupportedOSs.begin(), UnsupportedOSs.end(), Host.getOS())
39 != UnsupportedOSs.end())
40 return true;
41
42 if (std::find(UnsupportedArchs.begin(), UnsupportedArchs.end(), Host.getArch())
43 != UnsupportedArchs.end())
44 return true;
45
46 return false;
47 }
48
49 ThreadPoolTest() {
50 // Add unsupported configuration here, example:
51 // UnsupportedArchs.push_back(Triple::x86_64);
Mehdi Amini4b8d75b2015-12-15 09:10:28 +000052
53 // See https://llvm.org/bugs/show_bug.cgi?id=25829
54 UnsupportedArchs.push_back(Triple::ppc64le);
55 UnsupportedArchs.push_back(Triple::ppc64);
Mehdi Amini942e52c2015-12-15 09:10:25 +000056 }
Mehdi Amini0129fca2015-12-19 05:12:07 +000057
58 /// Make sure this thread not progress faster than the main thread.
59 void waitForMainThread() {
60 while (!MainThreadReady) {
61 std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
62 WaitMainThread.wait(LockGuard, [&] { return MainThreadReady; });
63 }
64 }
65 std::condition_variable WaitMainThread;
66 std::mutex WaitMainThreadMutex;
67 bool MainThreadReady;
68
Mehdi Amini942e52c2015-12-15 09:10:25 +000069};
70
71#define CHECK_UNSUPPORTED() \
72 do { \
73 if (isUnsupportedOSOrEnvironment()) \
74 return; \
75 } while (0); \
76
77TEST_F(ThreadPoolTest, AsyncBarrier) {
78 CHECK_UNSUPPORTED();
Mehdi Amini33a7ea42015-12-15 00:59:19 +000079 // test that async & barrier work together properly.
80
81 std::atomic_int checked_in{0};
82
Mehdi Amini0129fca2015-12-19 05:12:07 +000083 MainThreadReady = false;
Mehdi Amini33a7ea42015-12-15 00:59:19 +000084 ThreadPool Pool;
85 for (size_t i = 0; i < 5; ++i) {
Mehdi Amini0129fca2015-12-19 05:12:07 +000086 Pool.async([this, &checked_in, i] {
87 waitForMainThread();
Mehdi Amini33a7ea42015-12-15 00:59:19 +000088 ++checked_in;
89 });
90 }
Mehdi Amini0129fca2015-12-19 05:12:07 +000091 ASSERT_EQ(0, checked_in);
92 MainThreadReady = true;
93 WaitMainThread.notify_all();
Mehdi Amini33a7ea42015-12-15 00:59:19 +000094 Pool.wait();
95 ASSERT_EQ(5, checked_in);
96}
97
Teresa Johnsonf064d622015-12-15 04:44:02 +000098static void TestFunc(std::atomic_int &checked_in, int i) { checked_in += i; }
99
Mehdi Amini942e52c2015-12-15 09:10:25 +0000100TEST_F(ThreadPoolTest, AsyncBarrierArgs) {
101 CHECK_UNSUPPORTED();
Teresa Johnsonf064d622015-12-15 04:44:02 +0000102 // Test that async works with a function requiring multiple parameters.
103 std::atomic_int checked_in{0};
104
105 ThreadPool Pool;
106 for (size_t i = 0; i < 5; ++i) {
107 Pool.async(TestFunc, std::ref(checked_in), i);
108 }
109 Pool.wait();
110 ASSERT_EQ(10, checked_in);
111}
112
Mehdi Amini942e52c2015-12-15 09:10:25 +0000113TEST_F(ThreadPoolTest, Async) {
114 CHECK_UNSUPPORTED();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000115 ThreadPool Pool;
116 std::atomic_int i{0};
Mehdi Amini0129fca2015-12-19 05:12:07 +0000117 MainThreadReady = false;
118 Pool.async([this, &i] {
119 waitForMainThread();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000120 ++i;
121 });
122 Pool.async([&i] { ++i; });
Mehdi Amini0129fca2015-12-19 05:12:07 +0000123 ASSERT_NE(2, i.load());
124 MainThreadReady = true;
125 WaitMainThread.notify_all();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000126 Pool.wait();
127 ASSERT_EQ(2, i.load());
128}
129
Mehdi Amini942e52c2015-12-15 09:10:25 +0000130TEST_F(ThreadPoolTest, GetFuture) {
131 CHECK_UNSUPPORTED();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000132 ThreadPool Pool;
133 std::atomic_int i{0};
Mehdi Amini0129fca2015-12-19 05:12:07 +0000134 MainThreadReady = false;
135 Pool.async([this, &i] {
136 waitForMainThread();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000137 ++i;
138 });
139 // Force the future using get()
140 Pool.async([&i] { ++i; }).get();
Mehdi Amini0129fca2015-12-19 05:12:07 +0000141 ASSERT_NE(2, i.load());
142 MainThreadReady = true;
143 WaitMainThread.notify_all();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000144 Pool.wait();
145 ASSERT_EQ(2, i.load());
146}
147
Mehdi Amini942e52c2015-12-15 09:10:25 +0000148TEST_F(ThreadPoolTest, PoolDestruction) {
149 CHECK_UNSUPPORTED();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000150 // Test that we are waiting on destruction
151 std::atomic_int checked_in{0};
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000152 {
Mehdi Amini0129fca2015-12-19 05:12:07 +0000153 MainThreadReady = false;
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000154 ThreadPool Pool;
155 for (size_t i = 0; i < 5; ++i) {
Mehdi Amini0129fca2015-12-19 05:12:07 +0000156 Pool.async([this, &checked_in, i] {
157 waitForMainThread();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000158 ++checked_in;
159 });
160 }
Mehdi Amini0129fca2015-12-19 05:12:07 +0000161 ASSERT_EQ(0, checked_in);
162 MainThreadReady = true;
163 WaitMainThread.notify_all();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000164 }
165 ASSERT_EQ(5, checked_in);
166}