recursive_spin_lock_ut.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include <library/cpp/testing/gtest/gtest.h>
  2. #include <library/cpp/yt/threading/recursive_spin_lock.h>
  3. #include <library/cpp/yt/threading/event_count.h>
  4. #include <thread>
  5. namespace NYT::NThreading {
  6. namespace {
  7. ////////////////////////////////////////////////////////////////////////////////
  8. TEST(TRecursiveSpinLockTest, SingleThread)
  9. {
  10. TRecursiveSpinLock lock;
  11. EXPECT_FALSE(lock.IsLocked());
  12. EXPECT_TRUE(lock.TryAcquire());
  13. EXPECT_TRUE(lock.IsLocked());
  14. EXPECT_TRUE(lock.TryAcquire());
  15. EXPECT_TRUE(lock.IsLocked());
  16. lock.Release();
  17. EXPECT_TRUE(lock.IsLocked());
  18. lock.Release();
  19. EXPECT_FALSE(lock.IsLocked());
  20. EXPECT_TRUE(lock.TryAcquire());
  21. EXPECT_TRUE(lock.IsLocked());
  22. lock.Release();
  23. lock.Acquire();
  24. lock.Release();
  25. }
  26. TEST(TRecursiveSpinLockTest, TwoThreads)
  27. {
  28. TRecursiveSpinLock lock;
  29. TEvent e1, e2, e3, e4, e5, e6, e7;
  30. std::thread t1([&] {
  31. e1.Wait();
  32. EXPECT_TRUE(lock.IsLocked());
  33. EXPECT_FALSE(lock.IsLockedByCurrentThread());
  34. EXPECT_FALSE(lock.TryAcquire());
  35. e2.NotifyOne();
  36. e3.Wait();
  37. EXPECT_TRUE(lock.IsLocked());
  38. EXPECT_FALSE(lock.IsLockedByCurrentThread());
  39. EXPECT_FALSE(lock.TryAcquire());
  40. e4.NotifyOne();
  41. e5.Wait();
  42. EXPECT_FALSE(lock.IsLocked());
  43. EXPECT_FALSE(lock.IsLockedByCurrentThread());
  44. EXPECT_TRUE(lock.TryAcquire());
  45. e6.NotifyOne();
  46. e7.Wait();
  47. lock.Release();
  48. });
  49. std::thread t2([&] {
  50. EXPECT_FALSE(lock.IsLocked());
  51. EXPECT_TRUE(lock.TryAcquire());
  52. EXPECT_TRUE(lock.IsLockedByCurrentThread());
  53. e1.NotifyOne();
  54. e2.Wait();
  55. EXPECT_TRUE(lock.TryAcquire());
  56. EXPECT_TRUE(lock.IsLockedByCurrentThread());
  57. e3.NotifyOne();
  58. e4.Wait();
  59. lock.Release();
  60. lock.Release();
  61. EXPECT_FALSE(lock.IsLocked());
  62. e5.NotifyOne();
  63. e6.Wait();
  64. EXPECT_TRUE(lock.IsLocked());
  65. EXPECT_FALSE(lock.IsLockedByCurrentThread());
  66. e7.NotifyOne();
  67. lock.Acquire();
  68. lock.Acquire();
  69. lock.Release();
  70. lock.Release();
  71. });
  72. t1.join();
  73. t2.join();
  74. }
  75. ////////////////////////////////////////////////////////////////////////////////
  76. } // namespace
  77. } // namespace NYT::NThreading