TaskQueueTest.cpp 2.3 KB

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