/Users/deen/code/yugabyte-db/src/yb/gutil/dynamic_annotations.h
Line | Count | Source |
1 | | /* Copyright (c) 2008-2009, Google Inc. |
2 | | * All rights reserved. |
3 | | * |
4 | | * Redistribution and use in source and binary forms, with or without |
5 | | * modification, are permitted provided that the following conditions are |
6 | | * met: |
7 | | * |
8 | | * * Redistributions of source code must retain the above copyright |
9 | | * notice, this list of conditions and the following disclaimer. |
10 | | * * Redistributions in binary form must reproduce the above |
11 | | * copyright notice, this list of conditions and the following disclaimer |
12 | | * in the documentation and/or other materials provided with the |
13 | | * distribution. |
14 | | * * Neither the name of Google Inc. nor the names of its |
15 | | * contributors may be used to endorse or promote products derived from |
16 | | * this software without specific prior written permission. |
17 | | * |
18 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 | | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 | | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 | | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 | | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 | | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 | | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 | | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 | | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | | * |
30 | | * The following only applies to changes made to this file as part of YugaByte development. |
31 | | * |
32 | | * Portions Copyright (c) YugaByte, Inc. |
33 | | * |
34 | | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
35 | | * in compliance with the License. You may obtain a copy of the License at |
36 | | * |
37 | | * http://www.apache.org/licenses/LICENSE-2.0 |
38 | | * |
39 | | * Unless required by applicable law or agreed to in writing, software distributed under the License |
40 | | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
41 | | * or implied. See the License for the specific language governing permissions and limitations |
42 | | * under the License. |
43 | | * |
44 | | * |
45 | | * --- |
46 | | * Author: Kostya Serebryany |
47 | | */ |
48 | | |
49 | | /* This file defines dynamic annotations for use with dynamic analysis |
50 | | tool such as valgrind, PIN, etc. |
51 | | |
52 | | Dynamic annotation is a source code annotation that affects |
53 | | the generated code (that is, the annotation is not a comment). |
54 | | Each such annotation is attached to a particular |
55 | | instruction and/or to a particular object (address) in the program. |
56 | | |
57 | | The annotations that should be used by users are macros in all upper-case |
58 | | (e.g., ANNOTATE_NEW_MEMORY). |
59 | | |
60 | | Actual implementation of these macros may differ depending on the |
61 | | dynamic analysis tool being used. |
62 | | |
63 | | See http://code.google.com/p/data-race-test/ for more information. |
64 | | |
65 | | This file supports the following dynamic analysis tools: |
66 | | - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). |
67 | | Macros are defined empty. |
68 | | - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). |
69 | | Macros are defined as calls to non-inlinable empty functions |
70 | | that are intercepted by Valgrind. */ |
71 | | |
72 | | #ifndef YB_GUTIL_DYNAMIC_ANNOTATIONS_H |
73 | | #define YB_GUTIL_DYNAMIC_ANNOTATIONS_H |
74 | | |
75 | | #include <stddef.h> |
76 | | |
77 | | #ifdef __cplusplus |
78 | | #include <utility> |
79 | | #endif |
80 | | |
81 | | #ifndef DYNAMIC_ANNOTATIONS_ENABLED |
82 | | # define DYNAMIC_ANNOTATIONS_ENABLED 0 |
83 | | #endif |
84 | | |
85 | | #if DYNAMIC_ANNOTATIONS_ENABLED != 0 |
86 | | |
87 | | /* ------------------------------------------------------------- |
88 | | Annotations useful when implementing condition variables such as CondVar, |
89 | | using conditional critical sections (Await/LockWhen) and when constructing |
90 | | user-defined synchronization mechanisms. |
91 | | |
92 | | The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can |
93 | | be used to define happens-before arcs in user-defined synchronization |
94 | | mechanisms: the race detector will infer an arc from the former to the |
95 | | latter when they share the same argument pointer. |
96 | | |
97 | | Example 1 (reference counting): |
98 | | |
99 | | void Unref() { |
100 | | ANNOTATE_HAPPENS_BEFORE(&refcount_); |
101 | | if (AtomicDecrementByOne(&refcount_) == 0) { |
102 | | ANNOTATE_HAPPENS_AFTER(&refcount_); |
103 | | delete this; |
104 | | } |
105 | | } |
106 | | |
107 | | Example 2 (message queue): |
108 | | |
109 | | void MyQueue::Put(Type *e) { |
110 | | MutexLock lock(&mu_); |
111 | | ANNOTATE_HAPPENS_BEFORE(e); |
112 | | PutElementIntoMyQueue(e); |
113 | | } |
114 | | |
115 | | Type *MyQueue::Get() { |
116 | | MutexLock lock(&mu_); |
117 | | Type *e = GetElementFromMyQueue(); |
118 | | ANNOTATE_HAPPENS_AFTER(e); |
119 | | return e; |
120 | | } |
121 | | |
122 | | Note: when possible, please use the existing reference counting and message |
123 | | queue implementations instead of inventing new ones. */ |
124 | | |
125 | | /* Report that wait on the condition variable at address "cv" has succeeded |
126 | | and the lock at address "lock" is held. */ |
127 | | #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ |
128 | | AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) |
129 | | |
130 | | /* Report that wait on the condition variable at "cv" has succeeded. Variant |
131 | | w/o lock. */ |
132 | | #define ANNOTATE_CONDVAR_WAIT(cv) \ |
133 | | AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) |
134 | | |
135 | | /* Report that we are about to signal on the condition variable at address |
136 | | "cv". */ |
137 | | #define ANNOTATE_CONDVAR_SIGNAL(cv) \ |
138 | | AnnotateCondVarSignal(__FILE__, __LINE__, cv) |
139 | | |
140 | | /* Report that we are about to signal_all on the condition variable at "cv". */ |
141 | | #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ |
142 | | AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) |
143 | | |
144 | | /* Annotations for user-defined synchronization mechanisms. */ |
145 | | #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj) |
146 | | #define ANNOTATE_HAPPENS_AFTER(obj) ANNOTATE_CONDVAR_WAIT(obj) |
147 | | |
148 | | /* Report that the bytes in the range [pointer, pointer+size) are about |
149 | | to be published safely. The race checker will create a happens-before |
150 | | arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to |
151 | | subsequent accesses to this memory. |
152 | | Note: this annotation may not work properly if the race detector uses |
153 | | sampling, i.e. does not observe all memory accesses. |
154 | | */ |
155 | | #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ |
156 | | AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) |
157 | | |
158 | | /* DEPRECATED. Don't use it. */ |
159 | | #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \ |
160 | | AnnotateUnpublishMemoryRange(__FILE__, __LINE__, pointer, size) |
161 | | |
162 | | /* DEPRECATED. Don't use it. */ |
163 | | #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size) \ |
164 | | do { \ |
165 | | ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \ |
166 | | ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size); \ |
167 | | } while (0) |
168 | | |
169 | | /* Instruct the tool to create a happens-before arc between mu->Unlock() and |
170 | | mu->Lock(). This annotation may slow down the race detector and hide real |
171 | | races. Normally it is used only when it would be difficult to annotate each |
172 | | of the mutex's critical sections individually using the annotations above. |
173 | | This annotation makes sense only for hybrid race detectors. For pure |
174 | | happens-before detectors this is a no-op. For more details see |
175 | | http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ |
176 | | #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ |
177 | | AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) |
178 | | |
179 | | /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */ |
180 | | #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \ |
181 | | AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) |
182 | | |
183 | | /* ------------------------------------------------------------- |
184 | | Annotations useful when defining memory allocators, or when memory that |
185 | | was protected in one way starts to be protected in another. */ |
186 | | |
187 | | /* Report that a new memory at "address" of size "size" has been allocated. |
188 | | This might be used when the memory has been retrieved from a free list and |
189 | | is about to be reused, or when a the locking discipline for a variable |
190 | | changes. */ |
191 | | #define ANNOTATE_NEW_MEMORY(address, size) \ |
192 | | AnnotateNewMemory(__FILE__, __LINE__, address, size) |
193 | | |
194 | | /* ------------------------------------------------------------- |
195 | | Annotations useful when defining FIFO queues that transfer data between |
196 | | threads. */ |
197 | | |
198 | | /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at |
199 | | address "pcq" has been created. The ANNOTATE_PCQ_* annotations |
200 | | should be used only for FIFO queues. For non-FIFO queues use |
201 | | ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */ |
202 | | #define ANNOTATE_PCQ_CREATE(pcq) \ |
203 | | AnnotatePCQCreate(__FILE__, __LINE__, pcq) |
204 | | |
205 | | /* Report that the queue at address "pcq" is about to be destroyed. */ |
206 | | #define ANNOTATE_PCQ_DESTROY(pcq) \ |
207 | | AnnotatePCQDestroy(__FILE__, __LINE__, pcq) |
208 | | |
209 | | /* Report that we are about to put an element into a FIFO queue at address |
210 | | "pcq". */ |
211 | | #define ANNOTATE_PCQ_PUT(pcq) \ |
212 | | AnnotatePCQPut(__FILE__, __LINE__, pcq) |
213 | | |
214 | | /* Report that we've just got an element from a FIFO queue at address "pcq". */ |
215 | | #define ANNOTATE_PCQ_GET(pcq) \ |
216 | | AnnotatePCQGet(__FILE__, __LINE__, pcq) |
217 | | |
218 | | /* ------------------------------------------------------------- |
219 | | Annotations that suppress errors. It is usually better to express the |
220 | | program's synchronization using the other annotations, but these can |
221 | | be used when all else fails. */ |
222 | | |
223 | | /* Report that we may have a benign race at "pointer", with size |
224 | | "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the |
225 | | point where "pointer" has been allocated, preferably close to the point |
226 | | where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ |
227 | | #define ANNOTATE_BENIGN_RACE(pointer, description) \ |
228 | | AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ |
229 | | sizeof(*(pointer)), description) |
230 | | |
231 | | /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to |
232 | | the memory range [address, address+size). */ |
233 | | #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ |
234 | | AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) |
235 | | |
236 | | /* Request the analysis tool to ignore all reads in the current thread |
237 | | until ANNOTATE_IGNORE_READS_END is called. |
238 | | Useful to ignore intentional racey reads, while still checking |
239 | | other reads and all writes. |
240 | | See also ANNOTATE_UNPROTECTED_READ. */ |
241 | | #define ANNOTATE_IGNORE_READS_BEGIN() \ |
242 | | AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
243 | | |
244 | | /* Stop ignoring reads. */ |
245 | | #define ANNOTATE_IGNORE_READS_END() \ |
246 | | AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
247 | | |
248 | | /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ |
249 | | #define ANNOTATE_IGNORE_WRITES_BEGIN() \ |
250 | | AnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
251 | | |
252 | | /* Stop ignoring writes. */ |
253 | | #define ANNOTATE_IGNORE_WRITES_END() \ |
254 | | AnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
255 | | |
256 | | /* Start ignoring all memory accesses (reads and writes). */ |
257 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
258 | | do {\ |
259 | | ANNOTATE_IGNORE_READS_BEGIN();\ |
260 | | ANNOTATE_IGNORE_WRITES_BEGIN();\ |
261 | | }while(0)\ |
262 | | |
263 | | /* Stop ignoring all memory accesses. */ |
264 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
265 | | do {\ |
266 | | ANNOTATE_IGNORE_WRITES_END();\ |
267 | | ANNOTATE_IGNORE_READS_END();\ |
268 | | }while(0)\ |
269 | | |
270 | | /* Start ignoring all synchronization until ANNOTATE_IGNORE_SYNC_END |
271 | | is called. */ |
272 | | #define ANNOTATE_IGNORE_SYNC_BEGIN() \ |
273 | | AnnotateIgnoreSyncBegin(__FILE__, __LINE__) |
274 | | |
275 | | /* Stop ignoring all synchronization. */ |
276 | | #define ANNOTATE_IGNORE_SYNC_END() \ |
277 | | AnnotateIgnoreSyncEnd(__FILE__, __LINE__) |
278 | | |
279 | | /* Enable (enable!=0) or disable (enable==0) race detection for all threads. |
280 | | This annotation could be useful if you want to skip expensive race analysis |
281 | | during some period of program execution, e.g. during initialization. */ |
282 | | #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ |
283 | | AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) |
284 | | |
285 | | /* ------------------------------------------------------------- |
286 | | Annotations useful for debugging. */ |
287 | | |
288 | | /* Request to trace every access to "address". */ |
289 | | #define ANNOTATE_TRACE_MEMORY(address) \ |
290 | | AnnotateTraceMemory(__FILE__, __LINE__, address) |
291 | | |
292 | | /* Report the current thread name to a race detector. */ |
293 | | #define ANNOTATE_THREAD_NAME(name) \ |
294 | | AnnotateThreadName(__FILE__, __LINE__, name) |
295 | | |
296 | | /* ------------------------------------------------------------- |
297 | | Annotations useful when implementing locks. They are not |
298 | | normally needed by modules that merely use locks. |
299 | | The "lock" argument is a pointer to the lock object. */ |
300 | | |
301 | | /* Report that a lock has been created at address "lock". */ |
302 | | #define ANNOTATE_RWLOCK_CREATE(lock) \ |
303 | | AnnotateRWLockCreate(__FILE__, __LINE__, lock) |
304 | | |
305 | | /* Report that a linker initialized lock has been created at address "lock". |
306 | | */ |
307 | | #ifdef THREAD_SANITIZER |
308 | | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ |
309 | | AnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) |
310 | | #else |
311 | | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) |
312 | | #endif |
313 | | |
314 | | /* Report that the lock at address "lock" is about to be destroyed. */ |
315 | | #define ANNOTATE_RWLOCK_DESTROY(lock) \ |
316 | | AnnotateRWLockDestroy(__FILE__, __LINE__, lock) |
317 | | |
318 | | /* Report that the lock at address "lock" has been acquired. |
319 | | is_w=1 for writer lock, is_w=0 for reader lock. */ |
320 | | #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ |
321 | | AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) |
322 | | |
323 | | /* Report that the lock at address "lock" is about to be released. */ |
324 | | #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ |
325 | | AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) |
326 | | |
327 | | /* ------------------------------------------------------------- |
328 | | Annotations useful when implementing barriers. They are not |
329 | | normally needed by modules that merely use barriers. |
330 | | The "barrier" argument is a pointer to the barrier object. */ |
331 | | |
332 | | /* Report that the "barrier" has been initialized with initial "count". |
333 | | If 'reinitialization_allowed' is true, initialization is allowed to happen |
334 | | multiple times w/o calling barrier_destroy() */ |
335 | | #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ |
336 | | AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \ |
337 | | reinitialization_allowed) |
338 | | |
339 | | /* Report that we are about to enter barrier_wait("barrier"). */ |
340 | | #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ |
341 | | AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) |
342 | | |
343 | | /* Report that we just exited barrier_wait("barrier"). */ |
344 | | #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ |
345 | | AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) |
346 | | |
347 | | /* Report that the "barrier" has been destroyed. */ |
348 | | #define ANNOTATE_BARRIER_DESTROY(barrier) \ |
349 | | AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) |
350 | | |
351 | | /* ------------------------------------------------------------- |
352 | | Annotations useful for testing race detectors. */ |
353 | | |
354 | | /* Report that we expect a race on the variable at "address". |
355 | | Use only in unit tests for a race detector. */ |
356 | | #define ANNOTATE_EXPECT_RACE(address, description) \ |
357 | | AnnotateExpectRace(__FILE__, __LINE__, address, description) |
358 | | |
359 | | /* A no-op. Insert where you like to test the interceptors. */ |
360 | | #define ANNOTATE_NO_OP(arg) \ |
361 | | AnnotateNoOp(__FILE__, __LINE__, arg) |
362 | | |
363 | | /* Force the race detector to flush its state. The actual effect depends on |
364 | | * the implementation of the detector. */ |
365 | | #define ANNOTATE_FLUSH_STATE() \ |
366 | | AnnotateFlushState(__FILE__, __LINE__) |
367 | | |
368 | | |
369 | | #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
370 | | |
371 | | #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ |
372 | | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) /* empty */ |
373 | | #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ |
374 | | #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ |
375 | | #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ |
376 | | #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ |
377 | | #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ |
378 | | #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ |
379 | | #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ |
380 | | #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ |
381 | | #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */ |
382 | | #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ |
383 | | #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ |
384 | | #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ |
385 | | #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */ |
386 | | #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ |
387 | | #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ |
388 | | #define ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ |
389 | | #define ANNOTATE_PCQ_CREATE(pcq) /* empty */ |
390 | | #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */ |
391 | | #define ANNOTATE_PCQ_PUT(pcq) /* empty */ |
392 | | #define ANNOTATE_PCQ_GET(pcq) /* empty */ |
393 | | #define ANNOTATE_NEW_MEMORY(address, size) /* empty */ |
394 | | #define ANNOTATE_EXPECT_RACE(address, description) /* empty */ |
395 | | #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ |
396 | | #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ |
397 | | #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ |
398 | | #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ |
399 | | #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ |
400 | | #define ANNOTATE_THREAD_NAME(name) /* empty */ |
401 | | #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ |
402 | | #define ANNOTATE_IGNORE_READS_END() /* empty */ |
403 | | #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ |
404 | | #define ANNOTATE_IGNORE_WRITES_END() /* empty */ |
405 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ |
406 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ |
407 | | #define ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ |
408 | | #define ANNOTATE_IGNORE_SYNC_END() /* empty */ |
409 | | #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ |
410 | | #define ANNOTATE_NO_OP(arg) /* empty */ |
411 | | #define ANNOTATE_FLUSH_STATE() /* empty */ |
412 | | |
413 | | #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
414 | | |
415 | | /* Macro definitions for GCC attributes that allow static thread safety |
416 | | analysis to recognize and use some of the dynamic annotations as |
417 | | escape hatches. |
418 | | TODO(user): remove the check for __SUPPORT_DYN_ANNOTATION__ once the |
419 | | default crosstool/GCC supports these GCC attributes. */ |
420 | | |
421 | | #define ANNOTALYSIS_STATIC_INLINE |
422 | | #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ; // NOLINT |
423 | | #define ANNOTALYSIS_IGNORE_READS_BEGIN |
424 | | #define ANNOTALYSIS_IGNORE_READS_END |
425 | | #define ANNOTALYSIS_IGNORE_WRITES_BEGIN |
426 | | #define ANNOTALYSIS_IGNORE_WRITES_END |
427 | | #define ANNOTALYSIS_UNPROTECTED_READ |
428 | | |
429 | | #if defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__)) |
430 | | |
431 | | #if DYNAMIC_ANNOTATIONS_ENABLED == 0 |
432 | | #define ANNOTALYSIS_ONLY 1 |
433 | | #undef ANNOTALYSIS_STATIC_INLINE |
434 | | #define ANNOTALYSIS_STATIC_INLINE static inline |
435 | | #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
436 | | #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY { (void)file; (void)line; } |
437 | | #endif |
438 | | |
439 | | /* Only emit attributes when annotalysis is enabled. */ |
440 | | #if defined(__SUPPORT_TS_ANNOTATION__) && defined(__SUPPORT_DYN_ANNOTATION__) |
441 | | #undef ANNOTALYSIS_IGNORE_READS_BEGIN |
442 | | #define ANNOTALYSIS_IGNORE_READS_BEGIN __attribute__ ((ignore_reads_begin)) |
443 | | #undef ANNOTALYSIS_IGNORE_READS_END |
444 | | #define ANNOTALYSIS_IGNORE_READS_END __attribute__ ((ignore_reads_end)) |
445 | | #undef ANNOTALYSIS_IGNORE_WRITES_BEGIN |
446 | | #define ANNOTALYSIS_IGNORE_WRITES_BEGIN __attribute__ ((ignore_writes_begin)) |
447 | | #undef ANNOTALYSIS_IGNORE_WRITES_END |
448 | | #define ANNOTALYSIS_IGNORE_WRITES_END __attribute__ ((ignore_writes_end)) |
449 | | #undef ANNOTALYSIS_UNPROTECTED_READ |
450 | | #define ANNOTALYSIS_UNPROTECTED_READ __attribute__ ((unprotected_read)) |
451 | | #endif |
452 | | |
453 | | #endif // defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__)) |
454 | | |
455 | | |
456 | | /* TODO(user) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the |
457 | | appropriate feature ID. */ |
458 | | #if defined(__clang__) && (!defined(SWIG)) \ |
459 | | && defined(__CLANG_SUPPORT_DYN_ANNOTATION__) |
460 | | |
461 | | /* TODO(user) -- The exclusive lock here ignores writes as well, but |
462 | | allows INGORE_READS_AND_WRITES to work properly. */ |
463 | | #undef ANNOTALYSIS_IGNORE_READS_BEGIN |
464 | | #define ANNOTALYSIS_IGNORE_READS_BEGIN \ |
465 | | __attribute__((exclusive_lock_function("*"))) |
466 | | #undef ANNOTALYSIS_IGNORE_READS_END |
467 | | #define ANNOTALYSIS_IGNORE_READS_END \ |
468 | | __attribute__((unlock_function("*"))) |
469 | | |
470 | | #if DYNAMIC_ANNOTATIONS_ENABLED == 0 |
471 | | /* Turn on certain macros for static analysis, even if dynamic annotations are |
472 | | not enabled. */ |
473 | | #define CLANG_ANNOTALYSIS_ONLY 1 |
474 | | |
475 | | #undef ANNOTALYSIS_STATIC_INLINE |
476 | | #define ANNOTALYSIS_STATIC_INLINE static inline |
477 | | #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
478 | | #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY { (void)file; (void)line; } |
479 | | |
480 | | #endif /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
481 | | #endif /* defined(__clang__) && (!defined(SWIG)) */ |
482 | | |
483 | | |
484 | | /* Use the macros above rather than using these functions directly. */ |
485 | | #ifdef __cplusplus |
486 | | extern "C" { |
487 | | #endif |
488 | | void AnnotateRWLockCreate(const char *file, int line, void *lock); |
489 | | void AnnotateRWLockCreateStatic(const char *file, int line, void *lock); |
490 | | void AnnotateRWLockDestroy(const char *file, int line, void *lock); |
491 | | void AnnotateRWLockAcquired(const char *file, int line, void *lock, long is_w); // NOLINT |
492 | | void AnnotateRWLockReleased(const char *file, int line, void *lock, long is_w); // NOLINT |
493 | | void AnnotateBarrierInit(const char *file, int line, |
494 | | const volatile void *barrier, long count, // NOLINT |
495 | | long reinitialization_allowed); // NOLINT |
496 | | void AnnotateBarrierWaitBefore(const char *file, int line, |
497 | | const volatile void *barrier); |
498 | | void AnnotateBarrierWaitAfter(const char *file, int line, |
499 | | const volatile void *barrier); |
500 | | void AnnotateBarrierDestroy(const char *file, int line, |
501 | | const volatile void *barrier); |
502 | | void AnnotateCondVarWait(const char *file, int line, |
503 | | const volatile void *cv, |
504 | | const volatile void *lock); |
505 | | void AnnotateCondVarSignal(const char *file, int line, |
506 | | const volatile void *cv); |
507 | | void AnnotateCondVarSignalAll(const char *file, int line, |
508 | | const volatile void *cv); |
509 | | void AnnotatePublishMemoryRange(const char *file, int line, |
510 | | const volatile void *address, |
511 | | long size); // NOLINT |
512 | | void AnnotateUnpublishMemoryRange(const char *file, int line, |
513 | | const volatile void *address, |
514 | | long size); // NOLINT |
515 | | void AnnotatePCQCreate(const char *file, int line, |
516 | | const volatile void *pcq); |
517 | | void AnnotatePCQDestroy(const char *file, int line, |
518 | | const volatile void *pcq); |
519 | | void AnnotatePCQPut(const char *file, int line, |
520 | | const volatile void *pcq); |
521 | | void AnnotatePCQGet(const char *file, int line, |
522 | | const volatile void *pcq); |
523 | | void AnnotateNewMemory(const char *file, int line, void *address, size_t size); |
524 | | void AnnotateExpectRace(const char *file, int line, |
525 | | const volatile void *address, |
526 | | const char *description); |
527 | | void AnnotateBenignRace(const char *file, int line, |
528 | | const volatile void *address, |
529 | | const char *description); |
530 | | void AnnotateBenignRaceSized(const char *file, int line, |
531 | | const volatile void *address, |
532 | | long size, // NOLINT |
533 | | const char *description); |
534 | | void AnnotateMutexIsUsedAsCondVar(const char *file, int line, |
535 | | const volatile void *mu); |
536 | | void AnnotateTraceMemory(const char *file, int line, |
537 | | const volatile void *arg); |
538 | | void AnnotateThreadName(const char *file, int line, |
539 | | const char *name); |
540 | | ANNOTALYSIS_STATIC_INLINE |
541 | | void AnnotateIgnoreReadsBegin(const char *file, int line) |
542 | | ANNOTALYSIS_IGNORE_READS_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
543 | | ANNOTALYSIS_STATIC_INLINE |
544 | | void AnnotateIgnoreReadsEnd(const char *file, int line) |
545 | | ANNOTALYSIS_IGNORE_READS_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
546 | | ANNOTALYSIS_STATIC_INLINE |
547 | | void AnnotateIgnoreWritesBegin(const char *file, int line) |
548 | | ANNOTALYSIS_IGNORE_WRITES_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
549 | | ANNOTALYSIS_STATIC_INLINE |
550 | | void AnnotateIgnoreWritesEnd(const char *file, int line) |
551 | | ANNOTALYSIS_IGNORE_WRITES_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
552 | | void AnnotateIgnoreSyncBegin(const char *file, int line); |
553 | | void AnnotateIgnoreSyncEnd(const char *file, int line); |
554 | | void AnnotateEnableRaceDetection(const char *file, int line, int enable); |
555 | | void AnnotateNoOp(const char *file, int line, |
556 | | const volatile void *arg); |
557 | | void AnnotateFlushState(const char *file, int line); |
558 | | |
559 | | /* Return non-zero value if running under valgrind. |
560 | | |
561 | | If "valgrind.h" is included into dynamic_annotations.c, |
562 | | the regular valgrind mechanism will be used. |
563 | | See http://valgrind.org/docs/manual/manual-core-adv.html about |
564 | | RUNNING_ON_VALGRIND and other valgrind "client requests". |
565 | | The file "valgrind.h" may be obtained by doing |
566 | | svn co svn://svn.valgrind.org/valgrind/trunk/include |
567 | | |
568 | | If for some reason you can't use "valgrind.h" or want to fake valgrind, |
569 | | there are two ways to make this function return non-zero: |
570 | | - Use environment variable: export RUNNING_ON_VALGRIND=1 |
571 | | - Make your tool intercept the function YbRunningOnValgrind() and |
572 | | change its return value. |
573 | | */ |
574 | | int YbRunningOnValgrind(void); |
575 | | |
576 | | /* YbValgrindSlowdown returns: |
577 | | * 1.0, if (YbRunningOnValgrind() == 0) |
578 | | * 50.0, if (YbRunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) |
579 | | * atof(getenv("VALGRIND_SLOWDOWN")) otherwise |
580 | | This function can be used to scale timeout values: |
581 | | EXAMPLE: |
582 | | for (;;) { |
583 | | DoExpensiveBackgroundTask(); |
584 | | SleepForSeconds(5 * YbValgrindSlowdown()); |
585 | | } |
586 | | */ |
587 | | double YbValgrindSlowdown(void); |
588 | | |
589 | | |
590 | | /* AddressSanitizer annotations from LLVM asan_interface.h */ |
591 | | |
592 | | // Marks memory region [addr, addr+size) as unaddressable. |
593 | | // This memory must be previously allocated by the user program. Accessing |
594 | | // addresses in this region from instrumented code is forbidden until |
595 | | // this region is unpoisoned. This function is not guaranteed to poison |
596 | | // the whole region - it may poison only subregion of [addr, addr+size) due |
597 | | // to ASan alignment restrictions. |
598 | | // Method is NOT thread-safe in the sense that no two threads can |
599 | | // (un)poison memory in the same memory region simultaneously. |
600 | | void __asan_poison_memory_region(void const volatile *addr, size_t size); |
601 | | // Marks memory region [addr, addr+size) as addressable. |
602 | | // This memory must be previously allocated by the user program. Accessing |
603 | | // addresses in this region is allowed until this region is poisoned again. |
604 | | // This function may unpoison a superregion of [addr, addr+size) due to |
605 | | // ASan alignment restrictions. |
606 | | // Method is NOT thread-safe in the sense that no two threads can |
607 | | // (un)poison memory in the same memory region simultaneously. |
608 | | void __asan_unpoison_memory_region(void const volatile *addr, size_t size); |
609 | | |
610 | | // User code should use macros instead of functions. |
611 | | #if defined(__SANITIZE_ADDRESS__) || defined(ADDRESS_SANITIZER) |
612 | | #define ASAN_POISON_MEMORY_REGION(addr, size) \ |
613 | | __asan_poison_memory_region((addr), (size)) |
614 | | #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ |
615 | | __asan_unpoison_memory_region((addr), (size)) |
616 | | #else |
617 | | #define ASAN_POISON_MEMORY_REGION(addr, size) \ |
618 | 122M | ((void)(addr), (void)(size)) |
619 | | #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ |
620 | 653M | ((void)(addr), (void)(size)) |
621 | | #endif |
622 | | |
623 | | // Sets the callback to be called right before death on error. |
624 | | // Passing 0 will unset the callback. |
625 | | void __asan_set_death_callback(void (*callback)(void)); |
626 | | |
627 | | #if defined(__SANITIZE_ADDRESS__) || defined(ADDRESS_SANITIZER) |
628 | | #define ASAN_SET_DEATH_CALLBACK(cb) \ |
629 | | __asan_set_death_callback((cb)) |
630 | | #else |
631 | | #define ASAN_SET_DEATH_CALLBACK(cb) \ |
632 | | ((void)(cb)) |
633 | | #endif |
634 | | |
635 | | #ifdef __cplusplus |
636 | | } |
637 | | #endif |
638 | | |
639 | | #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) |
640 | | |
641 | | /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. |
642 | | |
643 | | Instead of doing |
644 | | ANNOTATE_IGNORE_READS_BEGIN(); |
645 | | ... = x; |
646 | | ANNOTATE_IGNORE_READS_END(); |
647 | | one can use |
648 | | ... = ANNOTATE_UNPROTECTED_READ(x); */ |
649 | | template <class T> |
650 | | inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) // NOLINT |
651 | | ANNOTALYSIS_UNPROTECTED_READ { |
652 | | ANNOTATE_IGNORE_READS_BEGIN(); |
653 | | T res = x; |
654 | | ANNOTATE_IGNORE_READS_END(); |
655 | | return res; |
656 | | } |
657 | | /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ |
658 | | #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ |
659 | | namespace { \ |
660 | | class static_var ## _annotator { \ |
661 | | public: \ |
662 | | static_var ## _annotator() { \ |
663 | | ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ |
664 | | sizeof(static_var), \ |
665 | | # static_var ": " description); \ |
666 | | } \ |
667 | | }; \ |
668 | | static static_var ## _annotator the ## static_var ## _annotator;\ |
669 | | } // namespace |
670 | | |
671 | | template <class T> |
672 | | class UnprotectedWriter { |
673 | | public: |
674 | | explicit UnprotectedWriter(T* t) : t_(t) {} |
675 | | |
676 | | UnprotectedWriter(const UnprotectedWriter&) = default; |
677 | | void operator=(const UnprotectedWriter&) = delete; |
678 | | |
679 | | void operator=(const T& t) const { |
680 | | ANNOTATE_IGNORE_WRITES_BEGIN(); |
681 | | *t_ = t; |
682 | | ANNOTATE_IGNORE_WRITES_END(); |
683 | | } |
684 | | |
685 | | void operator=(T&& t) const { |
686 | | ANNOTATE_IGNORE_WRITES_BEGIN(); |
687 | | *t_ = std::move(t); |
688 | | ANNOTATE_IGNORE_WRITES_END(); |
689 | | } |
690 | | |
691 | | private: |
692 | | T* t_; |
693 | | }; |
694 | | |
695 | | template <class T> |
696 | | auto ANNOTATE_UNPROTECTED_WRITE(T& t) { // NOLINT |
697 | | return UnprotectedWriter<T>(&t); |
698 | | } |
699 | | |
700 | | #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
701 | | |
702 | 10.7G | #define ANNOTATE_UNPROTECTED_READ(x) (x) |
703 | 1.42k | #define ANNOTATE_UNPROTECTED_WRITE(x) (x) |
704 | | #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ |
705 | | |
706 | | #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
707 | | |
708 | | /* Annotalysis, a GCC based static analyzer, is able to understand and use |
709 | | some of the dynamic annotations defined in this file. However, dynamic |
710 | | annotations are usually disabled in the opt mode (to avoid additional |
711 | | runtime overheads) while Annotalysis only works in the opt mode. |
712 | | In order for Annotalysis to use these dynamic annotations when they |
713 | | are disabled, we re-define these annotations here. Note that unlike the |
714 | | original macro definitions above, these macros are expanded to calls to |
715 | | static inline functions so that the compiler will be able to remove the |
716 | | calls after the analysis. */ |
717 | | |
718 | | #ifdef ANNOTALYSIS_ONLY |
719 | | |
720 | | #undef ANNOTALYSIS_ONLY |
721 | | |
722 | | /* Undefine and re-define the macros that the static analyzer understands. */ |
723 | | #undef ANNOTATE_IGNORE_READS_BEGIN |
724 | | #define ANNOTATE_IGNORE_READS_BEGIN() \ |
725 | | AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
726 | | |
727 | | #undef ANNOTATE_IGNORE_READS_END |
728 | | #define ANNOTATE_IGNORE_READS_END() \ |
729 | | AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
730 | | |
731 | | #undef ANNOTATE_IGNORE_WRITES_BEGIN |
732 | | #define ANNOTATE_IGNORE_WRITES_BEGIN() \ |
733 | | AnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
734 | | |
735 | | #undef ANNOTATE_IGNORE_WRITES_END |
736 | | #define ANNOTATE_IGNORE_WRITES_END() \ |
737 | | AnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
738 | | |
739 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN |
740 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
741 | | do { \ |
742 | | ANNOTATE_IGNORE_READS_BEGIN(); \ |
743 | | ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
744 | | }while(0) \ |
745 | | |
746 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_END |
747 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
748 | | do { \ |
749 | | ANNOTATE_IGNORE_WRITES_END(); \ |
750 | | ANNOTATE_IGNORE_READS_END(); \ |
751 | | }while(0) \ |
752 | | |
753 | | #if defined(__cplusplus) |
754 | | #undef ANNOTATE_UNPROTECTED_READ |
755 | | template <class T> |
756 | | inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) // NOLINT |
757 | | ANNOTALYSIS_UNPROTECTED_READ { |
758 | | ANNOTATE_IGNORE_READS_BEGIN(); |
759 | | T res = x; |
760 | | ANNOTATE_IGNORE_READS_END(); |
761 | | return res; |
762 | | } |
763 | | #endif /* __cplusplus */ |
764 | | |
765 | | #endif /* ANNOTALYSIS_ONLY */ |
766 | | |
767 | | |
768 | | #ifdef CLANG_ANNOTALYSIS_ONLY |
769 | | |
770 | | #undef CLANG_ANNOTALYSIS_ONLY |
771 | | |
772 | | /* Turn on macros that the static analyzer understands. These should be on |
773 | | * even if dynamic annotations are off. */ |
774 | | |
775 | | #undef ANNOTATE_IGNORE_READS_BEGIN |
776 | | #define ANNOTATE_IGNORE_READS_BEGIN() \ |
777 | | AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
778 | | |
779 | | #undef ANNOTATE_IGNORE_READS_END |
780 | | #define ANNOTATE_IGNORE_READS_END() \ |
781 | | AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
782 | | |
783 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN |
784 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
785 | | do { \ |
786 | | ANNOTATE_IGNORE_READS_BEGIN(); \ |
787 | | ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
788 | | } while (0) \ |
789 | | |
790 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_END |
791 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
792 | | do { \ |
793 | | ANNOTATE_IGNORE_WRITES_END(); \ |
794 | | ANNOTATE_IGNORE_READS_END(); \ |
795 | | } while (0) \ |
796 | | |
797 | | #if defined(__cplusplus) |
798 | | #undef ANNOTATE_UNPROTECTED_READ |
799 | | template <class T> |
800 | | inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { // NOLINT |
801 | | ANNOTATE_IGNORE_READS_BEGIN(); |
802 | | T res = x; |
803 | | ANNOTATE_IGNORE_READS_END(); |
804 | | return res; |
805 | | } |
806 | | #endif |
807 | | |
808 | | #endif /* CLANG_ANNOTALYSIS_ONLY */ |
809 | | |
810 | | |
811 | | /* Undefine the macros intended only in this file. */ |
812 | | #undef ANNOTALYSIS_STATIC_INLINE |
813 | | #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
814 | | |
815 | | #endif /* YB_GUTIL_DYNAMIC_ANNOTATIONS_H */ |