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