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