118884134ea65da81bc35b7641af1e21a797dec9
[oota-llvm.git] / unittests / Support / ThreadPool.cpp
1 //========- 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"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/Triple.h"
15 #include "llvm/Support/Host.h"
16 #include "llvm/Support/TargetSelect.h"
17
18 #include "gtest/gtest.h"
19
20 using namespace llvm;
21 using namespace std::chrono;
22
23 /// Try best to make this thread not progress faster than the main thread
24 static 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
34 // Fixture for the unittests, allowing to *temporarily* disable the unittests
35 // on a particular platform
36 class 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;
41 protected:
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);
64   }
65 };
66
67 #define CHECK_UNSUPPORTED() \
68   do { \
69     if (isUnsupportedOSOrEnvironment()) \
70       return; \
71   } while (0); \
72
73 TEST_F(ThreadPoolTest, AsyncBarrier) {
74   CHECK_UNSUPPORTED();
75   // test that async & barrier work together properly.
76
77   std::atomic_int checked_in{0};
78
79   ThreadPool Pool;
80   for (size_t i = 0; i < 5; ++i) {
81     Pool.async([&checked_in, i] {
82       yield();
83       ++checked_in;
84     });
85   }
86   ASSERT_EQ(0, checked_in);
87   Pool.wait();
88   ASSERT_EQ(5, checked_in);
89 }
90
91 static void TestFunc(std::atomic_int &checked_in, int i) { checked_in += i; }
92
93 TEST_F(ThreadPoolTest, AsyncBarrierArgs) {
94   CHECK_UNSUPPORTED();
95   // Test that async works with a function requiring multiple parameters.
96   std::atomic_int checked_in{0};
97
98   ThreadPool Pool;
99   for (size_t i = 0; i < 5; ++i) {
100     Pool.async(TestFunc, std::ref(checked_in), i);
101   }
102   Pool.wait();
103   ASSERT_EQ(10, checked_in);
104 }
105
106 TEST_F(ThreadPoolTest, Async) {
107   CHECK_UNSUPPORTED();
108   ThreadPool Pool;
109   std::atomic_int i{0};
110   // sleep here just to ensure that the not-equal is correct.
111   Pool.async([&i] {
112     yield();
113     ++i;
114   });
115   Pool.async([&i] { ++i; });
116   ASSERT_NE(2, i.load());
117   Pool.wait();
118   ASSERT_EQ(2, i.load());
119 }
120
121 TEST_F(ThreadPoolTest, GetFuture) {
122   CHECK_UNSUPPORTED();
123   ThreadPool Pool;
124   std::atomic_int i{0};
125   // sleep here just to ensure that the not-equal is correct.
126   Pool.async([&i] {
127     yield();
128     ++i;
129   });
130   // Force the future using get()
131   Pool.async([&i] { ++i; }).get();
132   ASSERT_NE(2, i.load());
133   Pool.wait();
134   ASSERT_EQ(2, i.load());
135 }
136
137 TEST_F(ThreadPoolTest, PoolDestruction) {
138   CHECK_UNSUPPORTED();
139   // Test that we are waiting on destruction
140   std::atomic_int checked_in{0};
141
142   {
143     ThreadPool Pool;
144     for (size_t i = 0; i < 5; ++i) {
145       Pool.async([&checked_in, i] {
146         yield();
147         ++checked_in;
148       });
149     }
150     ASSERT_EQ(0, checked_in);
151   }
152   ASSERT_EQ(5, checked_in);
153 }