]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/util/sync_point.h
bump version to 15.2.11-pve1
[ceph.git] / ceph / src / rocksdb / util / sync_point.h
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
5#pragma once
6
7#include <assert.h>
7c673cae
FG
8#include <functional>
9#include <mutex>
10#include <string>
11#include <thread>
7c673cae
FG
12#include <vector>
13
14// This is only set from db_stress.cc and for testing only.
15// If non-zero, kill at various points in source code with probability 1/this
16extern int rocksdb_kill_odds;
17// If kill point has a prefix on this list, will skip killing.
18extern std::vector<std::string> rocksdb_kill_prefix_blacklist;
19
20#ifdef NDEBUG
21// empty in release build
22#define TEST_KILL_RANDOM(kill_point, rocksdb_kill_odds)
23#else
24
25namespace rocksdb {
11fdf7f2 26// Kill the process with probability 1/odds for testing.
7c673cae
FG
27extern void TestKillRandom(std::string kill_point, int odds,
28 const std::string& srcfile, int srcline);
29
30// To avoid crashing always at some frequently executed codepaths (during
31// kill random test), use this factor to reduce odds
32#define REDUCE_ODDS 2
33#define REDUCE_ODDS2 4
34
35#define TEST_KILL_RANDOM(kill_point, rocksdb_kill_odds) \
36 { \
37 if (rocksdb_kill_odds > 0) { \
38 TestKillRandom(kill_point, rocksdb_kill_odds, __FILE__, __LINE__); \
39 } \
40 }
41} // namespace rocksdb
42#endif
43
44#ifdef NDEBUG
45#define TEST_SYNC_POINT(x)
11fdf7f2 46#define TEST_IDX_SYNC_POINT(x, index)
7c673cae 47#define TEST_SYNC_POINT_CALLBACK(x, y)
11fdf7f2 48#define INIT_SYNC_POINT_SINGLETONS()
7c673cae
FG
49#else
50
51namespace rocksdb {
52
53// This class provides facility to reproduce race conditions deterministically
54// in unit tests.
55// Developer could specify sync points in the codebase via TEST_SYNC_POINT.
56// Each sync point represents a position in the execution stream of a thread.
57// In the unit test, 'Happens After' relationship among sync points could be
58// setup via SyncPoint::LoadDependency, to reproduce a desired interleave of
59// threads execution.
60// Refer to (DBTest,TransactionLogIteratorRace), for an example use case.
61
62class SyncPoint {
63 public:
64 static SyncPoint* GetInstance();
65
11fdf7f2
TL
66 SyncPoint(const SyncPoint&) = delete;
67 SyncPoint& operator=(const SyncPoint&) = delete;
68 ~SyncPoint();
69
7c673cae
FG
70 struct SyncPointPair {
71 std::string predecessor;
72 std::string successor;
73 };
74
75 // call once at the beginning of a test to setup the dependency between
76 // sync points
77 void LoadDependency(const std::vector<SyncPointPair>& dependencies);
78
79 // call once at the beginning of a test to setup the dependency between
80 // sync points and setup markers indicating the successor is only enabled
81 // when it is processed on the same thread as the predecessor.
82 // When adding a marker, it implicitly adds a dependency for the marker pair.
83 void LoadDependencyAndMarkers(const std::vector<SyncPointPair>& dependencies,
84 const std::vector<SyncPointPair>& markers);
85
11fdf7f2
TL
86 // The argument to the callback is passed through from
87 // TEST_SYNC_POINT_CALLBACK(); nullptr if TEST_SYNC_POINT or
88 // TEST_IDX_SYNC_POINT was used.
89 void SetCallBack(const std::string& point,
90 const std::function<void(void*)>& callback);
91
92 // Clear callback function by point
93 void ClearCallBack(const std::string& point);
94
7c673cae
FG
95 // Clear all call back functions.
96 void ClearAllCallBacks();
97
98 // enable sync point processing (disabled on startup)
99 void EnableProcessing();
100
101 // disable sync point processing
102 void DisableProcessing();
103
104 // remove the execution trace of all sync points
105 void ClearTrace();
106
107 // triggered by TEST_SYNC_POINT, blocking execution until all predecessors
108 // are executed.
11fdf7f2 109 // And/or call registered callback function, with argument `cb_arg`
7c673cae
FG
110 void Process(const std::string& point, void* cb_arg = nullptr);
111
112 // TODO: it might be useful to provide a function that blocks until all
113 // sync points are cleared.
114
11fdf7f2
TL
115 // We want this to be public so we can
116 // subclass the implementation
117 struct Data;
118
7c673cae 119 private:
11fdf7f2
TL
120 // Singleton
121 SyncPoint();
122 Data* impl_;
7c673cae
FG
123};
124
125} // namespace rocksdb
126
127// Use TEST_SYNC_POINT to specify sync points inside code base.
128// Sync points can have happens-after depedency on other sync points,
129// configured at runtime via SyncPoint::LoadDependency. This could be
130// utilized to re-produce race conditions between threads.
131// See TransactionLogIteratorRace in db_test.cc for an example use case.
132// TEST_SYNC_POINT is no op in release build.
133#define TEST_SYNC_POINT(x) rocksdb::SyncPoint::GetInstance()->Process(x)
11fdf7f2
TL
134#define TEST_IDX_SYNC_POINT(x, index) \
135 rocksdb::SyncPoint::GetInstance()->Process(x + std::to_string(index))
7c673cae
FG
136#define TEST_SYNC_POINT_CALLBACK(x, y) \
137 rocksdb::SyncPoint::GetInstance()->Process(x, y)
11fdf7f2
TL
138#define INIT_SYNC_POINT_SINGLETONS() \
139 (void)rocksdb::SyncPoint::GetInstance();
7c673cae 140#endif // NDEBUG