• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //========- unittests/Support/TaskQueue.cpp - TaskQueue.h tests ------========//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Config/llvm-config.h"
10 
11 #if LLVM_ENABLE_THREADS
12 
13 #include "llvm/Support/TaskQueue.h"
14 
15 #include "gtest/gtest.h"
16 
17 using namespace llvm;
18 
19 class TaskQueueTest : public testing::Test {
20 protected:
TaskQueueTest()21   TaskQueueTest() {}
22 };
23 
TEST_F(TaskQueueTest,OrderedFutures)24 TEST_F(TaskQueueTest, OrderedFutures) {
25   ThreadPool TP(hardware_concurrency(1));
26   TaskQueue TQ(TP);
27   std::atomic<int> X{ 0 };
28   std::atomic<int> Y{ 0 };
29   std::atomic<int> Z{ 0 };
30 
31   std::mutex M1, M2, M3;
32   std::unique_lock<std::mutex> L1(M1);
33   std::unique_lock<std::mutex> L2(M2);
34   std::unique_lock<std::mutex> L3(M3);
35 
36   std::future<void> F1 = TQ.async([&] {
37     std::unique_lock<std::mutex> Lock(M1);
38     ++X;
39   });
40   std::future<void> F2 = TQ.async([&] {
41     std::unique_lock<std::mutex> Lock(M2);
42     ++Y;
43   });
44   std::future<void> F3 = TQ.async([&] {
45     std::unique_lock<std::mutex> Lock(M3);
46     ++Z;
47   });
48 
49   L1.unlock();
50   F1.wait();
51   ASSERT_EQ(1, X);
52   ASSERT_EQ(0, Y);
53   ASSERT_EQ(0, Z);
54 
55   L2.unlock();
56   F2.wait();
57   ASSERT_EQ(1, X);
58   ASSERT_EQ(1, Y);
59   ASSERT_EQ(0, Z);
60 
61   L3.unlock();
62   F3.wait();
63   ASSERT_EQ(1, X);
64   ASSERT_EQ(1, Y);
65   ASSERT_EQ(1, Z);
66 }
67 
TEST_F(TaskQueueTest,UnOrderedFutures)68 TEST_F(TaskQueueTest, UnOrderedFutures) {
69   ThreadPool TP(hardware_concurrency(1));
70   TaskQueue TQ(TP);
71   std::atomic<int> X{ 0 };
72   std::atomic<int> Y{ 0 };
73   std::atomic<int> Z{ 0 };
74   std::mutex M;
75 
76   std::unique_lock<std::mutex> Lock(M);
77 
78   std::future<void> F1 = TQ.async([&] { ++X; });
79   std::future<void> F2 = TQ.async([&] { ++Y; });
80   std::future<void> F3 = TQ.async([&M, &Z] {
81     std::unique_lock<std::mutex> Lock(M);
82     ++Z;
83   });
84 
85   F2.wait();
86   ASSERT_EQ(1, X);
87   ASSERT_EQ(1, Y);
88   ASSERT_EQ(0, Z);
89 
90   Lock.unlock();
91 
92   F3.wait();
93   ASSERT_EQ(1, X);
94   ASSERT_EQ(1, Y);
95   ASSERT_EQ(1, Z);
96 }
97 
TEST_F(TaskQueueTest,FutureWithReturnValue)98 TEST_F(TaskQueueTest, FutureWithReturnValue) {
99   ThreadPool TP(hardware_concurrency(1));
100   TaskQueue TQ(TP);
101   std::future<std::string> F1 = TQ.async([&] { return std::string("Hello"); });
102   std::future<int> F2 = TQ.async([&] { return 42; });
103 
104   ASSERT_EQ(42, F2.get());
105   ASSERT_EQ("Hello", F1.get());
106 }
107 #endif
108