]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_race_tools.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / utilities / transactions / lock / range / range_tree / lib / portability / toku_race_tools.h
1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 #ident "$Id$"
4 /*======
5 This file is part of PerconaFT.
6
7
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9
10 PerconaFT is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License, version 2,
12 as published by the Free Software Foundation.
13
14 PerconaFT is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
21
22 ----------------------------------------
23
24 PerconaFT is free software: you can redistribute it and/or modify
25 it under the terms of the GNU Affero General Public License, version 3,
26 as published by the Free Software Foundation.
27
28 PerconaFT is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU Affero General Public License for more details.
32
33 You should have received a copy of the GNU Affero General Public License
34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
35
36 ----------------------------------------
37
38 Licensed under the Apache License, Version 2.0 (the "License");
39 you may not use this file except in compliance with the License.
40 You may obtain a copy of the License at
41
42 http://www.apache.org/licenses/LICENSE-2.0
43
44 Unless required by applicable law or agreed to in writing, software
45 distributed under the License is distributed on an "AS IS" BASIS,
46 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47 See the License for the specific language governing permissions and
48 limitations under the License.
49 ======= */
50
51 #ident \
52 "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
53
54 #pragma once
55
56 // PORT2: #include <portability/toku_config.h>
57
58 #ifdef HAVE_valgrind
59 #undef USE_VALGRIND
60 #define USE_VALGRIND 1
61 #endif
62
63 #if defined(__linux__) && USE_VALGRIND
64
65 #include <valgrind/drd.h>
66 #include <valgrind/helgrind.h>
67
68 #define TOKU_ANNOTATE_NEW_MEMORY(p, size) ANNOTATE_NEW_MEMORY(p, size)
69 #define TOKU_VALGRIND_HG_ENABLE_CHECKING(p, size) \
70 VALGRIND_HG_ENABLE_CHECKING(p, size)
71 #define TOKU_VALGRIND_HG_DISABLE_CHECKING(p, size) \
72 VALGRIND_HG_DISABLE_CHECKING(p, size)
73 #define TOKU_DRD_IGNORE_VAR(v) DRD_IGNORE_VAR(v)
74 #define TOKU_DRD_STOP_IGNORING_VAR(v) DRD_STOP_IGNORING_VAR(v)
75 #define TOKU_ANNOTATE_IGNORE_READS_BEGIN() ANNOTATE_IGNORE_READS_BEGIN()
76 #define TOKU_ANNOTATE_IGNORE_READS_END() ANNOTATE_IGNORE_READS_END()
77 #define TOKU_ANNOTATE_IGNORE_WRITES_BEGIN() ANNOTATE_IGNORE_WRITES_BEGIN()
78 #define TOKU_ANNOTATE_IGNORE_WRITES_END() ANNOTATE_IGNORE_WRITES_END()
79
80 /*
81 * How to make helgrind happy about tree rotations and new mutex orderings:
82 *
83 * // Tell helgrind that we unlocked it so that the next call doesn't get a
84 * "destroyed a locked mutex" error.
85 * // Tell helgrind that we destroyed the mutex.
86 * VALGRIND_HG_MUTEX_UNLOCK_PRE(&locka);
87 * VALGRIND_HG_MUTEX_DESTROY_PRE(&locka);
88 *
89 * // And recreate it. It would be better to simply be able to say that the
90 * order on these two can now be reversed, because this code forgets all the
91 * ordering information for this mutex.
92 * // Then tell helgrind that we have locked it again.
93 * VALGRIND_HG_MUTEX_INIT_POST(&locka, 0);
94 * VALGRIND_HG_MUTEX_LOCK_POST(&locka);
95 *
96 * When the ordering of two locks changes, we don't need tell Helgrind about do
97 * both locks. Just one is good enough.
98 */
99
100 #define TOKU_VALGRIND_RESET_MUTEX_ORDERING_INFO(mutex) \
101 VALGRIND_HG_MUTEX_UNLOCK_PRE(mutex); \
102 VALGRIND_HG_MUTEX_DESTROY_PRE(mutex); \
103 VALGRIND_HG_MUTEX_INIT_POST(mutex, 0); \
104 VALGRIND_HG_MUTEX_LOCK_POST(mutex);
105
106 #else // !defined(__linux__) || !USE_VALGRIND
107
108 #define NVALGRIND 1
109 #define TOKU_ANNOTATE_NEW_MEMORY(p, size) ((void)0)
110 #define TOKU_VALGRIND_HG_ENABLE_CHECKING(p, size) ((void)0)
111 #define TOKU_VALGRIND_HG_DISABLE_CHECKING(p, size) ((void)0)
112 #define TOKU_DRD_IGNORE_VAR(v)
113 #define TOKU_DRD_STOP_IGNORING_VAR(v)
114 #define TOKU_ANNOTATE_IGNORE_READS_BEGIN() ((void)0)
115 #define TOKU_ANNOTATE_IGNORE_READS_END() ((void)0)
116 #define TOKU_ANNOTATE_IGNORE_WRITES_BEGIN() ((void)0)
117 #define TOKU_ANNOTATE_IGNORE_WRITES_END() ((void)0)
118 #define TOKU_VALGRIND_RESET_MUTEX_ORDERING_INFO(mutex)
119 #undef RUNNING_ON_VALGRIND
120 #define RUNNING_ON_VALGRIND (0U)
121 #endif
122
123 // Valgrind 3.10.1 (and previous versions).
124 // Problems with VALGRIND_HG_DISABLE_CHECKING and VALGRIND_HG_ENABLE_CHECKING.
125 // Helgrind's implementation of disable and enable checking causes false races
126 // to be reported. In addition, the race report does not include ANY
127 // information about the code that uses the helgrind disable and enable
128 // functions. Therefore, it is very difficult to figure out the cause of the
129 // race. DRD does implement the disable and enable functions.
130
131 // Problems with ANNOTATE_IGNORE_READS.
132 // Helgrind does not implement ignore reads.
133 // Annotate ignore reads is the way to inform DRD to ignore racy reads.
134
135 // FT code uses unsafe reads in several places. These unsafe reads have been
136 // noted as valid since they use the toku_unsafe_fetch function. Unfortunately,
137 // this causes helgrind to report erroneous data races which makes use of
138 // helgrind problematic.
139
140 // Unsafely fetch and return a `T' from src, telling drd to ignore
141 // racey access to src for the next sizeof(*src) bytes
142 template <typename T>
143 T toku_unsafe_fetch(T *src) {
144 if (0)
145 TOKU_VALGRIND_HG_DISABLE_CHECKING(src,
146 sizeof *src); // disabled, see comment
147 TOKU_ANNOTATE_IGNORE_READS_BEGIN();
148 T r = *src;
149 TOKU_ANNOTATE_IGNORE_READS_END();
150 if (0)
151 TOKU_VALGRIND_HG_ENABLE_CHECKING(src,
152 sizeof *src); // disabled, see comment
153 return r;
154 }
155
156 template <typename T>
157 T toku_unsafe_fetch(T &src) {
158 return toku_unsafe_fetch(&src);
159 }
160
161 // Unsafely set a `T' value into *dest from src, telling drd to ignore
162 // racey access to dest for the next sizeof(*dest) bytes
163 template <typename T>
164 void toku_unsafe_set(T *dest, const T src) {
165 if (0)
166 TOKU_VALGRIND_HG_DISABLE_CHECKING(dest,
167 sizeof *dest); // disabled, see comment
168 TOKU_ANNOTATE_IGNORE_WRITES_BEGIN();
169 *dest = src;
170 TOKU_ANNOTATE_IGNORE_WRITES_END();
171 if (0)
172 TOKU_VALGRIND_HG_ENABLE_CHECKING(dest,
173 sizeof *dest); // disabled, see comment
174 }
175
176 template <typename T>
177 void toku_unsafe_set(T &dest, const T src) {
178 toku_unsafe_set(&dest, src);
179 }