1 //========- unittests/Support/TaskQueue.cpp - TaskQueue.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/Config/llvm-config.h" 11 12 #if LLVM_ENABLE_THREADS 13 14 #include "llvm/Support/TaskQueue.h" 15 16 #include "gtest/gtest.h" 17 18 using namespace llvm; 19 20 class TaskQueueTest : public testing::Test { 21 protected: 22 TaskQueueTest() {} 23 }; 24 25 TEST_F(TaskQueueTest, OrderedFutures) { 26 ThreadPool TP(1); 27 TaskQueue TQ(TP); 28 std::atomic<int> X{ 0 }; 29 std::atomic<int> Y{ 0 }; 30 std::atomic<int> Z{ 0 }; 31 32 std::mutex M1, M2, M3; 33 std::unique_lock<std::mutex> L1(M1); 34 std::unique_lock<std::mutex> L2(M2); 35 std::unique_lock<std::mutex> L3(M3); 36 37 std::future<void> F1 = TQ.async([&] { 38 std::unique_lock<std::mutex> Lock(M1); 39 ++X; 40 }); 41 std::future<void> F2 = TQ.async([&] { 42 std::unique_lock<std::mutex> Lock(M2); 43 ++Y; 44 }); 45 std::future<void> F3 = TQ.async([&] { 46 std::unique_lock<std::mutex> Lock(M3); 47 ++Z; 48 }); 49 50 L1.unlock(); 51 F1.wait(); 52 ASSERT_EQ(1, X); 53 ASSERT_EQ(0, Y); 54 ASSERT_EQ(0, Z); 55 56 L2.unlock(); 57 F2.wait(); 58 ASSERT_EQ(1, X); 59 ASSERT_EQ(1, Y); 60 ASSERT_EQ(0, Z); 61 62 L3.unlock(); 63 F3.wait(); 64 ASSERT_EQ(1, X); 65 ASSERT_EQ(1, Y); 66 ASSERT_EQ(1, Z); 67 } 68 69 TEST_F(TaskQueueTest, UnOrderedFutures) { 70 ThreadPool TP(1); 71 TaskQueue TQ(TP); 72 std::atomic<int> X{ 0 }; 73 std::atomic<int> Y{ 0 }; 74 std::atomic<int> Z{ 0 }; 75 std::mutex M; 76 77 std::unique_lock<std::mutex> Lock(M); 78 79 std::future<void> F1 = TQ.async([&] { ++X; }); 80 std::future<void> F2 = TQ.async([&] { ++Y; }); 81 std::future<void> F3 = TQ.async([&M, &Z] { 82 std::unique_lock<std::mutex> Lock(M); 83 ++Z; 84 }); 85 86 F2.wait(); 87 ASSERT_EQ(1, X); 88 ASSERT_EQ(1, Y); 89 ASSERT_EQ(0, Z); 90 91 Lock.unlock(); 92 93 F3.wait(); 94 ASSERT_EQ(1, X); 95 ASSERT_EQ(1, Y); 96 ASSERT_EQ(1, Z); 97 } 98 99 TEST_F(TaskQueueTest, FutureWithReturnValue) { 100 ThreadPool TP(1); 101 TaskQueue TQ(TP); 102 std::future<std::string> F1 = TQ.async([&] { return std::string("Hello"); }); 103 std::future<int> F2 = TQ.async([&] { return 42; }); 104 105 ASSERT_EQ(42, F2.get()); 106 ASSERT_EQ("Hello", F1.get()); 107 } 108 #endif 109