blob: 5fb14537568233bff964cf65d8e95aa0c0b5c972 [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;
21using namespace std::chrono;
22
23/// Try best to make this thread not progress faster than the main thread
24static void yield() {
25#ifdef LLVM_ENABLE_THREADS
26 std::this_thread::yield();
27#endif
28 std::this_thread::sleep_for(milliseconds(200));
29#ifdef LLVM_ENABLE_THREADS
30 std::this_thread::yield();
31#endif
32}
33
Mehdi Amini942e52c2015-12-15 09:10:25 +000034// Fixture for the unittests, allowing to *temporarily* disable the unittests
35// on a particular platform
36class ThreadPoolTest : public testing::Test {
37 Triple Host;
38 SmallVector<Triple::ArchType, 4> UnsupportedArchs;
39 SmallVector<Triple::OSType, 4> UnsupportedOSs;
40 SmallVector<Triple::EnvironmentType, 1> UnsupportedEnvironments;
41protected:
42 // This is intended for platform as a temporary "XFAIL"
43 bool isUnsupportedOSOrEnvironment() {
44 Triple Host(Triple::normalize(sys::getProcessTriple()));
45
46 if (std::find(UnsupportedEnvironments.begin(), UnsupportedEnvironments.end(),
47 Host.getEnvironment()) != UnsupportedEnvironments.end())
48 return true;
49
50 if (std::find(UnsupportedOSs.begin(), UnsupportedOSs.end(), Host.getOS())
51 != UnsupportedOSs.end())
52 return true;
53
54 if (std::find(UnsupportedArchs.begin(), UnsupportedArchs.end(), Host.getArch())
55 != UnsupportedArchs.end())
56 return true;
57
58 return false;
59 }
60
61 ThreadPoolTest() {
62 // Add unsupported configuration here, example:
63 // UnsupportedArchs.push_back(Triple::x86_64);
Mehdi Amini4b8d75b2015-12-15 09:10:28 +000064
65 // See https://llvm.org/bugs/show_bug.cgi?id=25829
66 UnsupportedArchs.push_back(Triple::ppc64le);
67 UnsupportedArchs.push_back(Triple::ppc64);
Mehdi Amini942e52c2015-12-15 09:10:25 +000068 }
69};
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
83 ThreadPool Pool;
84 for (size_t i = 0; i < 5; ++i) {
85 Pool.async([&checked_in, i] {
86 yield();
87 ++checked_in;
88 });
89 }
90 ASSERT_EQ(0, checked_in);
91 Pool.wait();
92 ASSERT_EQ(5, checked_in);
93}
94
Teresa Johnsonf064d622015-12-15 04:44:02 +000095static void TestFunc(std::atomic_int &checked_in, int i) { checked_in += i; }
96
Mehdi Amini942e52c2015-12-15 09:10:25 +000097TEST_F(ThreadPoolTest, AsyncBarrierArgs) {
98 CHECK_UNSUPPORTED();
Teresa Johnsonf064d622015-12-15 04:44:02 +000099 // Test that async works with a function requiring multiple parameters.
100 std::atomic_int checked_in{0};
101
102 ThreadPool Pool;
103 for (size_t i = 0; i < 5; ++i) {
104 Pool.async(TestFunc, std::ref(checked_in), i);
105 }
106 Pool.wait();
107 ASSERT_EQ(10, checked_in);
108}
109
Mehdi Amini942e52c2015-12-15 09:10:25 +0000110TEST_F(ThreadPoolTest, Async) {
111 CHECK_UNSUPPORTED();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000112 ThreadPool Pool;
113 std::atomic_int i{0};
114 // sleep here just to ensure that the not-equal is correct.
115 Pool.async([&i] {
116 yield();
117 ++i;
118 });
119 Pool.async([&i] { ++i; });
120 ASSERT_NE(2, i.load());
121 Pool.wait();
122 ASSERT_EQ(2, i.load());
123}
124
Mehdi Amini942e52c2015-12-15 09:10:25 +0000125TEST_F(ThreadPoolTest, GetFuture) {
126 CHECK_UNSUPPORTED();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000127 ThreadPool Pool;
128 std::atomic_int i{0};
129 // sleep here just to ensure that the not-equal is correct.
130 Pool.async([&i] {
131 yield();
132 ++i;
133 });
134 // Force the future using get()
135 Pool.async([&i] { ++i; }).get();
136 ASSERT_NE(2, i.load());
137 Pool.wait();
138 ASSERT_EQ(2, i.load());
139}
140
Mehdi Amini942e52c2015-12-15 09:10:25 +0000141TEST_F(ThreadPoolTest, PoolDestruction) {
142 CHECK_UNSUPPORTED();
Mehdi Amini33a7ea42015-12-15 00:59:19 +0000143 // Test that we are waiting on destruction
144 std::atomic_int checked_in{0};
145
146 {
147 ThreadPool Pool;
148 for (size_t i = 0; i < 5; ++i) {
149 Pool.async([&checked_in, i] {
150 yield();
151 ++checked_in;
152 });
153 }
154 ASSERT_EQ(0, checked_in);
155 }
156 ASSERT_EQ(5, checked_in);
157}