Mark ThreadPool unittests as unsupported on PowerPC64
[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     // See https://llvm.org/bugs/show_bug.cgi?id=25829
66     UnsupportedArchs.push_back(Triple::ppc64le);
67     UnsupportedArchs.push_back(Triple::ppc64);
68   }
69 };
70
71 #define CHECK_UNSUPPORTED() \
72   do { \
73     if (isUnsupportedOSOrEnvironment()) \
74       return; \
75   } while (0); \
76
77 TEST_F(ThreadPoolTest, AsyncBarrier) {
78   CHECK_UNSUPPORTED();
79   // 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
95 static void TestFunc(std::atomic_int &checked_in, int i) { checked_in += i; }
96
97 TEST_F(ThreadPoolTest, AsyncBarrierArgs) {
98   CHECK_UNSUPPORTED();
99   // 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
110 TEST_F(ThreadPoolTest, Async) {
111   CHECK_UNSUPPORTED();
112   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
125 TEST_F(ThreadPoolTest, GetFuture) {
126   CHECK_UNSUPPORTED();
127   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
141 TEST_F(ThreadPoolTest, PoolDestruction) {
142   CHECK_UNSUPPORTED();
143   // 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 }