135169f66SZachary Turner //========- unittests/Support/TaskQueue.cpp - TaskQueue.h tests ------========//
235169f66SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
635169f66SZachary Turner //
735169f66SZachary Turner //===----------------------------------------------------------------------===//
835169f66SZachary Turner
90d63dbbcSNico Weber #include "llvm/Config/llvm-config.h"
100d63dbbcSNico Weber
11a7f9e66cSNico Weber #if LLVM_ENABLE_THREADS
12a7f9e66cSNico Weber
1335169f66SZachary Turner #include "llvm/Support/TaskQueue.h"
1435169f66SZachary Turner
1535169f66SZachary Turner #include "gtest/gtest.h"
1635169f66SZachary Turner
1735169f66SZachary Turner using namespace llvm;
1835169f66SZachary Turner
1935169f66SZachary Turner class TaskQueueTest : public testing::Test {
2035169f66SZachary Turner protected:
TaskQueueTest()2135169f66SZachary Turner TaskQueueTest() {}
2235169f66SZachary Turner };
2335169f66SZachary Turner
TEST_F(TaskQueueTest,OrderedFutures)2435169f66SZachary Turner TEST_F(TaskQueueTest, OrderedFutures) {
25*8404aeb5SAlexandre Ganea ThreadPool TP(hardware_concurrency(1));
2635169f66SZachary Turner TaskQueue TQ(TP);
27eee66518SZachary Turner std::atomic<int> X{ 0 };
28eee66518SZachary Turner std::atomic<int> Y{ 0 };
29eee66518SZachary Turner std::atomic<int> Z{ 0 };
3035169f66SZachary Turner
3135169f66SZachary Turner std::mutex M1, M2, M3;
3235169f66SZachary Turner std::unique_lock<std::mutex> L1(M1);
3335169f66SZachary Turner std::unique_lock<std::mutex> L2(M2);
3435169f66SZachary Turner std::unique_lock<std::mutex> L3(M3);
3535169f66SZachary Turner
3635169f66SZachary Turner std::future<void> F1 = TQ.async([&] {
3735169f66SZachary Turner std::unique_lock<std::mutex> Lock(M1);
3835169f66SZachary Turner ++X;
3935169f66SZachary Turner });
4035169f66SZachary Turner std::future<void> F2 = TQ.async([&] {
4135169f66SZachary Turner std::unique_lock<std::mutex> Lock(M2);
4235169f66SZachary Turner ++Y;
4335169f66SZachary Turner });
4435169f66SZachary Turner std::future<void> F3 = TQ.async([&] {
4535169f66SZachary Turner std::unique_lock<std::mutex> Lock(M3);
4635169f66SZachary Turner ++Z;
4735169f66SZachary Turner });
4835169f66SZachary Turner
4935169f66SZachary Turner L1.unlock();
5035169f66SZachary Turner F1.wait();
5135169f66SZachary Turner ASSERT_EQ(1, X);
5235169f66SZachary Turner ASSERT_EQ(0, Y);
5335169f66SZachary Turner ASSERT_EQ(0, Z);
5435169f66SZachary Turner
5535169f66SZachary Turner L2.unlock();
5635169f66SZachary Turner F2.wait();
5735169f66SZachary Turner ASSERT_EQ(1, X);
5835169f66SZachary Turner ASSERT_EQ(1, Y);
5935169f66SZachary Turner ASSERT_EQ(0, Z);
6035169f66SZachary Turner
6135169f66SZachary Turner L3.unlock();
6235169f66SZachary Turner F3.wait();
6335169f66SZachary Turner ASSERT_EQ(1, X);
6435169f66SZachary Turner ASSERT_EQ(1, Y);
6535169f66SZachary Turner ASSERT_EQ(1, Z);
6635169f66SZachary Turner }
6735169f66SZachary Turner
TEST_F(TaskQueueTest,UnOrderedFutures)6835169f66SZachary Turner TEST_F(TaskQueueTest, UnOrderedFutures) {
69*8404aeb5SAlexandre Ganea ThreadPool TP(hardware_concurrency(1));
7035169f66SZachary Turner TaskQueue TQ(TP);
71eee66518SZachary Turner std::atomic<int> X{ 0 };
72eee66518SZachary Turner std::atomic<int> Y{ 0 };
73eee66518SZachary Turner std::atomic<int> Z{ 0 };
7435169f66SZachary Turner std::mutex M;
7535169f66SZachary Turner
7635169f66SZachary Turner std::unique_lock<std::mutex> Lock(M);
7735169f66SZachary Turner
7835169f66SZachary Turner std::future<void> F1 = TQ.async([&] { ++X; });
7935169f66SZachary Turner std::future<void> F2 = TQ.async([&] { ++Y; });
8035169f66SZachary Turner std::future<void> F3 = TQ.async([&M, &Z] {
8135169f66SZachary Turner std::unique_lock<std::mutex> Lock(M);
8235169f66SZachary Turner ++Z;
8335169f66SZachary Turner });
8435169f66SZachary Turner
8535169f66SZachary Turner F2.wait();
8635169f66SZachary Turner ASSERT_EQ(1, X);
8735169f66SZachary Turner ASSERT_EQ(1, Y);
8835169f66SZachary Turner ASSERT_EQ(0, Z);
8935169f66SZachary Turner
9035169f66SZachary Turner Lock.unlock();
9135169f66SZachary Turner
9235169f66SZachary Turner F3.wait();
9335169f66SZachary Turner ASSERT_EQ(1, X);
9435169f66SZachary Turner ASSERT_EQ(1, Y);
9535169f66SZachary Turner ASSERT_EQ(1, Z);
9635169f66SZachary Turner }
9735169f66SZachary Turner
TEST_F(TaskQueueTest,FutureWithReturnValue)9835169f66SZachary Turner TEST_F(TaskQueueTest, FutureWithReturnValue) {
99*8404aeb5SAlexandre Ganea ThreadPool TP(hardware_concurrency(1));
10035169f66SZachary Turner TaskQueue TQ(TP);
10135169f66SZachary Turner std::future<std::string> F1 = TQ.async([&] { return std::string("Hello"); });
10235169f66SZachary Turner std::future<int> F2 = TQ.async([&] { return 42; });
10335169f66SZachary Turner
10435169f66SZachary Turner ASSERT_EQ(42, F2.get());
10535169f66SZachary Turner ASSERT_EQ("Hello", F1.get());
10635169f66SZachary Turner }
10735169f66SZachary Turner #endif
108