Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/python3.8/dynamic_annotations.h @ 69:33d812a61356
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 17:55:14 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 69:33d812a61356 |
---|---|
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 * * 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 * Author: Kostya Serebryany | |
28 * Copied to CPython by Jeffrey Yasskin, with all macros renamed to | |
29 * start with _Py_ to avoid colliding with users embedding Python, and | |
30 * with deprecated macros removed. | |
31 */ | |
32 | |
33 /* This file defines dynamic annotations for use with dynamic analysis | |
34 tool such as valgrind, PIN, etc. | |
35 | |
36 Dynamic annotation is a source code annotation that affects | |
37 the generated code (that is, the annotation is not a comment). | |
38 Each such annotation is attached to a particular | |
39 instruction and/or to a particular object (address) in the program. | |
40 | |
41 The annotations that should be used by users are macros in all upper-case | |
42 (e.g., _Py_ANNOTATE_NEW_MEMORY). | |
43 | |
44 Actual implementation of these macros may differ depending on the | |
45 dynamic analysis tool being used. | |
46 | |
47 See http://code.google.com/p/data-race-test/ for more information. | |
48 | |
49 This file supports the following dynamic analysis tools: | |
50 - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). | |
51 Macros are defined empty. | |
52 - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). | |
53 Macros are defined as calls to non-inlinable empty functions | |
54 that are intercepted by Valgrind. */ | |
55 | |
56 #ifndef __DYNAMIC_ANNOTATIONS_H__ | |
57 #define __DYNAMIC_ANNOTATIONS_H__ | |
58 | |
59 #ifndef DYNAMIC_ANNOTATIONS_ENABLED | |
60 # define DYNAMIC_ANNOTATIONS_ENABLED 0 | |
61 #endif | |
62 | |
63 #if DYNAMIC_ANNOTATIONS_ENABLED != 0 | |
64 | |
65 /* ------------------------------------------------------------- | |
66 Annotations useful when implementing condition variables such as CondVar, | |
67 using conditional critical sections (Await/LockWhen) and when constructing | |
68 user-defined synchronization mechanisms. | |
69 | |
70 The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and | |
71 _Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in | |
72 user-defined synchronization mechanisms: the race detector will infer an | |
73 arc from the former to the latter when they share the same argument | |
74 pointer. | |
75 | |
76 Example 1 (reference counting): | |
77 | |
78 void Unref() { | |
79 _Py_ANNOTATE_HAPPENS_BEFORE(&refcount_); | |
80 if (AtomicDecrementByOne(&refcount_) == 0) { | |
81 _Py_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 _Py_ANNOTATE_HAPPENS_BEFORE(e); | |
91 PutElementIntoMyQueue(e); | |
92 } | |
93 | |
94 Type *MyQueue::Get() { | |
95 MutexLock lock(&mu_); | |
96 Type *e = GetElementFromMyQueue(); | |
97 _Py_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 _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ | |
107 AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) | |
108 | |
109 /* Report that wait on the condition variable at "cv" has succeeded. Variant | |
110 w/o lock. */ | |
111 #define _Py_ANNOTATE_CONDVAR_WAIT(cv) \ | |
112 AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) | |
113 | |
114 /* Report that we are about to signal on the condition variable at address | |
115 "cv". */ | |
116 #define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \ | |
117 AnnotateCondVarSignal(__FILE__, __LINE__, cv) | |
118 | |
119 /* Report that we are about to signal_all on the condition variable at "cv". */ | |
120 #define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ | |
121 AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) | |
122 | |
123 /* Annotations for user-defined synchronization mechanisms. */ | |
124 #define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj) | |
125 #define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj) | |
126 | |
127 /* Report that the bytes in the range [pointer, pointer+size) are about | |
128 to be published safely. The race checker will create a happens-before | |
129 arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to | |
130 subsequent accesses to this memory. | |
131 Note: this annotation may not work properly if the race detector uses | |
132 sampling, i.e. does not observe all memory accesses. | |
133 */ | |
134 #define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ | |
135 AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) | |
136 | |
137 /* Instruct the tool to create a happens-before arc between mu->Unlock() and | |
138 mu->Lock(). This annotation may slow down the race detector and hide real | |
139 races. Normally it is used only when it would be difficult to annotate each | |
140 of the mutex's critical sections individually using the annotations above. | |
141 This annotation makes sense only for hybrid race detectors. For pure | |
142 happens-before detectors this is a no-op. For more details see | |
143 http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ | |
144 #define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ | |
145 AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) | |
146 | |
147 /* ------------------------------------------------------------- | |
148 Annotations useful when defining memory allocators, or when memory that | |
149 was protected in one way starts to be protected in another. */ | |
150 | |
151 /* Report that a new memory at "address" of size "size" has been allocated. | |
152 This might be used when the memory has been retrieved from a free list and | |
153 is about to be reused, or when the locking discipline for a variable | |
154 changes. */ | |
155 #define _Py_ANNOTATE_NEW_MEMORY(address, size) \ | |
156 AnnotateNewMemory(__FILE__, __LINE__, address, size) | |
157 | |
158 /* ------------------------------------------------------------- | |
159 Annotations useful when defining FIFO queues that transfer data between | |
160 threads. */ | |
161 | |
162 /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at | |
163 address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should | |
164 be used only for FIFO queues. For non-FIFO queues use | |
165 _Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for | |
166 get). */ | |
167 #define _Py_ANNOTATE_PCQ_CREATE(pcq) \ | |
168 AnnotatePCQCreate(__FILE__, __LINE__, pcq) | |
169 | |
170 /* Report that the queue at address "pcq" is about to be destroyed. */ | |
171 #define _Py_ANNOTATE_PCQ_DESTROY(pcq) \ | |
172 AnnotatePCQDestroy(__FILE__, __LINE__, pcq) | |
173 | |
174 /* Report that we are about to put an element into a FIFO queue at address | |
175 "pcq". */ | |
176 #define _Py_ANNOTATE_PCQ_PUT(pcq) \ | |
177 AnnotatePCQPut(__FILE__, __LINE__, pcq) | |
178 | |
179 /* Report that we've just got an element from a FIFO queue at address "pcq". */ | |
180 #define _Py_ANNOTATE_PCQ_GET(pcq) \ | |
181 AnnotatePCQGet(__FILE__, __LINE__, pcq) | |
182 | |
183 /* ------------------------------------------------------------- | |
184 Annotations that suppress errors. It is usually better to express the | |
185 program's synchronization using the other annotations, but these can | |
186 be used when all else fails. */ | |
187 | |
188 /* Report that we may have a benign race at "pointer", with size | |
189 "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the | |
190 point where "pointer" has been allocated, preferably close to the point | |
191 where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */ | |
192 #define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \ | |
193 AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ | |
194 sizeof(*(pointer)), description) | |
195 | |
196 /* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to | |
197 the memory range [address, address+size). */ | |
198 #define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ | |
199 AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) | |
200 | |
201 /* Request the analysis tool to ignore all reads in the current thread | |
202 until _Py_ANNOTATE_IGNORE_READS_END is called. | |
203 Useful to ignore intentional racey reads, while still checking | |
204 other reads and all writes. | |
205 See also _Py_ANNOTATE_UNPROTECTED_READ. */ | |
206 #define _Py_ANNOTATE_IGNORE_READS_BEGIN() \ | |
207 AnnotateIgnoreReadsBegin(__FILE__, __LINE__) | |
208 | |
209 /* Stop ignoring reads. */ | |
210 #define _Py_ANNOTATE_IGNORE_READS_END() \ | |
211 AnnotateIgnoreReadsEnd(__FILE__, __LINE__) | |
212 | |
213 /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ | |
214 #define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \ | |
215 AnnotateIgnoreWritesBegin(__FILE__, __LINE__) | |
216 | |
217 /* Stop ignoring writes. */ | |
218 #define _Py_ANNOTATE_IGNORE_WRITES_END() \ | |
219 AnnotateIgnoreWritesEnd(__FILE__, __LINE__) | |
220 | |
221 /* Start ignoring all memory accesses (reads and writes). */ | |
222 #define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ | |
223 do {\ | |
224 _Py_ANNOTATE_IGNORE_READS_BEGIN();\ | |
225 _Py_ANNOTATE_IGNORE_WRITES_BEGIN();\ | |
226 }while(0)\ | |
227 | |
228 /* Stop ignoring all memory accesses. */ | |
229 #define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ | |
230 do {\ | |
231 _Py_ANNOTATE_IGNORE_WRITES_END();\ | |
232 _Py_ANNOTATE_IGNORE_READS_END();\ | |
233 }while(0)\ | |
234 | |
235 /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: | |
236 RWLOCK* and CONDVAR*. */ | |
237 #define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \ | |
238 AnnotateIgnoreSyncBegin(__FILE__, __LINE__) | |
239 | |
240 /* Stop ignoring sync events. */ | |
241 #define _Py_ANNOTATE_IGNORE_SYNC_END() \ | |
242 AnnotateIgnoreSyncEnd(__FILE__, __LINE__) | |
243 | |
244 | |
245 /* Enable (enable!=0) or disable (enable==0) race detection for all threads. | |
246 This annotation could be useful if you want to skip expensive race analysis | |
247 during some period of program execution, e.g. during initialization. */ | |
248 #define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ | |
249 AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) | |
250 | |
251 /* ------------------------------------------------------------- | |
252 Annotations useful for debugging. */ | |
253 | |
254 /* Request to trace every access to "address". */ | |
255 #define _Py_ANNOTATE_TRACE_MEMORY(address) \ | |
256 AnnotateTraceMemory(__FILE__, __LINE__, address) | |
257 | |
258 /* Report the current thread name to a race detector. */ | |
259 #define _Py_ANNOTATE_THREAD_NAME(name) \ | |
260 AnnotateThreadName(__FILE__, __LINE__, name) | |
261 | |
262 /* ------------------------------------------------------------- | |
263 Annotations useful when implementing locks. They are not | |
264 normally needed by modules that merely use locks. | |
265 The "lock" argument is a pointer to the lock object. */ | |
266 | |
267 /* Report that a lock has been created at address "lock". */ | |
268 #define _Py_ANNOTATE_RWLOCK_CREATE(lock) \ | |
269 AnnotateRWLockCreate(__FILE__, __LINE__, lock) | |
270 | |
271 /* Report that the lock at address "lock" is about to be destroyed. */ | |
272 #define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \ | |
273 AnnotateRWLockDestroy(__FILE__, __LINE__, lock) | |
274 | |
275 /* Report that the lock at address "lock" has been acquired. | |
276 is_w=1 for writer lock, is_w=0 for reader lock. */ | |
277 #define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ | |
278 AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) | |
279 | |
280 /* Report that the lock at address "lock" is about to be released. */ | |
281 #define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ | |
282 AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) | |
283 | |
284 /* ------------------------------------------------------------- | |
285 Annotations useful when implementing barriers. They are not | |
286 normally needed by modules that merely use barriers. | |
287 The "barrier" argument is a pointer to the barrier object. */ | |
288 | |
289 /* Report that the "barrier" has been initialized with initial "count". | |
290 If 'reinitialization_allowed' is true, initialization is allowed to happen | |
291 multiple times w/o calling barrier_destroy() */ | |
292 #define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ | |
293 AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \ | |
294 reinitialization_allowed) | |
295 | |
296 /* Report that we are about to enter barrier_wait("barrier"). */ | |
297 #define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ | |
298 AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) | |
299 | |
300 /* Report that we just exited barrier_wait("barrier"). */ | |
301 #define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ | |
302 AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) | |
303 | |
304 /* Report that the "barrier" has been destroyed. */ | |
305 #define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \ | |
306 AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) | |
307 | |
308 /* ------------------------------------------------------------- | |
309 Annotations useful for testing race detectors. */ | |
310 | |
311 /* Report that we expect a race on the variable at "address". | |
312 Use only in unit tests for a race detector. */ | |
313 #define _Py_ANNOTATE_EXPECT_RACE(address, description) \ | |
314 AnnotateExpectRace(__FILE__, __LINE__, address, description) | |
315 | |
316 /* A no-op. Insert where you like to test the interceptors. */ | |
317 #define _Py_ANNOTATE_NO_OP(arg) \ | |
318 AnnotateNoOp(__FILE__, __LINE__, arg) | |
319 | |
320 /* Force the race detector to flush its state. The actual effect depends on | |
321 * the implementation of the detector. */ | |
322 #define _Py_ANNOTATE_FLUSH_STATE() \ | |
323 AnnotateFlushState(__FILE__, __LINE__) | |
324 | |
325 | |
326 #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ | |
327 | |
328 #define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */ | |
329 #define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ | |
330 #define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ | |
331 #define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ | |
332 #define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ | |
333 #define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ | |
334 #define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ | |
335 #define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ | |
336 #define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ | |
337 #define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */ | |
338 #define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ | |
339 #define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ | |
340 #define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ | |
341 #define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */ | |
342 #define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ | |
343 #define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ | |
344 #define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ | |
345 #define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */ | |
346 #define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */ | |
347 #define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */ | |
348 #define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */ | |
349 #define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */ | |
350 #define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */ | |
351 #define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */ | |
352 #define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ | |
353 #define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ | |
354 #define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ | |
355 #define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */ | |
356 #define _Py_ANNOTATE_THREAD_NAME(name) /* empty */ | |
357 #define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */ | |
358 #define _Py_ANNOTATE_IGNORE_READS_END() /* empty */ | |
359 #define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ | |
360 #define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */ | |
361 #define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ | |
362 #define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ | |
363 #define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ | |
364 #define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */ | |
365 #define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ | |
366 #define _Py_ANNOTATE_NO_OP(arg) /* empty */ | |
367 #define _Py_ANNOTATE_FLUSH_STATE() /* empty */ | |
368 | |
369 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ | |
370 | |
371 /* Use the macros above rather than using these functions directly. */ | |
372 #ifdef __cplusplus | |
373 extern "C" { | |
374 #endif | |
375 void AnnotateRWLockCreate(const char *file, int line, | |
376 const volatile void *lock); | |
377 void AnnotateRWLockDestroy(const char *file, int line, | |
378 const volatile void *lock); | |
379 void AnnotateRWLockAcquired(const char *file, int line, | |
380 const volatile void *lock, long is_w); | |
381 void AnnotateRWLockReleased(const char *file, int line, | |
382 const volatile void *lock, long is_w); | |
383 void AnnotateBarrierInit(const char *file, int line, | |
384 const volatile void *barrier, long count, | |
385 long reinitialization_allowed); | |
386 void AnnotateBarrierWaitBefore(const char *file, int line, | |
387 const volatile void *barrier); | |
388 void AnnotateBarrierWaitAfter(const char *file, int line, | |
389 const volatile void *barrier); | |
390 void AnnotateBarrierDestroy(const char *file, int line, | |
391 const volatile void *barrier); | |
392 void AnnotateCondVarWait(const char *file, int line, | |
393 const volatile void *cv, | |
394 const volatile void *lock); | |
395 void AnnotateCondVarSignal(const char *file, int line, | |
396 const volatile void *cv); | |
397 void AnnotateCondVarSignalAll(const char *file, int line, | |
398 const volatile void *cv); | |
399 void AnnotatePublishMemoryRange(const char *file, int line, | |
400 const volatile void *address, | |
401 long size); | |
402 void AnnotateUnpublishMemoryRange(const char *file, int line, | |
403 const volatile void *address, | |
404 long size); | |
405 void AnnotatePCQCreate(const char *file, int line, | |
406 const volatile void *pcq); | |
407 void AnnotatePCQDestroy(const char *file, int line, | |
408 const volatile void *pcq); | |
409 void AnnotatePCQPut(const char *file, int line, | |
410 const volatile void *pcq); | |
411 void AnnotatePCQGet(const char *file, int line, | |
412 const volatile void *pcq); | |
413 void AnnotateNewMemory(const char *file, int line, | |
414 const volatile void *address, | |
415 long size); | |
416 void AnnotateExpectRace(const char *file, int line, | |
417 const volatile void *address, | |
418 const char *description); | |
419 void AnnotateBenignRace(const char *file, int line, | |
420 const volatile void *address, | |
421 const char *description); | |
422 void AnnotateBenignRaceSized(const char *file, int line, | |
423 const volatile void *address, | |
424 long size, | |
425 const char *description); | |
426 void AnnotateMutexIsUsedAsCondVar(const char *file, int line, | |
427 const volatile void *mu); | |
428 void AnnotateTraceMemory(const char *file, int line, | |
429 const volatile void *arg); | |
430 void AnnotateThreadName(const char *file, int line, | |
431 const char *name); | |
432 void AnnotateIgnoreReadsBegin(const char *file, int line); | |
433 void AnnotateIgnoreReadsEnd(const char *file, int line); | |
434 void AnnotateIgnoreWritesBegin(const char *file, int line); | |
435 void AnnotateIgnoreWritesEnd(const char *file, int line); | |
436 void AnnotateEnableRaceDetection(const char *file, int line, int enable); | |
437 void AnnotateNoOp(const char *file, int line, | |
438 const volatile void *arg); | |
439 void AnnotateFlushState(const char *file, int line); | |
440 | |
441 /* Return non-zero value if running under valgrind. | |
442 | |
443 If "valgrind.h" is included into dynamic_annotations.c, | |
444 the regular valgrind mechanism will be used. | |
445 See http://valgrind.org/docs/manual/manual-core-adv.html about | |
446 RUNNING_ON_VALGRIND and other valgrind "client requests". | |
447 The file "valgrind.h" may be obtained by doing | |
448 svn co svn://svn.valgrind.org/valgrind/trunk/include | |
449 | |
450 If for some reason you can't use "valgrind.h" or want to fake valgrind, | |
451 there are two ways to make this function return non-zero: | |
452 - Use environment variable: export RUNNING_ON_VALGRIND=1 | |
453 - Make your tool intercept the function RunningOnValgrind() and | |
454 change its return value. | |
455 */ | |
456 int RunningOnValgrind(void); | |
457 | |
458 #ifdef __cplusplus | |
459 } | |
460 #endif | |
461 | |
462 #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) | |
463 | |
464 /* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. | |
465 | |
466 Instead of doing | |
467 _Py_ANNOTATE_IGNORE_READS_BEGIN(); | |
468 ... = x; | |
469 _Py_ANNOTATE_IGNORE_READS_END(); | |
470 one can use | |
471 ... = _Py_ANNOTATE_UNPROTECTED_READ(x); */ | |
472 template <class T> | |
473 inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) { | |
474 _Py_ANNOTATE_IGNORE_READS_BEGIN(); | |
475 T res = x; | |
476 _Py_ANNOTATE_IGNORE_READS_END(); | |
477 return res; | |
478 } | |
479 /* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ | |
480 #define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ | |
481 namespace { \ | |
482 class static_var ## _annotator { \ | |
483 public: \ | |
484 static_var ## _annotator() { \ | |
485 _Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ | |
486 sizeof(static_var), \ | |
487 # static_var ": " description); \ | |
488 } \ | |
489 }; \ | |
490 static static_var ## _annotator the ## static_var ## _annotator;\ | |
491 } | |
492 #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ | |
493 | |
494 #define _Py_ANNOTATE_UNPROTECTED_READ(x) (x) | |
495 #define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ | |
496 | |
497 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ | |
498 | |
499 #endif /* __DYNAMIC_ANNOTATIONS_H__ */ |