rwmutex_test.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "rwmutex.h"
  15. #include "gmock/gmock.h"
  16. #include "gtest/gtest.h"
  17. #include <array>
  18. #include <thread>
  19. #include <vector>
  20. namespace {
  21. constexpr const size_t NumThreads = 8;
  22. }
  23. // Check that WLock behaves like regular mutex.
  24. TEST(RWMutex, WLock) {
  25. dap::RWMutex rwmutex;
  26. int counter = 0;
  27. std::vector<std::thread> threads;
  28. for (size_t i = 0; i < NumThreads; i++) {
  29. threads.emplace_back([&] {
  30. for (int j = 0; j < 1000; j++) {
  31. dap::WLock lock(rwmutex);
  32. counter++;
  33. EXPECT_EQ(counter, 1);
  34. counter--;
  35. }
  36. });
  37. }
  38. for (auto& thread : threads) {
  39. thread.join();
  40. }
  41. EXPECT_EQ(counter, 0);
  42. }
  43. TEST(RWMutex, NoRLockWithWLock) {
  44. dap::RWMutex rwmutex;
  45. std::vector<std::thread> threads;
  46. std::array<int, NumThreads> counters = {};
  47. { // With WLock held...
  48. dap::WLock wlock(rwmutex);
  49. for (size_t i = 0; i < counters.size(); i++) {
  50. int* counter = &counters[i];
  51. threads.emplace_back([&rwmutex, counter] {
  52. dap::RLock lock(rwmutex);
  53. for (int j = 0; j < 1000; j++) {
  54. (*counter)++;
  55. }
  56. });
  57. }
  58. // RLocks should block
  59. for (int counter : counters) {
  60. EXPECT_EQ(counter, 0);
  61. }
  62. }
  63. for (auto& thread : threads) {
  64. thread.join();
  65. }
  66. for (int counter : counters) {
  67. EXPECT_EQ(counter, 1000);
  68. }
  69. }
  70. TEST(RWMutex, NoWLockWithRLock) {
  71. dap::RWMutex rwmutex;
  72. std::vector<std::thread> threads;
  73. size_t counter = 0;
  74. { // With RLocks held...
  75. dap::RLock rlockA(rwmutex);
  76. dap::RLock rlockB(rwmutex);
  77. dap::RLock rlockC(rwmutex);
  78. for (size_t i = 0; i < NumThreads; i++) {
  79. threads.emplace_back(std::thread([&] {
  80. dap::WLock lock(rwmutex);
  81. counter++;
  82. }));
  83. }
  84. // ... WLocks should block
  85. EXPECT_EQ(counter, 0U);
  86. }
  87. for (auto& thread : threads) {
  88. thread.join();
  89. }
  90. EXPECT_EQ(counter, NumThreads);
  91. }