sync_point_impl.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #include "test_util/sync_point_impl.h"
  6. #ifndef NDEBUG
  7. namespace ROCKSDB_NAMESPACE {
  8. void TestKillRandom(std::string kill_point, int odds,
  9. const std::string& srcfile, int srcline) {
  10. for (auto& p : rocksdb_kill_prefix_blacklist) {
  11. if (kill_point.substr(0, p.length()) == p) {
  12. return;
  13. }
  14. }
  15. assert(odds > 0);
  16. if (odds % 7 == 0) {
  17. // class Random uses multiplier 16807, which is 7^5. If odds are
  18. // multiplier of 7, there might be limited values generated.
  19. odds++;
  20. }
  21. auto* r = Random::GetTLSInstance();
  22. bool crash = r->OneIn(odds);
  23. if (crash) {
  24. port::Crash(srcfile, srcline);
  25. }
  26. }
  27. void SyncPoint::Data::LoadDependency(const std::vector<SyncPointPair>& dependencies) {
  28. std::lock_guard<std::mutex> lock(mutex_);
  29. successors_.clear();
  30. predecessors_.clear();
  31. cleared_points_.clear();
  32. for (const auto& dependency : dependencies) {
  33. successors_[dependency.predecessor].push_back(dependency.successor);
  34. predecessors_[dependency.successor].push_back(dependency.predecessor);
  35. }
  36. cv_.notify_all();
  37. }
  38. void SyncPoint::Data::LoadDependencyAndMarkers(
  39. const std::vector<SyncPointPair>& dependencies,
  40. const std::vector<SyncPointPair>& markers) {
  41. std::lock_guard<std::mutex> lock(mutex_);
  42. successors_.clear();
  43. predecessors_.clear();
  44. cleared_points_.clear();
  45. markers_.clear();
  46. marked_thread_id_.clear();
  47. for (const auto& dependency : dependencies) {
  48. successors_[dependency.predecessor].push_back(dependency.successor);
  49. predecessors_[dependency.successor].push_back(dependency.predecessor);
  50. }
  51. for (const auto& marker : markers) {
  52. successors_[marker.predecessor].push_back(marker.successor);
  53. predecessors_[marker.successor].push_back(marker.predecessor);
  54. markers_[marker.predecessor].push_back(marker.successor);
  55. }
  56. cv_.notify_all();
  57. }
  58. bool SyncPoint::Data::PredecessorsAllCleared(const std::string& point) {
  59. for (const auto& pred : predecessors_[point]) {
  60. if (cleared_points_.count(pred) == 0) {
  61. return false;
  62. }
  63. }
  64. return true;
  65. }
  66. void SyncPoint::Data::ClearCallBack(const std::string& point) {
  67. std::unique_lock<std::mutex> lock(mutex_);
  68. while (num_callbacks_running_ > 0) {
  69. cv_.wait(lock);
  70. }
  71. callbacks_.erase(point);
  72. }
  73. void SyncPoint::Data::ClearAllCallBacks() {
  74. std::unique_lock<std::mutex> lock(mutex_);
  75. while (num_callbacks_running_ > 0) {
  76. cv_.wait(lock);
  77. }
  78. callbacks_.clear();
  79. }
  80. void SyncPoint::Data::Process(const std::string& point, void* cb_arg) {
  81. if (!enabled_) {
  82. return;
  83. }
  84. std::unique_lock<std::mutex> lock(mutex_);
  85. auto thread_id = std::this_thread::get_id();
  86. auto marker_iter = markers_.find(point);
  87. if (marker_iter != markers_.end()) {
  88. for (auto& marked_point : marker_iter->second) {
  89. marked_thread_id_.emplace(marked_point, thread_id);
  90. }
  91. }
  92. if (DisabledByMarker(point, thread_id)) {
  93. return;
  94. }
  95. while (!PredecessorsAllCleared(point)) {
  96. cv_.wait(lock);
  97. if (DisabledByMarker(point, thread_id)) {
  98. return;
  99. }
  100. }
  101. auto callback_pair = callbacks_.find(point);
  102. if (callback_pair != callbacks_.end()) {
  103. num_callbacks_running_++;
  104. mutex_.unlock();
  105. callback_pair->second(cb_arg);
  106. mutex_.lock();
  107. num_callbacks_running_--;
  108. }
  109. cleared_points_.insert(point);
  110. cv_.notify_all();
  111. }
  112. } // namespace ROCKSDB_NAMESPACE
  113. #endif