/root/doris/be/src/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 | | * --- |
31 | | * Author: Kostya Serebryany |
32 | | */ |
33 | | |
34 | | /* This file defines dynamic annotations for use with dynamic analysis |
35 | | tool such as valgrind, PIN, etc. |
36 | | |
37 | | Dynamic annotation is a source code annotation that affects |
38 | | the generated code (that is, the annotation is not a comment). |
39 | | Each such annotation is attached to a particular |
40 | | instruction and/or to a particular object (address) in the program. |
41 | | |
42 | | The annotations that should be used by users are macros in all upper-case |
43 | | (e.g., ANNOTATE_NEW_MEMORY). |
44 | | |
45 | | Actual implementation of these macros may differ depending on the |
46 | | dynamic analysis tool being used. |
47 | | |
48 | | See http://code.google.com/p/data-race-test/ for more information. |
49 | | |
50 | | This file supports the following dynamic analysis tools: |
51 | | - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). |
52 | | Macros are defined empty. |
53 | | - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). |
54 | | Macros are defined as calls to non-inlinable empty functions |
55 | | that are intercepted by Valgrind. */ |
56 | | |
57 | | #ifndef __DYNAMIC_ANNOTATIONS_H__ |
58 | | #define __DYNAMIC_ANNOTATIONS_H__ |
59 | | |
60 | | #ifndef DYNAMIC_ANNOTATIONS_ENABLED |
61 | | #define DYNAMIC_ANNOTATIONS_ENABLED 0 |
62 | | #endif |
63 | | |
64 | | #if DYNAMIC_ANNOTATIONS_ENABLED != 0 |
65 | | |
66 | | /* ------------------------------------------------------------- |
67 | | Annotations useful when implementing condition variables such as CondVar, |
68 | | using conditional critical sections (Await/LockWhen) and when constructing |
69 | | user-defined synchronization mechanisms. |
70 | | |
71 | | The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can |
72 | | be used to define happens-before arcs in user-defined synchronization |
73 | | mechanisms: the race detector will infer an arc from the former to the |
74 | | latter when they share the same argument pointer. |
75 | | |
76 | | Example 1 (reference counting): |
77 | | |
78 | | void Unref() { |
79 | | ANNOTATE_HAPPENS_BEFORE(&refcount_); |
80 | | if (AtomicDecrementByOne(&refcount_) == 0) { |
81 | | ANNOTATE_HAPPENS_AFTER(&refcount_); |
82 | | delete this; |
83 | | } |
84 | | } |
85 | | |
86 | | Example 2 (message queue): |
87 | | |
88 | | void MyQueue::Put(Type *e) { |
89 | | MutexLock lock(&mu_); |
90 | | ANNOTATE_HAPPENS_BEFORE(e); |
91 | | PutElementIntoMyQueue(e); |
92 | | } |
93 | | |
94 | | Type *MyQueue::Get() { |
95 | | MutexLock lock(&mu_); |
96 | | Type *e = GetElementFromMyQueue(); |
97 | | ANNOTATE_HAPPENS_AFTER(e); |
98 | | return e; |
99 | | } |
100 | | |
101 | | Note: when possible, please use the existing reference counting and message |
102 | | queue implementations instead of inventing new ones. */ |
103 | | |
104 | | /* Report that wait on the condition variable at address "cv" has succeeded |
105 | | and the lock at address "lock" is held. */ |
106 | | #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) |
107 | | |
108 | | /* Report that wait on the condition variable at "cv" has succeeded. Variant |
109 | | w/o lock. */ |
110 | | #define ANNOTATE_CONDVAR_WAIT(cv) AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) |
111 | | |
112 | | /* Report that we are about to signal on the condition variable at address |
113 | | "cv". */ |
114 | | #define ANNOTATE_CONDVAR_SIGNAL(cv) AnnotateCondVarSignal(__FILE__, __LINE__, cv) |
115 | | |
116 | | /* Report that we are about to signal_all on the condition variable at "cv". */ |
117 | | #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) |
118 | | |
119 | | /* Annotations for user-defined synchronization mechanisms. */ |
120 | | #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj) |
121 | | #define ANNOTATE_HAPPENS_AFTER(obj) ANNOTATE_CONDVAR_WAIT(obj) |
122 | | |
123 | | /* Report that the bytes in the range [pointer, pointer+size) are about |
124 | | to be published safely. The race checker will create a happens-before |
125 | | arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to |
126 | | subsequent accesses to this memory. |
127 | | Note: this annotation may not work properly if the race detector uses |
128 | | sampling, i.e. does not observe all memory accesses. |
129 | | */ |
130 | | #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ |
131 | | AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) |
132 | | |
133 | | /* DEPRECATED. Don't use it. */ |
134 | | #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \ |
135 | | AnnotateUnpublishMemoryRange(__FILE__, __LINE__, pointer, size) |
136 | | |
137 | | /* DEPRECATED. Don't use it. */ |
138 | | #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size) \ |
139 | | do { \ |
140 | | ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \ |
141 | | ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size); \ |
142 | | } while (0) |
143 | | |
144 | | /* Instruct the tool to create a happens-before arc between mu->Unlock() and |
145 | | mu->Lock(). This annotation may slow down the race detector and hide real |
146 | | races. Normally it is used only when it would be difficult to annotate each |
147 | | of the mutex's critical sections individually using the annotations above. |
148 | | This annotation makes sense only for hybrid race detectors. For pure |
149 | | happens-before detectors this is a no-op. For more details see |
150 | | http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ |
151 | | #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) |
152 | | |
153 | | /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */ |
154 | | #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) |
155 | | |
156 | | /* ------------------------------------------------------------- |
157 | | Annotations useful when defining memory allocators, or when memory that |
158 | | was protected in one way starts to be protected in another. */ |
159 | | |
160 | | /* Report that a new memory at "address" of size "size" has been allocated. |
161 | | This might be used when the memory has been retrieved from a free list and |
162 | | is about to be reused, or when a the locking discipline for a variable |
163 | | changes. */ |
164 | | #define ANNOTATE_NEW_MEMORY(address, size) AnnotateNewMemory(__FILE__, __LINE__, address, size) |
165 | | |
166 | | /* ------------------------------------------------------------- |
167 | | Annotations useful when defining FIFO queues that transfer data between |
168 | | threads. */ |
169 | | |
170 | | /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at |
171 | | address "pcq" has been created. The ANNOTATE_PCQ_* annotations |
172 | | should be used only for FIFO queues. For non-FIFO queues use |
173 | | ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */ |
174 | | #define ANNOTATE_PCQ_CREATE(pcq) AnnotatePCQCreate(__FILE__, __LINE__, pcq) |
175 | | |
176 | | /* Report that the queue at address "pcq" is about to be destroyed. */ |
177 | | #define ANNOTATE_PCQ_DESTROY(pcq) AnnotatePCQDestroy(__FILE__, __LINE__, pcq) |
178 | | |
179 | | /* Report that we are about to put an element into a FIFO queue at address |
180 | | "pcq". */ |
181 | | #define ANNOTATE_PCQ_PUT(pcq) AnnotatePCQPut(__FILE__, __LINE__, pcq) |
182 | | |
183 | | /* Report that we've just got an element from a FIFO queue at address "pcq". */ |
184 | | #define ANNOTATE_PCQ_GET(pcq) AnnotatePCQGet(__FILE__, __LINE__, pcq) |
185 | | |
186 | | /* ------------------------------------------------------------- |
187 | | Annotations that suppress errors. It is usually better to express the |
188 | | program's synchronization using the other annotations, but these can |
189 | | be used when all else fails. */ |
190 | | |
191 | | /* Report that we may have a benign race at "pointer", with size |
192 | | "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the |
193 | | point where "pointer" has been allocated, preferably close to the point |
194 | | where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ |
195 | | #define ANNOTATE_BENIGN_RACE(pointer, description) \ |
196 | | AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, sizeof(*(pointer)), description) |
197 | | |
198 | | /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to |
199 | | the memory range [address, address+size). */ |
200 | | #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ |
201 | | AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) |
202 | | |
203 | | /* Request the analysis tool to ignore all reads in the current thread |
204 | | until ANNOTATE_IGNORE_READS_END is called. |
205 | | Useful to ignore intentional racey reads, while still checking |
206 | | other reads and all writes. |
207 | | See also ANNOTATE_UNPROTECTED_READ. */ |
208 | | #define ANNOTATE_IGNORE_READS_BEGIN() AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
209 | | |
210 | | /* Stop ignoring reads. */ |
211 | | #define ANNOTATE_IGNORE_READS_END() AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
212 | | |
213 | | /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ |
214 | | #define ANNOTATE_IGNORE_WRITES_BEGIN() AnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
215 | | |
216 | | /* Stop ignoring writes. */ |
217 | | #define ANNOTATE_IGNORE_WRITES_END() AnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
218 | | |
219 | | /* Start ignoring all memory accesses (reads and writes). */ |
220 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
221 | | do { \ |
222 | | ANNOTATE_IGNORE_READS_BEGIN(); \ |
223 | | ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
224 | | } while (0) |
225 | | |
226 | | /* Stop ignoring all memory accesses. */ |
227 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
228 | | do { \ |
229 | | ANNOTATE_IGNORE_WRITES_END(); \ |
230 | | ANNOTATE_IGNORE_READS_END(); \ |
231 | | } while (0) |
232 | | |
233 | | /* Start ignoring all synchronization until ANNOTATE_IGNORE_SYNC_END |
234 | | is called. */ |
235 | | #define ANNOTATE_IGNORE_SYNC_BEGIN() AnnotateIgnoreSyncBegin(__FILE__, __LINE__) |
236 | | |
237 | | /* Stop ignoring all synchronization. */ |
238 | | #define ANNOTATE_IGNORE_SYNC_END() AnnotateIgnoreSyncEnd(__FILE__, __LINE__) |
239 | | |
240 | | /* Enable (enable!=0) or disable (enable==0) race detection for all threads. |
241 | | This annotation could be useful if you want to skip expensive race analysis |
242 | | during some period of program execution, e.g. during initialization. */ |
243 | | #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ |
244 | | AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) |
245 | | |
246 | | /* ------------------------------------------------------------- |
247 | | Annotations useful for debugging. */ |
248 | | |
249 | | /* Request to trace every access to "address". */ |
250 | | #define ANNOTATE_TRACE_MEMORY(address) AnnotateTraceMemory(__FILE__, __LINE__, address) |
251 | | |
252 | | /* Report the current thread name to a race detector. */ |
253 | | #define ANNOTATE_THREAD_NAME(name) AnnotateThreadName(__FILE__, __LINE__, name) |
254 | | |
255 | | /* ------------------------------------------------------------- |
256 | | Annotations useful when implementing locks. They are not |
257 | | normally needed by modules that merely use locks. |
258 | | The "lock" argument is a pointer to the lock object. */ |
259 | | |
260 | | /* Report that a lock has been created at address "lock". */ |
261 | | #define ANNOTATE_RWLOCK_CREATE(lock) AnnotateRWLockCreate(__FILE__, __LINE__, lock) |
262 | | |
263 | | /* Report that a linker initialized lock has been created at address "lock". |
264 | | */ |
265 | | #ifdef THREAD_SANITIZER |
266 | | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) AnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) |
267 | | #else |
268 | | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) |
269 | | #endif |
270 | | |
271 | | /* Report that the lock at address "lock" is about to be destroyed. */ |
272 | | #define ANNOTATE_RWLOCK_DESTROY(lock) AnnotateRWLockDestroy(__FILE__, __LINE__, lock) |
273 | | |
274 | | /* Report that the lock at address "lock" has been acquired. |
275 | | is_w=1 for writer lock, is_w=0 for reader lock. */ |
276 | | #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) |
277 | | |
278 | | /* Report that the lock at address "lock" is about to be released. */ |
279 | | #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) |
280 | | |
281 | | /* ------------------------------------------------------------- |
282 | | Annotations useful when implementing barriers. They are not |
283 | | normally needed by modules that merely use barriers. |
284 | | The "barrier" argument is a pointer to the barrier object. */ |
285 | | |
286 | | /* Report that the "barrier" has been initialized with initial "count". |
287 | | If 'reinitialization_allowed' is true, initialization is allowed to happen |
288 | | multiple times w/o calling barrier_destroy() */ |
289 | | #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ |
290 | | AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, reinitialization_allowed) |
291 | | |
292 | | /* Report that we are about to enter barrier_wait("barrier"). */ |
293 | | #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) |
294 | | |
295 | | /* Report that we just exited barrier_wait("barrier"). */ |
296 | | #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) |
297 | | |
298 | | /* Report that the "barrier" has been destroyed. */ |
299 | | #define ANNOTATE_BARRIER_DESTROY(barrier) AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) |
300 | | |
301 | | /* ------------------------------------------------------------- |
302 | | Annotations useful for testing race detectors. */ |
303 | | |
304 | | /* Report that we expect a race on the variable at "address". |
305 | | Use only in unit tests for a race detector. */ |
306 | | #define ANNOTATE_EXPECT_RACE(address, description) \ |
307 | | AnnotateExpectRace(__FILE__, __LINE__, address, description) |
308 | | |
309 | | /* A no-op. Insert where you like to test the interceptors. */ |
310 | | #define ANNOTATE_NO_OP(arg) AnnotateNoOp(__FILE__, __LINE__, arg) |
311 | | |
312 | | /* Force the race detector to flush its state. The actual effect depends on |
313 | | * the implementation of the detector. */ |
314 | | #define ANNOTATE_FLUSH_STATE() AnnotateFlushState(__FILE__, __LINE__) |
315 | | |
316 | | #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
317 | | |
318 | | #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ |
319 | | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) /* empty */ |
320 | | #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ |
321 | | #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ |
322 | | #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ |
323 | | #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ |
324 | | #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ |
325 | | #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ |
326 | | #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ |
327 | | #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ |
328 | | #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */ |
329 | | #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ |
330 | | #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ |
331 | | #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ |
332 | | #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */ |
333 | | #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ |
334 | | #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ |
335 | | #define ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ |
336 | | #define ANNOTATE_PCQ_CREATE(pcq) /* empty */ |
337 | | #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */ |
338 | | #define ANNOTATE_PCQ_PUT(pcq) /* empty */ |
339 | | #define ANNOTATE_PCQ_GET(pcq) /* empty */ |
340 | | #define ANNOTATE_NEW_MEMORY(address, size) /* empty */ |
341 | | #define ANNOTATE_EXPECT_RACE(address, description) /* empty */ |
342 | | #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ |
343 | | #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ |
344 | | #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ |
345 | | #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ |
346 | | #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ |
347 | | #define ANNOTATE_THREAD_NAME(name) /* empty */ |
348 | | #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ |
349 | | #define ANNOTATE_IGNORE_READS_END() /* empty */ |
350 | | #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ |
351 | | #define ANNOTATE_IGNORE_WRITES_END() /* empty */ |
352 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ |
353 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ |
354 | | #define ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ |
355 | | #define ANNOTATE_IGNORE_SYNC_END() /* empty */ |
356 | | #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ |
357 | | #define ANNOTATE_NO_OP(arg) /* empty */ |
358 | | #define ANNOTATE_FLUSH_STATE() /* empty */ |
359 | | |
360 | | #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
361 | | |
362 | | /* Macro definitions for GCC attributes that allow static thread safety |
363 | | analysis to recognize and use some of the dynamic annotations as |
364 | | escape hatches. |
365 | | TODO(user): remove the check for __SUPPORT_DYN_ANNOTATION__ once the |
366 | | default crosstool/GCC supports these GCC attributes. */ |
367 | | |
368 | | #define ANNOTALYSIS_STATIC_INLINE |
369 | | #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ; |
370 | | #define ANNOTALYSIS_IGNORE_READS_BEGIN |
371 | | #define ANNOTALYSIS_IGNORE_READS_END |
372 | | #define ANNOTALYSIS_IGNORE_WRITES_BEGIN |
373 | | #define ANNOTALYSIS_IGNORE_WRITES_END |
374 | | #define ANNOTALYSIS_UNPROTECTED_READ |
375 | | |
376 | | #if defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__)) |
377 | | |
378 | | #if DYNAMIC_ANNOTATIONS_ENABLED == 0 |
379 | | #define ANNOTALYSIS_ONLY 1 |
380 | | #undef ANNOTALYSIS_STATIC_INLINE |
381 | | #define ANNOTALYSIS_STATIC_INLINE inline //static inline |
382 | | #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
383 | | #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY \ |
384 | | { \ |
385 | | (void)file; \ |
386 | | (void)line; \ |
387 | | } |
388 | | #endif |
389 | | |
390 | | /* Only emit attributes when annotalysis is enabled. */ |
391 | | #if defined(__SUPPORT_TS_ANNOTATION__) && defined(__SUPPORT_DYN_ANNOTATION__) |
392 | | #undef ANNOTALYSIS_IGNORE_READS_BEGIN |
393 | | #define ANNOTALYSIS_IGNORE_READS_BEGIN __attribute__((ignore_reads_begin)) |
394 | | #undef ANNOTALYSIS_IGNORE_READS_END |
395 | | #define ANNOTALYSIS_IGNORE_READS_END __attribute__((ignore_reads_end)) |
396 | | #undef ANNOTALYSIS_IGNORE_WRITES_BEGIN |
397 | | #define ANNOTALYSIS_IGNORE_WRITES_BEGIN __attribute__((ignore_writes_begin)) |
398 | | #undef ANNOTALYSIS_IGNORE_WRITES_END |
399 | | #define ANNOTALYSIS_IGNORE_WRITES_END __attribute__((ignore_writes_end)) |
400 | | #undef ANNOTALYSIS_UNPROTECTED_READ |
401 | | #define ANNOTALYSIS_UNPROTECTED_READ __attribute__((unprotected_read)) |
402 | | #endif |
403 | | |
404 | | #endif // defined(__GNUC__) && (!defined(SWIG)) && (!defined(__clang__)) |
405 | | |
406 | | /* TODO(user) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the |
407 | | appropriate feature ID. */ |
408 | | #if defined(__clang__) && (!defined(SWIG)) && defined(__CLANG_SUPPORT_DYN_ANNOTATION__) |
409 | | |
410 | | /* TODO(user) -- The exclusive lock here ignores writes as well, but |
411 | | allows INGORE_READS_AND_WRITES to work properly. */ |
412 | | #undef ANNOTALYSIS_IGNORE_READS_BEGIN |
413 | | #define ANNOTALYSIS_IGNORE_READS_BEGIN __attribute__((exclusive_lock_function("*"))) |
414 | | #undef ANNOTALYSIS_IGNORE_READS_END |
415 | | #define ANNOTALYSIS_IGNORE_READS_END __attribute__((unlock_function("*"))) |
416 | | |
417 | | #if DYNAMIC_ANNOTATIONS_ENABLED == 0 |
418 | | /* Turn on certain macros for static analysis, even if dynamic annotations are |
419 | | not enabled. */ |
420 | | #define CLANG_ANNOTALYSIS_ONLY 1 |
421 | | |
422 | | #undef ANNOTALYSIS_STATIC_INLINE |
423 | | #define ANNOTALYSIS_STATIC_INLINE inline //static inline |
424 | | #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
425 | | #define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY \ |
426 | | { \ |
427 | | (void)file; \ |
428 | | (void)line; \ |
429 | | } |
430 | | |
431 | | #endif /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
432 | | #endif /* defined(__clang__) && (!defined(SWIG)) */ |
433 | | |
434 | | /* Use the macros above rather than using these functions directly. */ |
435 | | #ifdef __cplusplus |
436 | | extern "C" { |
437 | | #endif |
438 | | void AnnotateRWLockCreate(const char* file, int line, const volatile void* lock); |
439 | | void AnnotateRWLockCreateStatic(const char* file, int line, const volatile void* lock); |
440 | | void AnnotateRWLockDestroy(const char* file, int line, const volatile void* lock); |
441 | | void AnnotateRWLockAcquired(const char* file, int line, const volatile void* lock, long is_w); |
442 | | void AnnotateRWLockReleased(const char* file, int line, const volatile void* lock, long is_w); |
443 | | void AnnotateBarrierInit(const char* file, int line, const volatile void* barrier, long count, |
444 | | long reinitialization_allowed); |
445 | | void AnnotateBarrierWaitBefore(const char* file, int line, const volatile void* barrier); |
446 | | void AnnotateBarrierWaitAfter(const char* file, int line, const volatile void* barrier); |
447 | | void AnnotateBarrierDestroy(const char* file, int line, const volatile void* barrier); |
448 | | void AnnotateCondVarWait(const char* file, int line, const volatile void* cv, |
449 | | const volatile void* lock); |
450 | | void AnnotateCondVarSignal(const char* file, int line, const volatile void* cv); |
451 | | void AnnotateCondVarSignalAll(const char* file, int line, const volatile void* cv); |
452 | | void AnnotatePublishMemoryRange(const char* file, int line, const volatile void* address, |
453 | | long size); |
454 | | void AnnotateUnpublishMemoryRange(const char* file, int line, const volatile void* address, |
455 | | long size); |
456 | | void AnnotatePCQCreate(const char* file, int line, const volatile void* pcq); |
457 | | void AnnotatePCQDestroy(const char* file, int line, const volatile void* pcq); |
458 | | void AnnotatePCQPut(const char* file, int line, const volatile void* pcq); |
459 | | void AnnotatePCQGet(const char* file, int line, const volatile void* pcq); |
460 | | void AnnotateNewMemory(const char* file, int line, const volatile void* address, long size); |
461 | | void AnnotateExpectRace(const char* file, int line, const volatile void* address, |
462 | | const char* description); |
463 | | void AnnotateBenignRace(const char* file, int line, const volatile void* address, |
464 | | const char* description); |
465 | | void AnnotateBenignRaceSized(const char* file, int line, const volatile void* address, long size, |
466 | | const char* description); |
467 | | void AnnotateMutexIsUsedAsCondVar(const char* file, int line, const volatile void* mu); |
468 | | void AnnotateTraceMemory(const char* file, int line, const volatile void* arg); |
469 | | void AnnotateThreadName(const char* file, int line, const char* name); |
470 | | ANNOTALYSIS_STATIC_INLINE |
471 | | void AnnotateIgnoreReadsBegin(const char* file, int line) |
472 | | ANNOTALYSIS_IGNORE_READS_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ANNOTALYSIS_STATIC_INLINE |
473 | | void AnnotateIgnoreReadsEnd(const char* file, int line) ANNOTALYSIS_IGNORE_READS_END |
474 | | ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ANNOTALYSIS_STATIC_INLINE |
475 | | void AnnotateIgnoreWritesBegin(const char* file, int line) ANNOTALYSIS_IGNORE_WRITES_BEGIN |
476 | | ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ANNOTALYSIS_STATIC_INLINE |
477 | | void AnnotateIgnoreWritesEnd(const char* file, int line) |
478 | | ANNOTALYSIS_IGNORE_WRITES_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
479 | | void AnnotateIgnoreSyncBegin(const char* file, int line); |
480 | | void AnnotateIgnoreSyncEnd(const char* file, int line); |
481 | | void AnnotateEnableRaceDetection(const char* file, int line, int enable); |
482 | | void AnnotateNoOp(const char* file, int line, const volatile void* arg); |
483 | | void AnnotateFlushState(const char* file, int line); |
484 | | |
485 | | /* AddressSanitizer annotations from LLVM asan_interface.h */ |
486 | | |
487 | | #if defined(__SANITIZE_ADDRESS__) || defined(ADDRESS_SANITIZER) |
488 | | // Marks memory region [addr, addr+size) as unaddressable. |
489 | | // This memory must be previously allocated by the user program. Accessing |
490 | | // addresses in this region from instrumented code is forbidden until |
491 | | // this region is unpoisoned. This function is not guaranteed to poison |
492 | | // the whole region - it may poison only subregion of [addr, addr+size) due |
493 | | // to ASan alignment restrictions. |
494 | | // Method is NOT thread-safe in the sense that no two threads can |
495 | | // (un)poison memory in the same memory region simultaneously. |
496 | | void __asan_poison_memory_region(void const volatile* addr, size_t size); |
497 | | // Marks memory region [addr, addr+size) as addressable. |
498 | | // This memory must be previously allocated by the user program. Accessing |
499 | | // addresses in this region is allowed until this region is poisoned again. |
500 | | // This function may unpoison a superregion of [addr, addr+size) due to |
501 | | // ASan alignment restrictions. |
502 | | // Method is NOT thread-safe in the sense that no two threads can |
503 | | // (un)poison memory in the same memory region simultaneously. |
504 | | void __asan_unpoison_memory_region(void const volatile* addr, size_t size); |
505 | | |
506 | | // User code should use macros instead of functions. |
507 | 2.01M | #define ASAN_POISON_MEMORY_REGION(addr, size) __asan_poison_memory_region((addr), (size)) |
508 | 1.80M | #define ASAN_UNPOISON_MEMORY_REGION(addr, size) __asan_unpoison_memory_region((addr), (size)) |
509 | | #else |
510 | | #define ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size)) |
511 | | #define ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size)) |
512 | | #endif |
513 | | |
514 | | // Sets the callback to be called right before death on error. |
515 | | // Passing 0 will unset the callback. |
516 | | void __asan_set_death_callback(void (*callback)(void)); |
517 | | |
518 | | #if defined(__SANITIZE_ADDRESS__) || defined(ADDRESS_SANITIZER) |
519 | | #define ASAN_SET_DEATH_CALLBACK(cb) __asan_set_death_callback((cb)) |
520 | | #else |
521 | | #define ASAN_SET_DEATH_CALLBACK(cb) ((void)(cb)) |
522 | | #endif |
523 | | |
524 | | #ifdef __cplusplus |
525 | | } |
526 | | #endif |
527 | | |
528 | | #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) |
529 | | |
530 | | /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. |
531 | | |
532 | | Instead of doing |
533 | | ANNOTATE_IGNORE_READS_BEGIN(); |
534 | | ... = x; |
535 | | ANNOTATE_IGNORE_READS_END(); |
536 | | one can use |
537 | | ... = ANNOTATE_UNPROTECTED_READ(x); */ |
538 | | template <class T> |
539 | | T ANNOTATE_UNPROTECTED_READ(const volatile T& x) ANNOTALYSIS_UNPROTECTED_READ { |
540 | | ANNOTATE_IGNORE_READS_BEGIN(); |
541 | | T res = x; |
542 | | ANNOTATE_IGNORE_READS_END(); |
543 | | return res; |
544 | | } |
545 | | /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ |
546 | | #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ |
547 | | namespace { \ |
548 | | class static_var##_annotator { \ |
549 | | public: \ |
550 | | static_var##_annotator() { \ |
551 | | ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \ |
552 | | #static_var ": " description); \ |
553 | | } \ |
554 | | }; \ |
555 | | static static_var##_annotator the##static_var##_annotator; \ |
556 | | } |
557 | | #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
558 | | |
559 | | #define ANNOTATE_UNPROTECTED_READ(x) (x) |
560 | | #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ |
561 | | |
562 | | #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
563 | | |
564 | | /* Annotalysis, a GCC based static analyzer, is able to understand and use |
565 | | some of the dynamic annotations defined in this file. However, dynamic |
566 | | annotations are usually disabled in the opt mode (to avoid additional |
567 | | runtime overheads) while Annotalysis only works in the opt mode. |
568 | | In order for Annotalysis to use these dynamic annotations when they |
569 | | are disabled, we re-define these annotations here. Note that unlike the |
570 | | original macro definitions above, these macros are expanded to calls to |
571 | | static inline functions so that the compiler will be able to remove the |
572 | | calls after the analysis. */ |
573 | | |
574 | | #ifdef ANNOTALYSIS_ONLY |
575 | | |
576 | | #undef ANNOTALYSIS_ONLY |
577 | | |
578 | | /* Undefine and re-define the macros that the static analyzer understands. */ |
579 | | #undef ANNOTATE_IGNORE_READS_BEGIN |
580 | | #define ANNOTATE_IGNORE_READS_BEGIN() AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
581 | | |
582 | | #undef ANNOTATE_IGNORE_READS_END |
583 | | #define ANNOTATE_IGNORE_READS_END() AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
584 | | |
585 | | #undef ANNOTATE_IGNORE_WRITES_BEGIN |
586 | | #define ANNOTATE_IGNORE_WRITES_BEGIN() AnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
587 | | |
588 | | #undef ANNOTATE_IGNORE_WRITES_END |
589 | | #define ANNOTATE_IGNORE_WRITES_END() AnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
590 | | |
591 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN |
592 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
593 | | do { \ |
594 | | ANNOTATE_IGNORE_READS_BEGIN(); \ |
595 | | ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
596 | | } while (0) |
597 | | |
598 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_END |
599 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
600 | | do { \ |
601 | | ANNOTATE_IGNORE_WRITES_END(); \ |
602 | | ANNOTATE_IGNORE_READS_END(); \ |
603 | | } while (0) |
604 | | |
605 | | #if defined(__cplusplus) |
606 | | #undef ANNOTATE_UNPROTECTED_READ |
607 | | template <class T> |
608 | | T ANNOTATE_UNPROTECTED_READ(const volatile T& x) ANNOTALYSIS_UNPROTECTED_READ { |
609 | | ANNOTATE_IGNORE_READS_BEGIN(); |
610 | | T res = x; |
611 | | ANNOTATE_IGNORE_READS_END(); |
612 | | return res; |
613 | | } |
614 | | #endif /* __cplusplus */ |
615 | | |
616 | | #endif /* ANNOTALYSIS_ONLY */ |
617 | | |
618 | | #ifdef CLANG_ANNOTALYSIS_ONLY |
619 | | |
620 | | #undef CLANG_ANNOTALYSIS_ONLY |
621 | | |
622 | | /* Turn on macros that the static analyzer understands. These should be on |
623 | | * even if dynamic annotations are off. */ |
624 | | |
625 | | #undef ANNOTATE_IGNORE_READS_BEGIN |
626 | | #define ANNOTATE_IGNORE_READS_BEGIN() AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
627 | | |
628 | | #undef ANNOTATE_IGNORE_READS_END |
629 | | #define ANNOTATE_IGNORE_READS_END() AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
630 | | |
631 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN |
632 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
633 | | do { \ |
634 | | ANNOTATE_IGNORE_READS_BEGIN(); \ |
635 | | ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
636 | | } while (0) |
637 | | |
638 | | #undef ANNOTATE_IGNORE_READS_AND_WRITES_END |
639 | | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
640 | | do { \ |
641 | | ANNOTATE_IGNORE_WRITES_END(); \ |
642 | | ANNOTATE_IGNORE_READS_END(); \ |
643 | | } while (0) |
644 | | |
645 | | #if defined(__cplusplus) |
646 | | #undef ANNOTATE_UNPROTECTED_READ |
647 | | template <class T> |
648 | | T ANNOTATE_UNPROTECTED_READ(const volatile T& x) { |
649 | | ANNOTATE_IGNORE_READS_BEGIN(); |
650 | | T res = x; |
651 | | ANNOTATE_IGNORE_READS_END(); |
652 | | return res; |
653 | | } |
654 | | #endif |
655 | | |
656 | | #endif /* CLANG_ANNOTALYSIS_ONLY */ |
657 | | |
658 | | /* Undefine the macros intended only in this file. */ |
659 | | #undef ANNOTALYSIS_STATIC_INLINE |
660 | | #undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY |
661 | | |
662 | | #endif /* __DYNAMIC_ANNOTATIONS_H__ */ |