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