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).
6 #include "test_util/sync_point_impl.h"
9 namespace ROCKSDB_NAMESPACE
{
11 void TestKillRandom(std::string kill_point
, int odds
,
12 const std::string
& srcfile
, int srcline
) {
13 for (auto& p
: rocksdb_kill_exclude_prefixes
) {
14 if (kill_point
.substr(0, p
.length()) == p
) {
21 // class Random uses multiplier 16807, which is 7^5. If odds are
22 // multiplier of 7, there might be limited values generated.
25 auto* r
= Random::GetTLSInstance();
26 bool crash
= r
->OneIn(odds
);
28 port::Crash(srcfile
, srcline
);
33 void SyncPoint::Data::LoadDependency(const std::vector
<SyncPointPair
>& dependencies
) {
34 std::lock_guard
<std::mutex
> lock(mutex_
);
36 predecessors_
.clear();
37 cleared_points_
.clear();
38 for (const auto& dependency
: dependencies
) {
39 successors_
[dependency
.predecessor
].push_back(dependency
.successor
);
40 predecessors_
[dependency
.successor
].push_back(dependency
.predecessor
);
45 void SyncPoint::Data::LoadDependencyAndMarkers(
46 const std::vector
<SyncPointPair
>& dependencies
,
47 const std::vector
<SyncPointPair
>& markers
) {
48 std::lock_guard
<std::mutex
> lock(mutex_
);
50 predecessors_
.clear();
51 cleared_points_
.clear();
53 marked_thread_id_
.clear();
54 for (const auto& dependency
: dependencies
) {
55 successors_
[dependency
.predecessor
].push_back(dependency
.successor
);
56 predecessors_
[dependency
.successor
].push_back(dependency
.predecessor
);
58 for (const auto& marker
: markers
) {
59 successors_
[marker
.predecessor
].push_back(marker
.successor
);
60 predecessors_
[marker
.successor
].push_back(marker
.predecessor
);
61 markers_
[marker
.predecessor
].push_back(marker
.successor
);
66 bool SyncPoint::Data::PredecessorsAllCleared(const std::string
& point
) {
67 for (const auto& pred
: predecessors_
[point
]) {
68 if (cleared_points_
.count(pred
) == 0) {
75 void SyncPoint::Data::ClearCallBack(const std::string
& point
) {
76 std::unique_lock
<std::mutex
> lock(mutex_
);
77 while (num_callbacks_running_
> 0) {
80 callbacks_
.erase(point
);
83 void SyncPoint::Data::ClearAllCallBacks() {
84 std::unique_lock
<std::mutex
> lock(mutex_
);
85 while (num_callbacks_running_
> 0) {
91 void SyncPoint::Data::Process(const std::string
& point
, void* cb_arg
) {
96 std::unique_lock
<std::mutex
> lock(mutex_
);
97 auto thread_id
= std::this_thread::get_id();
99 auto marker_iter
= markers_
.find(point
);
100 if (marker_iter
!= markers_
.end()) {
101 for (auto& marked_point
: marker_iter
->second
) {
102 marked_thread_id_
.emplace(marked_point
, thread_id
);
106 if (DisabledByMarker(point
, thread_id
)) {
110 while (!PredecessorsAllCleared(point
)) {
112 if (DisabledByMarker(point
, thread_id
)) {
117 auto callback_pair
= callbacks_
.find(point
);
118 if (callback_pair
!= callbacks_
.end()) {
119 num_callbacks_running_
++;
121 callback_pair
->second(cb_arg
);
123 num_callbacks_running_
--;
125 cleared_points_
.insert(point
);
128 } // namespace ROCKSDB_NAMESPACE