OSDN Git Service

Object/WasmObjectFile: Fix comparison of different signs
[android-x86/external-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
22 // Fixture for the unittests, allowing to *temporarily* disable the unittests
23 // on a particular platform
24 class 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;
29 protected:
30   // This is intended for platform as a temporary "XFAIL"
31   bool isUnsupportedOSOrEnvironment() {
32     Triple Host(Triple::normalize(sys::getProcessTriple()));
33
34     if (find(UnsupportedEnvironments, Host.getEnvironment()) !=
35         UnsupportedEnvironments.end())
36       return true;
37
38     if (is_contained(UnsupportedOSs, Host.getOS()))
39       return true;
40
41     if (is_contained(UnsupportedArchs, Host.getArch()))
42       return true;
43
44     return false;
45   }
46
47   ThreadPoolTest() {
48     // Add unsupported configuration here, example:
49     //   UnsupportedArchs.push_back(Triple::x86_64);
50
51     // See https://llvm.org/bugs/show_bug.cgi?id=25829
52     UnsupportedArchs.push_back(Triple::ppc64le);
53     UnsupportedArchs.push_back(Triple::ppc64);
54   }
55
56   /// Make sure this thread not progress faster than the main thread.
57   void waitForMainThread() {
58     std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
59     WaitMainThread.wait(LockGuard, [&] { return MainThreadReady; });
60   }
61
62   /// Set the readiness of the main thread.
63   void setMainThreadReady() {
64     {
65       std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
66       MainThreadReady = true;
67     }
68     WaitMainThread.notify_all();
69   }
70
71   void SetUp() override { MainThreadReady = false; }
72
73   std::condition_variable WaitMainThread;
74   std::mutex WaitMainThreadMutex;
75   bool MainThreadReady;
76
77 };
78
79 #define CHECK_UNSUPPORTED() \
80   do { \
81     if (isUnsupportedOSOrEnvironment()) \
82       return; \
83   } while (0); \
84
85 TEST_F(ThreadPoolTest, AsyncBarrier) {
86   CHECK_UNSUPPORTED();
87   // test that async & barrier work together properly.
88
89   std::atomic_int checked_in{0};
90
91   ThreadPool Pool;
92   for (size_t i = 0; i < 5; ++i) {
93     Pool.async([this, &checked_in] {
94       waitForMainThread();
95       ++checked_in;
96     });
97   }
98   ASSERT_EQ(0, checked_in);
99   setMainThreadReady();
100   Pool.wait();
101   ASSERT_EQ(5, checked_in);
102 }
103
104 static void TestFunc(std::atomic_int &checked_in, int i) { checked_in += i; }
105
106 TEST_F(ThreadPoolTest, AsyncBarrierArgs) {
107   CHECK_UNSUPPORTED();
108   // Test that async works with a function requiring multiple parameters.
109   std::atomic_int checked_in{0};
110
111   ThreadPool Pool;
112   for (size_t i = 0; i < 5; ++i) {
113     Pool.async(TestFunc, std::ref(checked_in), i);
114   }
115   Pool.wait();
116   ASSERT_EQ(10, checked_in);
117 }
118
119 TEST_F(ThreadPoolTest, Async) {
120   CHECK_UNSUPPORTED();
121   ThreadPool Pool;
122   std::atomic_int i{0};
123   Pool.async([this, &i] {
124     waitForMainThread();
125     ++i;
126   });
127   Pool.async([&i] { ++i; });
128   ASSERT_NE(2, i.load());
129   setMainThreadReady();
130   Pool.wait();
131   ASSERT_EQ(2, i.load());
132 }
133
134 TEST_F(ThreadPoolTest, GetFuture) {
135   CHECK_UNSUPPORTED();
136   ThreadPool Pool{2};
137   std::atomic_int i{0};
138   Pool.async([this, &i] {
139     waitForMainThread();
140     ++i;
141   });
142   // Force the future using get()
143   Pool.async([&i] { ++i; }).get();
144   ASSERT_NE(2, i.load());
145   setMainThreadReady();
146   Pool.wait();
147   ASSERT_EQ(2, i.load());
148 }
149
150 TEST_F(ThreadPoolTest, PoolDestruction) {
151   CHECK_UNSUPPORTED();
152   // Test that we are waiting on destruction
153   std::atomic_int checked_in{0};
154   {
155     ThreadPool Pool;
156     for (size_t i = 0; i < 5; ++i) {
157       Pool.async([this, &checked_in] {
158         waitForMainThread();
159         ++checked_in;
160       });
161     }
162     ASSERT_EQ(0, checked_in);
163     setMainThreadReady();
164   }
165   ASSERT_EQ(5, checked_in);
166 }