| OLD | NEW |
| (Empty) |
| 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__ */ | |
| OLD | NEW |