security/sandbox/chromium/base/third_party/dynamic_annotations/dynamic_annotations.h

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial