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: 21 TaskQueueTest() {} 22 }; 23 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 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 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