|
1 /* Copyright (c) 2011, 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 * * Neither the name of Google Inc. nor the names of its |
|
11 * contributors may be used to endorse or promote products derived from |
|
12 * this software without specific prior written permission. |
|
13 * |
|
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
25 */ |
|
26 |
|
27 /* This file defines dynamic annotations for use with dynamic analysis |
|
28 tool such as valgrind, PIN, etc. |
|
29 |
|
30 Dynamic annotation is a source code annotation that affects |
|
31 the generated code (that is, the annotation is not a comment). |
|
32 Each such annotation is attached to a particular |
|
33 instruction and/or to a particular object (address) in the program. |
|
34 |
|
35 The annotations that should be used by users are macros in all upper-case |
|
36 (e.g., ANNOTATE_NEW_MEMORY). |
|
37 |
|
38 Actual implementation of these macros may differ depending on the |
|
39 dynamic analysis tool being used. |
|
40 |
|
41 See http://code.google.com/p/data-race-test/ for more information. |
|
42 |
|
43 This file supports the following dynamic analysis tools: |
|
44 - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). |
|
45 Macros are defined empty. |
|
46 - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). |
|
47 Macros are defined as calls to non-inlinable empty functions |
|
48 that are intercepted by Valgrind. */ |
|
49 |
|
50 #ifndef __DYNAMIC_ANNOTATIONS_H__ |
|
51 #define __DYNAMIC_ANNOTATIONS_H__ |
|
52 |
|
53 #ifndef DYNAMIC_ANNOTATIONS_PREFIX |
|
54 # define DYNAMIC_ANNOTATIONS_PREFIX |
|
55 #endif |
|
56 |
|
57 #ifndef DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND |
|
58 # define DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND 1 |
|
59 #endif |
|
60 |
|
61 #ifdef DYNAMIC_ANNOTATIONS_WANT_ATTRIBUTE_WEAK |
|
62 # ifdef __GNUC__ |
|
63 # define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK __attribute__((weak)) |
|
64 # else |
|
65 /* TODO(glider): for Windows support we may want to change this macro in order |
|
66 to prepend __declspec(selectany) to the annotations' declarations. */ |
|
67 # error weak annotations are not supported for your compiler |
|
68 # endif |
|
69 #else |
|
70 # define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK |
|
71 #endif |
|
72 |
|
73 /* The following preprocessor magic prepends the value of |
|
74 DYNAMIC_ANNOTATIONS_PREFIX to annotation function names. */ |
|
75 #define DYNAMIC_ANNOTATIONS_GLUE0(A, B) A##B |
|
76 #define DYNAMIC_ANNOTATIONS_GLUE(A, B) DYNAMIC_ANNOTATIONS_GLUE0(A, B) |
|
77 #define DYNAMIC_ANNOTATIONS_NAME(name) \ |
|
78 DYNAMIC_ANNOTATIONS_GLUE(DYNAMIC_ANNOTATIONS_PREFIX, name) |
|
79 |
|
80 #ifndef DYNAMIC_ANNOTATIONS_ENABLED |
|
81 # define DYNAMIC_ANNOTATIONS_ENABLED 0 |
|
82 #endif |
|
83 |
|
84 #if DYNAMIC_ANNOTATIONS_ENABLED != 0 |
|
85 |
|
86 /* ------------------------------------------------------------- |
|
87 Annotations useful when implementing condition variables such as CondVar, |
|
88 using conditional critical sections (Await/LockWhen) and when constructing |
|
89 user-defined synchronization mechanisms. |
|
90 |
|
91 The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can |
|
92 be used to define happens-before arcs in user-defined synchronization |
|
93 mechanisms: the race detector will infer an arc from the former to the |
|
94 latter when they share the same argument pointer. |
|
95 |
|
96 Example 1 (reference counting): |
|
97 |
|
98 void Unref() { |
|
99 ANNOTATE_HAPPENS_BEFORE(&refcount_); |
|
100 if (AtomicDecrementByOne(&refcount_) == 0) { |
|
101 ANNOTATE_HAPPENS_AFTER(&refcount_); |
|
102 delete this; |
|
103 } |
|
104 } |
|
105 |
|
106 Example 2 (message queue): |
|
107 |
|
108 void MyQueue::Put(Type *e) { |
|
109 MutexLock lock(&mu_); |
|
110 ANNOTATE_HAPPENS_BEFORE(e); |
|
111 PutElementIntoMyQueue(e); |
|
112 } |
|
113 |
|
114 Type *MyQueue::Get() { |
|
115 MutexLock lock(&mu_); |
|
116 Type *e = GetElementFromMyQueue(); |
|
117 ANNOTATE_HAPPENS_AFTER(e); |
|
118 return e; |
|
119 } |
|
120 |
|
121 Note: when possible, please use the existing reference counting and message |
|
122 queue implementations instead of inventing new ones. */ |
|
123 |
|
124 /* Report that wait on the condition variable at address "cv" has succeeded |
|
125 and the lock at address "lock" is held. */ |
|
126 #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ |
|
127 DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)(__FILE__, __LINE__, cv, lock) |
|
128 |
|
129 /* Report that wait on the condition variable at "cv" has succeeded. Variant |
|
130 w/o lock. */ |
|
131 #define ANNOTATE_CONDVAR_WAIT(cv) \ |
|
132 DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)(__FILE__, __LINE__, cv, NULL) |
|
133 |
|
134 /* Report that we are about to signal on the condition variable at address |
|
135 "cv". */ |
|
136 #define ANNOTATE_CONDVAR_SIGNAL(cv) \ |
|
137 DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)(__FILE__, __LINE__, cv) |
|
138 |
|
139 /* Report that we are about to signal_all on the condition variable at address |
|
140 "cv". */ |
|
141 #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ |
|
142 DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)(__FILE__, __LINE__, cv) |
|
143 |
|
144 /* Annotations for user-defined synchronization mechanisms. */ |
|
145 #define ANNOTATE_HAPPENS_BEFORE(obj) \ |
|
146 DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)(__FILE__, __LINE__, obj) |
|
147 #define ANNOTATE_HAPPENS_AFTER(obj) \ |
|
148 DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)(__FILE__, __LINE__, obj) |
|
149 |
|
150 /* DEPRECATED. Don't use it. */ |
|
151 #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ |
|
152 DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)(__FILE__, __LINE__, \ |
|
153 pointer, size) |
|
154 |
|
155 /* DEPRECATED. Don't use it. */ |
|
156 #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \ |
|
157 DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)(__FILE__, __LINE__, \ |
|
158 pointer, size) |
|
159 |
|
160 /* DEPRECATED. Don't use it. */ |
|
161 #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size) \ |
|
162 do { \ |
|
163 ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \ |
|
164 ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size); \ |
|
165 } while (0) |
|
166 |
|
167 /* Instruct the tool to create a happens-before arc between mu->Unlock() and |
|
168 mu->Lock(). This annotation may slow down the race detector and hide real |
|
169 races. Normally it is used only when it would be difficult to annotate each |
|
170 of the mutex's critical sections individually using the annotations above. |
|
171 This annotation makes sense only for hybrid race detectors. For pure |
|
172 happens-before detectors this is a no-op. For more details see |
|
173 http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ |
|
174 #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ |
|
175 DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)(__FILE__, __LINE__, \ |
|
176 mu) |
|
177 |
|
178 /* Opposite to ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. |
|
179 Instruct the tool to NOT create h-b arcs between Unlock and Lock, even in |
|
180 pure happens-before mode. For a hybrid mode this is a no-op. */ |
|
181 #define ANNOTATE_NOT_HAPPENS_BEFORE_MUTEX(mu) \ |
|
182 DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)(__FILE__, __LINE__, mu) |
|
183 |
|
184 /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */ |
|
185 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \ |
|
186 DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)(__FILE__, __LINE__, \ |
|
187 mu) |
|
188 |
|
189 /* ------------------------------------------------------------- |
|
190 Annotations useful when defining memory allocators, or when memory that |
|
191 was protected in one way starts to be protected in another. */ |
|
192 |
|
193 /* Report that a new memory at "address" of size "size" has been allocated. |
|
194 This might be used when the memory has been retrieved from a free list and |
|
195 is about to be reused, or when a the locking discipline for a variable |
|
196 changes. */ |
|
197 #define ANNOTATE_NEW_MEMORY(address, size) \ |
|
198 DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)(__FILE__, __LINE__, address, \ |
|
199 size) |
|
200 |
|
201 /* ------------------------------------------------------------- |
|
202 Annotations useful when defining FIFO queues that transfer data between |
|
203 threads. */ |
|
204 |
|
205 /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at |
|
206 address "pcq" has been created. The ANNOTATE_PCQ_* annotations |
|
207 should be used only for FIFO queues. For non-FIFO queues use |
|
208 ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */ |
|
209 #define ANNOTATE_PCQ_CREATE(pcq) \ |
|
210 DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)(__FILE__, __LINE__, pcq) |
|
211 |
|
212 /* Report that the queue at address "pcq" is about to be destroyed. */ |
|
213 #define ANNOTATE_PCQ_DESTROY(pcq) \ |
|
214 DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)(__FILE__, __LINE__, pcq) |
|
215 |
|
216 /* Report that we are about to put an element into a FIFO queue at address |
|
217 "pcq". */ |
|
218 #define ANNOTATE_PCQ_PUT(pcq) \ |
|
219 DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)(__FILE__, __LINE__, pcq) |
|
220 |
|
221 /* Report that we've just got an element from a FIFO queue at address |
|
222 "pcq". */ |
|
223 #define ANNOTATE_PCQ_GET(pcq) \ |
|
224 DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)(__FILE__, __LINE__, pcq) |
|
225 |
|
226 /* ------------------------------------------------------------- |
|
227 Annotations that suppress errors. It is usually better to express the |
|
228 program's synchronization using the other annotations, but these can |
|
229 be used when all else fails. */ |
|
230 |
|
231 /* Report that we may have a benign race at "pointer", with size |
|
232 "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the |
|
233 point where "pointer" has been allocated, preferably close to the point |
|
234 where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ |
|
235 #define ANNOTATE_BENIGN_RACE(pointer, description) \ |
|
236 DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)(__FILE__, __LINE__, \ |
|
237 pointer, sizeof(*(pointer)), description) |
|
238 |
|
239 /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to |
|
240 the memory range [address, address+size). */ |
|
241 #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ |
|
242 DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)(__FILE__, __LINE__, \ |
|
243 address, size, description) |
|
244 |
|
245 /* Request the analysis tool to ignore all reads in the current thread |
|
246 until ANNOTATE_IGNORE_READS_END is called. |
|
247 Useful to ignore intentional racey reads, while still checking |
|
248 other reads and all writes. |
|
249 See also ANNOTATE_UNPROTECTED_READ. */ |
|
250 #define ANNOTATE_IGNORE_READS_BEGIN() \ |
|
251 DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) |
|
252 |
|
253 /* Stop ignoring reads. */ |
|
254 #define ANNOTATE_IGNORE_READS_END() \ |
|
255 DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) |
|
256 |
|
257 /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ |
|
258 #define ANNOTATE_IGNORE_WRITES_BEGIN() \ |
|
259 DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) |
|
260 |
|
261 /* Stop ignoring writes. */ |
|
262 #define ANNOTATE_IGNORE_WRITES_END() \ |
|
263 DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) |
|
264 |
|
265 /* Start ignoring all memory accesses (reads and writes). */ |
|
266 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
|
267 do {\ |
|
268 ANNOTATE_IGNORE_READS_BEGIN();\ |
|
269 ANNOTATE_IGNORE_WRITES_BEGIN();\ |
|
270 }while(0)\ |
|
271 |
|
272 /* Stop ignoring all memory accesses. */ |
|
273 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
|
274 do {\ |
|
275 ANNOTATE_IGNORE_WRITES_END();\ |
|
276 ANNOTATE_IGNORE_READS_END();\ |
|
277 }while(0)\ |
|
278 |
|
279 /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: |
|
280 RWLOCK* and CONDVAR*. */ |
|
281 #define ANNOTATE_IGNORE_SYNC_BEGIN() \ |
|
282 DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)(__FILE__, __LINE__) |
|
283 |
|
284 /* Stop ignoring sync events. */ |
|
285 #define ANNOTATE_IGNORE_SYNC_END() \ |
|
286 DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)(__FILE__, __LINE__) |
|
287 |
|
288 |
|
289 /* Enable (enable!=0) or disable (enable==0) race detection for all threads. |
|
290 This annotation could be useful if you want to skip expensive race analysis |
|
291 during some period of program execution, e.g. during initialization. */ |
|
292 #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ |
|
293 DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)(__FILE__, __LINE__, \ |
|
294 enable) |
|
295 |
|
296 /* ------------------------------------------------------------- |
|
297 Annotations useful for debugging. */ |
|
298 |
|
299 /* Request to trace every access to "address". */ |
|
300 #define ANNOTATE_TRACE_MEMORY(address) \ |
|
301 DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)(__FILE__, __LINE__, address) |
|
302 |
|
303 /* Report the current thread name to a race detector. */ |
|
304 #define ANNOTATE_THREAD_NAME(name) \ |
|
305 DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)(__FILE__, __LINE__, name) |
|
306 |
|
307 /* ------------------------------------------------------------- |
|
308 Annotations useful when implementing locks. They are not |
|
309 normally needed by modules that merely use locks. |
|
310 The "lock" argument is a pointer to the lock object. */ |
|
311 |
|
312 /* Report that a lock has been created at address "lock". */ |
|
313 #define ANNOTATE_RWLOCK_CREATE(lock) \ |
|
314 DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) |
|
315 |
|
316 /* Report that the lock at address "lock" is about to be destroyed. */ |
|
317 #define ANNOTATE_RWLOCK_DESTROY(lock) \ |
|
318 DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) |
|
319 |
|
320 /* Report that the lock at address "lock" has been acquired. |
|
321 is_w=1 for writer lock, is_w=0 for reader lock. */ |
|
322 #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ |
|
323 DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)(__FILE__, __LINE__, lock, \ |
|
324 is_w) |
|
325 |
|
326 /* Report that the lock at address "lock" is about to be released. */ |
|
327 #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ |
|
328 DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)(__FILE__, __LINE__, lock, \ |
|
329 is_w) |
|
330 |
|
331 /* ------------------------------------------------------------- |
|
332 Annotations useful when implementing barriers. They are not |
|
333 normally needed by modules that merely use barriers. |
|
334 The "barrier" argument is a pointer to the barrier object. */ |
|
335 |
|
336 /* Report that the "barrier" has been initialized with initial "count". |
|
337 If 'reinitialization_allowed' is true, initialization is allowed to happen |
|
338 multiple times w/o calling barrier_destroy() */ |
|
339 #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ |
|
340 DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)(__FILE__, __LINE__, barrier, \ |
|
341 count, reinitialization_allowed) |
|
342 |
|
343 /* Report that we are about to enter barrier_wait("barrier"). */ |
|
344 #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ |
|
345 DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)(__FILE__, __LINE__, \ |
|
346 barrier) |
|
347 |
|
348 /* Report that we just exited barrier_wait("barrier"). */ |
|
349 #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ |
|
350 DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)(__FILE__, __LINE__, \ |
|
351 barrier) |
|
352 |
|
353 /* Report that the "barrier" has been destroyed. */ |
|
354 #define ANNOTATE_BARRIER_DESTROY(barrier) \ |
|
355 DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)(__FILE__, __LINE__, \ |
|
356 barrier) |
|
357 |
|
358 /* ------------------------------------------------------------- |
|
359 Annotations useful for testing race detectors. */ |
|
360 |
|
361 /* Report that we expect a race on the variable at "address". |
|
362 Use only in unit tests for a race detector. */ |
|
363 #define ANNOTATE_EXPECT_RACE(address, description) \ |
|
364 DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)(__FILE__, __LINE__, address, \ |
|
365 description) |
|
366 |
|
367 #define ANNOTATE_FLUSH_EXPECTED_RACES() \ |
|
368 DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)(__FILE__, __LINE__) |
|
369 |
|
370 /* A no-op. Insert where you like to test the interceptors. */ |
|
371 #define ANNOTATE_NO_OP(arg) \ |
|
372 DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)(__FILE__, __LINE__, arg) |
|
373 |
|
374 /* Force the race detector to flush its state. The actual effect depends on |
|
375 * the implementation of the detector. */ |
|
376 #define ANNOTATE_FLUSH_STATE() \ |
|
377 DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)(__FILE__, __LINE__) |
|
378 |
|
379 |
|
380 #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
|
381 |
|
382 #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ |
|
383 #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ |
|
384 #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ |
|
385 #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ |
|
386 #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ |
|
387 #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ |
|
388 #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ |
|
389 #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ |
|
390 #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ |
|
391 #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */ |
|
392 #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ |
|
393 #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ |
|
394 #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ |
|
395 #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */ |
|
396 #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ |
|
397 #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ |
|
398 #define ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ |
|
399 #define ANNOTATE_PCQ_CREATE(pcq) /* empty */ |
|
400 #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */ |
|
401 #define ANNOTATE_PCQ_PUT(pcq) /* empty */ |
|
402 #define ANNOTATE_PCQ_GET(pcq) /* empty */ |
|
403 #define ANNOTATE_NEW_MEMORY(address, size) /* empty */ |
|
404 #define ANNOTATE_EXPECT_RACE(address, description) /* empty */ |
|
405 #define ANNOTATE_FLUSH_EXPECTED_RACES(address, description) /* empty */ |
|
406 #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ |
|
407 #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ |
|
408 #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ |
|
409 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ |
|
410 #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ |
|
411 #define ANNOTATE_THREAD_NAME(name) /* empty */ |
|
412 #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ |
|
413 #define ANNOTATE_IGNORE_READS_END() /* empty */ |
|
414 #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ |
|
415 #define ANNOTATE_IGNORE_WRITES_END() /* empty */ |
|
416 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ |
|
417 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ |
|
418 #define ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ |
|
419 #define ANNOTATE_IGNORE_SYNC_END() /* empty */ |
|
420 #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ |
|
421 #define ANNOTATE_NO_OP(arg) /* empty */ |
|
422 #define ANNOTATE_FLUSH_STATE() /* empty */ |
|
423 |
|
424 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
|
425 |
|
426 /* Use the macros above rather than using these functions directly. */ |
|
427 #ifdef __cplusplus |
|
428 extern "C" { |
|
429 #endif |
|
430 |
|
431 |
|
432 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)( |
|
433 const char *file, int line, |
|
434 const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
435 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)( |
|
436 const char *file, int line, |
|
437 const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
438 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)( |
|
439 const char *file, int line, |
|
440 const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
441 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)( |
|
442 const char *file, int line, |
|
443 const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
444 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)( |
|
445 const char *file, int line, const volatile void *barrier, long count, |
|
446 long reinitialization_allowed) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
447 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)( |
|
448 const char *file, int line, |
|
449 const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
450 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)( |
|
451 const char *file, int line, |
|
452 const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
453 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)( |
|
454 const char *file, int line, |
|
455 const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
456 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)( |
|
457 const char *file, int line, const volatile void *cv, |
|
458 const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
459 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)( |
|
460 const char *file, int line, |
|
461 const volatile void *cv) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
462 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)( |
|
463 const char *file, int line, |
|
464 const volatile void *cv) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
465 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)( |
|
466 const char *file, int line, |
|
467 const volatile void *obj) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
468 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)( |
|
469 const char *file, int line, |
|
470 const volatile void *obj) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
471 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)( |
|
472 const char *file, int line, |
|
473 const volatile void *address, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
474 void DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)( |
|
475 const char *file, int line, |
|
476 const volatile void *address, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
477 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)( |
|
478 const char *file, int line, |
|
479 const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
480 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)( |
|
481 const char *file, int line, |
|
482 const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
483 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)( |
|
484 const char *file, int line, |
|
485 const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
486 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)( |
|
487 const char *file, int line, |
|
488 const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
489 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)( |
|
490 const char *file, int line, |
|
491 const volatile void *mem, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
492 void DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)( |
|
493 const char *file, int line, const volatile void *mem, |
|
494 const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
495 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)( |
|
496 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
497 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)( |
|
498 const char *file, int line, const volatile void *mem, |
|
499 const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
500 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)( |
|
501 const char *file, int line, const volatile void *mem, long size, |
|
502 const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
503 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)( |
|
504 const char *file, int line, |
|
505 const volatile void *mu) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
506 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)( |
|
507 const char *file, int line, |
|
508 const volatile void *mu) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
509 void DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)( |
|
510 const char *file, int line, |
|
511 const volatile void *arg) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
512 void DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)( |
|
513 const char *file, int line, |
|
514 const char *name) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
515 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)( |
|
516 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
517 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)( |
|
518 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
519 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)( |
|
520 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
521 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)( |
|
522 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
523 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)( |
|
524 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
525 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)( |
|
526 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
527 void DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)( |
|
528 const char *file, int line, int enable) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
529 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)( |
|
530 const char *file, int line, |
|
531 const volatile void *arg) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
532 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)( |
|
533 const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
534 |
|
535 #if DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 |
|
536 /* Return non-zero value if running under valgrind. |
|
537 |
|
538 If "valgrind.h" is included into dynamic_annotations.c, |
|
539 the regular valgrind mechanism will be used. |
|
540 See http://valgrind.org/docs/manual/manual-core-adv.html about |
|
541 RUNNING_ON_VALGRIND and other valgrind "client requests". |
|
542 The file "valgrind.h" may be obtained by doing |
|
543 svn co svn://svn.valgrind.org/valgrind/trunk/include |
|
544 |
|
545 If for some reason you can't use "valgrind.h" or want to fake valgrind, |
|
546 there are two ways to make this function return non-zero: |
|
547 - Use environment variable: export RUNNING_ON_VALGRIND=1 |
|
548 - Make your tool intercept the function RunningOnValgrind() and |
|
549 change its return value. |
|
550 */ |
|
551 int RunningOnValgrind(void) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
|
552 #endif /* DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 */ |
|
553 |
|
554 #ifdef __cplusplus |
|
555 } |
|
556 #endif |
|
557 |
|
558 #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) |
|
559 |
|
560 /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. |
|
561 |
|
562 Instead of doing |
|
563 ANNOTATE_IGNORE_READS_BEGIN(); |
|
564 ... = x; |
|
565 ANNOTATE_IGNORE_READS_END(); |
|
566 one can use |
|
567 ... = ANNOTATE_UNPROTECTED_READ(x); */ |
|
568 template <class T> |
|
569 inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { |
|
570 ANNOTATE_IGNORE_READS_BEGIN(); |
|
571 T res = x; |
|
572 ANNOTATE_IGNORE_READS_END(); |
|
573 return res; |
|
574 } |
|
575 /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ |
|
576 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ |
|
577 namespace { \ |
|
578 class static_var ## _annotator { \ |
|
579 public: \ |
|
580 static_var ## _annotator() { \ |
|
581 ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ |
|
582 sizeof(static_var), \ |
|
583 # static_var ": " description); \ |
|
584 } \ |
|
585 }; \ |
|
586 static static_var ## _annotator the ## static_var ## _annotator;\ |
|
587 } |
|
588 #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
|
589 |
|
590 #define ANNOTATE_UNPROTECTED_READ(x) (x) |
|
591 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ |
|
592 |
|
593 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
|
594 |
|
595 #endif /* __DYNAMIC_ANNOTATIONS_H__ */ |