17db96d56Sopenharmony_ci/* Copyright (c) 2008-2009, Google Inc. 27db96d56Sopenharmony_ci * All rights reserved. 37db96d56Sopenharmony_ci * 47db96d56Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 57db96d56Sopenharmony_ci * modification, are permitted provided that the following conditions are 67db96d56Sopenharmony_ci * met: 77db96d56Sopenharmony_ci * 87db96d56Sopenharmony_ci * * Redistributions of source code must retain the above copyright 97db96d56Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 107db96d56Sopenharmony_ci * * Neither the name of Google Inc. nor the names of its 117db96d56Sopenharmony_ci * contributors may be used to endorse or promote products derived from 127db96d56Sopenharmony_ci * this software without specific prior written permission. 137db96d56Sopenharmony_ci * 147db96d56Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 157db96d56Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 167db96d56Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 177db96d56Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 187db96d56Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 197db96d56Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 207db96d56Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 217db96d56Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 227db96d56Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 237db96d56Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 247db96d56Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 257db96d56Sopenharmony_ci * 267db96d56Sopenharmony_ci * --- 277db96d56Sopenharmony_ci * Author: Kostya Serebryany 287db96d56Sopenharmony_ci * Copied to CPython by Jeffrey Yasskin, with all macros renamed to 297db96d56Sopenharmony_ci * start with _Py_ to avoid colliding with users embedding Python, and 307db96d56Sopenharmony_ci * with deprecated macros removed. 317db96d56Sopenharmony_ci */ 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci/* This file defines dynamic annotations for use with dynamic analysis 347db96d56Sopenharmony_ci tool such as valgrind, PIN, etc. 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ci Dynamic annotation is a source code annotation that affects 377db96d56Sopenharmony_ci the generated code (that is, the annotation is not a comment). 387db96d56Sopenharmony_ci Each such annotation is attached to a particular 397db96d56Sopenharmony_ci instruction and/or to a particular object (address) in the program. 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci The annotations that should be used by users are macros in all upper-case 427db96d56Sopenharmony_ci (e.g., _Py_ANNOTATE_NEW_MEMORY). 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci Actual implementation of these macros may differ depending on the 457db96d56Sopenharmony_ci dynamic analysis tool being used. 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci See https://code.google.com/p/data-race-test/ for more information. 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci This file supports the following dynamic analysis tools: 507db96d56Sopenharmony_ci - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). 517db96d56Sopenharmony_ci Macros are defined empty. 527db96d56Sopenharmony_ci - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). 537db96d56Sopenharmony_ci Macros are defined as calls to non-inlinable empty functions 547db96d56Sopenharmony_ci that are intercepted by Valgrind. */ 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci#ifndef __DYNAMIC_ANNOTATIONS_H__ 577db96d56Sopenharmony_ci#define __DYNAMIC_ANNOTATIONS_H__ 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci#ifndef DYNAMIC_ANNOTATIONS_ENABLED 607db96d56Sopenharmony_ci# define DYNAMIC_ANNOTATIONS_ENABLED 0 617db96d56Sopenharmony_ci#endif 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci#if DYNAMIC_ANNOTATIONS_ENABLED != 0 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci /* ------------------------------------------------------------- 667db96d56Sopenharmony_ci Annotations useful when implementing condition variables such as CondVar, 677db96d56Sopenharmony_ci using conditional critical sections (Await/LockWhen) and when constructing 687db96d56Sopenharmony_ci user-defined synchronization mechanisms. 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and 717db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in 727db96d56Sopenharmony_ci user-defined synchronization mechanisms: the race detector will infer an 737db96d56Sopenharmony_ci arc from the former to the latter when they share the same argument 747db96d56Sopenharmony_ci pointer. 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci Example 1 (reference counting): 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci void Unref() { 797db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_BEFORE(&refcount_); 807db96d56Sopenharmony_ci if (AtomicDecrementByOne(&refcount_) == 0) { 817db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_AFTER(&refcount_); 827db96d56Sopenharmony_ci delete this; 837db96d56Sopenharmony_ci } 847db96d56Sopenharmony_ci } 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci Example 2 (message queue): 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci void MyQueue::Put(Type *e) { 897db96d56Sopenharmony_ci MutexLock lock(&mu_); 907db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_BEFORE(e); 917db96d56Sopenharmony_ci PutElementIntoMyQueue(e); 927db96d56Sopenharmony_ci } 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci Type *MyQueue::Get() { 957db96d56Sopenharmony_ci MutexLock lock(&mu_); 967db96d56Sopenharmony_ci Type *e = GetElementFromMyQueue(); 977db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_AFTER(e); 987db96d56Sopenharmony_ci return e; 997db96d56Sopenharmony_ci } 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci Note: when possible, please use the existing reference counting and message 1027db96d56Sopenharmony_ci queue implementations instead of inventing new ones. */ 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci /* Report that wait on the condition variable at address "cv" has succeeded 1057db96d56Sopenharmony_ci and the lock at address "lock" is held. */ 1067db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ 1077db96d56Sopenharmony_ci AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci /* Report that wait on the condition variable at "cv" has succeeded. Variant 1107db96d56Sopenharmony_ci w/o lock. */ 1117db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_WAIT(cv) \ 1127db96d56Sopenharmony_ci AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci /* Report that we are about to signal on the condition variable at address 1157db96d56Sopenharmony_ci "cv". */ 1167db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \ 1177db96d56Sopenharmony_ci AnnotateCondVarSignal(__FILE__, __LINE__, cv) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci /* Report that we are about to signal_all on the condition variable at "cv". */ 1207db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ 1217db96d56Sopenharmony_ci AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ci /* Annotations for user-defined synchronization mechanisms. */ 1247db96d56Sopenharmony_ci#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj) 1257db96d56Sopenharmony_ci#define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj) 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci /* Report that the bytes in the range [pointer, pointer+size) are about 1287db96d56Sopenharmony_ci to be published safely. The race checker will create a happens-before 1297db96d56Sopenharmony_ci arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to 1307db96d56Sopenharmony_ci subsequent accesses to this memory. 1317db96d56Sopenharmony_ci Note: this annotation may not work properly if the race detector uses 1327db96d56Sopenharmony_ci sampling, i.e. does not observe all memory accesses. 1337db96d56Sopenharmony_ci */ 1347db96d56Sopenharmony_ci#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ 1357db96d56Sopenharmony_ci AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci /* Instruct the tool to create a happens-before arc between mu->Unlock() and 1387db96d56Sopenharmony_ci mu->Lock(). This annotation may slow down the race detector and hide real 1397db96d56Sopenharmony_ci races. Normally it is used only when it would be difficult to annotate each 1407db96d56Sopenharmony_ci of the mutex's critical sections individually using the annotations above. 1417db96d56Sopenharmony_ci This annotation makes sense only for hybrid race detectors. For pure 1427db96d56Sopenharmony_ci happens-before detectors this is a no-op. For more details see 1437db96d56Sopenharmony_ci https://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ 1447db96d56Sopenharmony_ci#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ 1457db96d56Sopenharmony_ci AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci /* ------------------------------------------------------------- 1487db96d56Sopenharmony_ci Annotations useful when defining memory allocators, or when memory that 1497db96d56Sopenharmony_ci was protected in one way starts to be protected in another. */ 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_ci /* Report that a new memory at "address" of size "size" has been allocated. 1527db96d56Sopenharmony_ci This might be used when the memory has been retrieved from a free list and 1537db96d56Sopenharmony_ci is about to be reused, or when the locking discipline for a variable 1547db96d56Sopenharmony_ci changes. */ 1557db96d56Sopenharmony_ci#define _Py_ANNOTATE_NEW_MEMORY(address, size) \ 1567db96d56Sopenharmony_ci AnnotateNewMemory(__FILE__, __LINE__, address, size) 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci /* ------------------------------------------------------------- 1597db96d56Sopenharmony_ci Annotations useful when defining FIFO queues that transfer data between 1607db96d56Sopenharmony_ci threads. */ 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at 1637db96d56Sopenharmony_ci address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should 1647db96d56Sopenharmony_ci be used only for FIFO queues. For non-FIFO queues use 1657db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for 1667db96d56Sopenharmony_ci get). */ 1677db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_CREATE(pcq) \ 1687db96d56Sopenharmony_ci AnnotatePCQCreate(__FILE__, __LINE__, pcq) 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci /* Report that the queue at address "pcq" is about to be destroyed. */ 1717db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_DESTROY(pcq) \ 1727db96d56Sopenharmony_ci AnnotatePCQDestroy(__FILE__, __LINE__, pcq) 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci /* Report that we are about to put an element into a FIFO queue at address 1757db96d56Sopenharmony_ci "pcq". */ 1767db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_PUT(pcq) \ 1777db96d56Sopenharmony_ci AnnotatePCQPut(__FILE__, __LINE__, pcq) 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci /* Report that we've just got an element from a FIFO queue at address "pcq". */ 1807db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_GET(pcq) \ 1817db96d56Sopenharmony_ci AnnotatePCQGet(__FILE__, __LINE__, pcq) 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ci /* ------------------------------------------------------------- 1847db96d56Sopenharmony_ci Annotations that suppress errors. It is usually better to express the 1857db96d56Sopenharmony_ci program's synchronization using the other annotations, but these can 1867db96d56Sopenharmony_ci be used when all else fails. */ 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci /* Report that we may have a benign race at "pointer", with size 1897db96d56Sopenharmony_ci "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the 1907db96d56Sopenharmony_ci point where "pointer" has been allocated, preferably close to the point 1917db96d56Sopenharmony_ci where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */ 1927db96d56Sopenharmony_ci#define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \ 1937db96d56Sopenharmony_ci AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ 1947db96d56Sopenharmony_ci sizeof(*(pointer)), description) 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci /* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to 1977db96d56Sopenharmony_ci the memory range [address, address+size). */ 1987db96d56Sopenharmony_ci#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ 1997db96d56Sopenharmony_ci AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ci /* Request the analysis tool to ignore all reads in the current thread 2027db96d56Sopenharmony_ci until _Py_ANNOTATE_IGNORE_READS_END is called. 2037db96d56Sopenharmony_ci Useful to ignore intentional racey reads, while still checking 2047db96d56Sopenharmony_ci other reads and all writes. 2057db96d56Sopenharmony_ci See also _Py_ANNOTATE_UNPROTECTED_READ. */ 2067db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_BEGIN() \ 2077db96d56Sopenharmony_ci AnnotateIgnoreReadsBegin(__FILE__, __LINE__) 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ci /* Stop ignoring reads. */ 2107db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_END() \ 2117db96d56Sopenharmony_ci AnnotateIgnoreReadsEnd(__FILE__, __LINE__) 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ 2147db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \ 2157db96d56Sopenharmony_ci AnnotateIgnoreWritesBegin(__FILE__, __LINE__) 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci /* Stop ignoring writes. */ 2187db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_WRITES_END() \ 2197db96d56Sopenharmony_ci AnnotateIgnoreWritesEnd(__FILE__, __LINE__) 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci /* Start ignoring all memory accesses (reads and writes). */ 2227db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ 2237db96d56Sopenharmony_ci do {\ 2247db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_BEGIN();\ 2257db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_WRITES_BEGIN();\ 2267db96d56Sopenharmony_ci }while(0)\ 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci /* Stop ignoring all memory accesses. */ 2297db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ 2307db96d56Sopenharmony_ci do {\ 2317db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_WRITES_END();\ 2327db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_END();\ 2337db96d56Sopenharmony_ci }while(0)\ 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: 2367db96d56Sopenharmony_ci RWLOCK* and CONDVAR*. */ 2377db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \ 2387db96d56Sopenharmony_ci AnnotateIgnoreSyncBegin(__FILE__, __LINE__) 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci /* Stop ignoring sync events. */ 2417db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_SYNC_END() \ 2427db96d56Sopenharmony_ci AnnotateIgnoreSyncEnd(__FILE__, __LINE__) 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci /* Enable (enable!=0) or disable (enable==0) race detection for all threads. 2467db96d56Sopenharmony_ci This annotation could be useful if you want to skip expensive race analysis 2477db96d56Sopenharmony_ci during some period of program execution, e.g. during initialization. */ 2487db96d56Sopenharmony_ci#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ 2497db96d56Sopenharmony_ci AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_ci /* ------------------------------------------------------------- 2527db96d56Sopenharmony_ci Annotations useful for debugging. */ 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_ci /* Request to trace every access to "address". */ 2557db96d56Sopenharmony_ci#define _Py_ANNOTATE_TRACE_MEMORY(address) \ 2567db96d56Sopenharmony_ci AnnotateTraceMemory(__FILE__, __LINE__, address) 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_ci /* Report the current thread name to a race detector. */ 2597db96d56Sopenharmony_ci#define _Py_ANNOTATE_THREAD_NAME(name) \ 2607db96d56Sopenharmony_ci AnnotateThreadName(__FILE__, __LINE__, name) 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci /* ------------------------------------------------------------- 2637db96d56Sopenharmony_ci Annotations useful when implementing locks. They are not 2647db96d56Sopenharmony_ci normally needed by modules that merely use locks. 2657db96d56Sopenharmony_ci The "lock" argument is a pointer to the lock object. */ 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci /* Report that a lock has been created at address "lock". */ 2687db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_CREATE(lock) \ 2697db96d56Sopenharmony_ci AnnotateRWLockCreate(__FILE__, __LINE__, lock) 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci /* Report that the lock at address "lock" is about to be destroyed. */ 2727db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \ 2737db96d56Sopenharmony_ci AnnotateRWLockDestroy(__FILE__, __LINE__, lock) 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci /* Report that the lock at address "lock" has been acquired. 2767db96d56Sopenharmony_ci is_w=1 for writer lock, is_w=0 for reader lock. */ 2777db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ 2787db96d56Sopenharmony_ci AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_ci /* Report that the lock at address "lock" is about to be released. */ 2817db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ 2827db96d56Sopenharmony_ci AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci /* ------------------------------------------------------------- 2857db96d56Sopenharmony_ci Annotations useful when implementing barriers. They are not 2867db96d56Sopenharmony_ci normally needed by modules that merely use barriers. 2877db96d56Sopenharmony_ci The "barrier" argument is a pointer to the barrier object. */ 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci /* Report that the "barrier" has been initialized with initial "count". 2907db96d56Sopenharmony_ci If 'reinitialization_allowed' is true, initialization is allowed to happen 2917db96d56Sopenharmony_ci multiple times w/o calling barrier_destroy() */ 2927db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ 2937db96d56Sopenharmony_ci AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \ 2947db96d56Sopenharmony_ci reinitialization_allowed) 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci /* Report that we are about to enter barrier_wait("barrier"). */ 2977db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ 2987db96d56Sopenharmony_ci AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ci /* Report that we just exited barrier_wait("barrier"). */ 3017db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ 3027db96d56Sopenharmony_ci AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) 3037db96d56Sopenharmony_ci 3047db96d56Sopenharmony_ci /* Report that the "barrier" has been destroyed. */ 3057db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \ 3067db96d56Sopenharmony_ci AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci /* ------------------------------------------------------------- 3097db96d56Sopenharmony_ci Annotations useful for testing race detectors. */ 3107db96d56Sopenharmony_ci 3117db96d56Sopenharmony_ci /* Report that we expect a race on the variable at "address". 3127db96d56Sopenharmony_ci Use only in unit tests for a race detector. */ 3137db96d56Sopenharmony_ci#define _Py_ANNOTATE_EXPECT_RACE(address, description) \ 3147db96d56Sopenharmony_ci AnnotateExpectRace(__FILE__, __LINE__, address, description) 3157db96d56Sopenharmony_ci 3167db96d56Sopenharmony_ci /* A no-op. Insert where you like to test the interceptors. */ 3177db96d56Sopenharmony_ci#define _Py_ANNOTATE_NO_OP(arg) \ 3187db96d56Sopenharmony_ci AnnotateNoOp(__FILE__, __LINE__, arg) 3197db96d56Sopenharmony_ci 3207db96d56Sopenharmony_ci /* Force the race detector to flush its state. The actual effect depends on 3217db96d56Sopenharmony_ci * the implementation of the detector. */ 3227db96d56Sopenharmony_ci#define _Py_ANNOTATE_FLUSH_STATE() \ 3237db96d56Sopenharmony_ci AnnotateFlushState(__FILE__, __LINE__) 3247db96d56Sopenharmony_ci 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */ 3297db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ 3307db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ 3317db96d56Sopenharmony_ci#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ 3327db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ 3337db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ 3347db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ 3357db96d56Sopenharmony_ci#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ 3367db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ 3377db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */ 3387db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ 3397db96d56Sopenharmony_ci#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ 3407db96d56Sopenharmony_ci#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ 3417db96d56Sopenharmony_ci#define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */ 3427db96d56Sopenharmony_ci#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ 3437db96d56Sopenharmony_ci#define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ 3447db96d56Sopenharmony_ci#define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ 3457db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */ 3467db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */ 3477db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */ 3487db96d56Sopenharmony_ci#define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */ 3497db96d56Sopenharmony_ci#define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */ 3507db96d56Sopenharmony_ci#define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */ 3517db96d56Sopenharmony_ci#define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */ 3527db96d56Sopenharmony_ci#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ 3537db96d56Sopenharmony_ci#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ 3547db96d56Sopenharmony_ci#define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ 3557db96d56Sopenharmony_ci#define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */ 3567db96d56Sopenharmony_ci#define _Py_ANNOTATE_THREAD_NAME(name) /* empty */ 3577db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */ 3587db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_END() /* empty */ 3597db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ 3607db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */ 3617db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ 3627db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ 3637db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ 3647db96d56Sopenharmony_ci#define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */ 3657db96d56Sopenharmony_ci#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ 3667db96d56Sopenharmony_ci#define _Py_ANNOTATE_NO_OP(arg) /* empty */ 3677db96d56Sopenharmony_ci#define _Py_ANNOTATE_FLUSH_STATE() /* empty */ 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_ci#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci/* Use the macros above rather than using these functions directly. */ 3727db96d56Sopenharmony_ci#ifdef __cplusplus 3737db96d56Sopenharmony_ciextern "C" { 3747db96d56Sopenharmony_ci#endif 3757db96d56Sopenharmony_civoid AnnotateRWLockCreate(const char *file, int line, 3767db96d56Sopenharmony_ci const volatile void *lock); 3777db96d56Sopenharmony_civoid AnnotateRWLockDestroy(const char *file, int line, 3787db96d56Sopenharmony_ci const volatile void *lock); 3797db96d56Sopenharmony_civoid AnnotateRWLockAcquired(const char *file, int line, 3807db96d56Sopenharmony_ci const volatile void *lock, long is_w); 3817db96d56Sopenharmony_civoid AnnotateRWLockReleased(const char *file, int line, 3827db96d56Sopenharmony_ci const volatile void *lock, long is_w); 3837db96d56Sopenharmony_civoid AnnotateBarrierInit(const char *file, int line, 3847db96d56Sopenharmony_ci const volatile void *barrier, long count, 3857db96d56Sopenharmony_ci long reinitialization_allowed); 3867db96d56Sopenharmony_civoid AnnotateBarrierWaitBefore(const char *file, int line, 3877db96d56Sopenharmony_ci const volatile void *barrier); 3887db96d56Sopenharmony_civoid AnnotateBarrierWaitAfter(const char *file, int line, 3897db96d56Sopenharmony_ci const volatile void *barrier); 3907db96d56Sopenharmony_civoid AnnotateBarrierDestroy(const char *file, int line, 3917db96d56Sopenharmony_ci const volatile void *barrier); 3927db96d56Sopenharmony_civoid AnnotateCondVarWait(const char *file, int line, 3937db96d56Sopenharmony_ci const volatile void *cv, 3947db96d56Sopenharmony_ci const volatile void *lock); 3957db96d56Sopenharmony_civoid AnnotateCondVarSignal(const char *file, int line, 3967db96d56Sopenharmony_ci const volatile void *cv); 3977db96d56Sopenharmony_civoid AnnotateCondVarSignalAll(const char *file, int line, 3987db96d56Sopenharmony_ci const volatile void *cv); 3997db96d56Sopenharmony_civoid AnnotatePublishMemoryRange(const char *file, int line, 4007db96d56Sopenharmony_ci const volatile void *address, 4017db96d56Sopenharmony_ci long size); 4027db96d56Sopenharmony_civoid AnnotateUnpublishMemoryRange(const char *file, int line, 4037db96d56Sopenharmony_ci const volatile void *address, 4047db96d56Sopenharmony_ci long size); 4057db96d56Sopenharmony_civoid AnnotatePCQCreate(const char *file, int line, 4067db96d56Sopenharmony_ci const volatile void *pcq); 4077db96d56Sopenharmony_civoid AnnotatePCQDestroy(const char *file, int line, 4087db96d56Sopenharmony_ci const volatile void *pcq); 4097db96d56Sopenharmony_civoid AnnotatePCQPut(const char *file, int line, 4107db96d56Sopenharmony_ci const volatile void *pcq); 4117db96d56Sopenharmony_civoid AnnotatePCQGet(const char *file, int line, 4127db96d56Sopenharmony_ci const volatile void *pcq); 4137db96d56Sopenharmony_civoid AnnotateNewMemory(const char *file, int line, 4147db96d56Sopenharmony_ci const volatile void *address, 4157db96d56Sopenharmony_ci long size); 4167db96d56Sopenharmony_civoid AnnotateExpectRace(const char *file, int line, 4177db96d56Sopenharmony_ci const volatile void *address, 4187db96d56Sopenharmony_ci const char *description); 4197db96d56Sopenharmony_civoid AnnotateBenignRace(const char *file, int line, 4207db96d56Sopenharmony_ci const volatile void *address, 4217db96d56Sopenharmony_ci const char *description); 4227db96d56Sopenharmony_civoid AnnotateBenignRaceSized(const char *file, int line, 4237db96d56Sopenharmony_ci const volatile void *address, 4247db96d56Sopenharmony_ci long size, 4257db96d56Sopenharmony_ci const char *description); 4267db96d56Sopenharmony_civoid AnnotateMutexIsUsedAsCondVar(const char *file, int line, 4277db96d56Sopenharmony_ci const volatile void *mu); 4287db96d56Sopenharmony_civoid AnnotateTraceMemory(const char *file, int line, 4297db96d56Sopenharmony_ci const volatile void *arg); 4307db96d56Sopenharmony_civoid AnnotateThreadName(const char *file, int line, 4317db96d56Sopenharmony_ci const char *name); 4327db96d56Sopenharmony_civoid AnnotateIgnoreReadsBegin(const char *file, int line); 4337db96d56Sopenharmony_civoid AnnotateIgnoreReadsEnd(const char *file, int line); 4347db96d56Sopenharmony_civoid AnnotateIgnoreWritesBegin(const char *file, int line); 4357db96d56Sopenharmony_civoid AnnotateIgnoreWritesEnd(const char *file, int line); 4367db96d56Sopenharmony_civoid AnnotateEnableRaceDetection(const char *file, int line, int enable); 4377db96d56Sopenharmony_civoid AnnotateNoOp(const char *file, int line, 4387db96d56Sopenharmony_ci const volatile void *arg); 4397db96d56Sopenharmony_civoid AnnotateFlushState(const char *file, int line); 4407db96d56Sopenharmony_ci 4417db96d56Sopenharmony_ci/* Return non-zero value if running under valgrind. 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci If "valgrind.h" is included into dynamic_annotations.c, 4447db96d56Sopenharmony_ci the regular valgrind mechanism will be used. 4457db96d56Sopenharmony_ci See http://valgrind.org/docs/manual/manual-core-adv.html about 4467db96d56Sopenharmony_ci RUNNING_ON_VALGRIND and other valgrind "client requests". 4477db96d56Sopenharmony_ci The file "valgrind.h" may be obtained by doing 4487db96d56Sopenharmony_ci svn co svn://svn.valgrind.org/valgrind/trunk/include 4497db96d56Sopenharmony_ci 4507db96d56Sopenharmony_ci If for some reason you can't use "valgrind.h" or want to fake valgrind, 4517db96d56Sopenharmony_ci there are two ways to make this function return non-zero: 4527db96d56Sopenharmony_ci - Use environment variable: export RUNNING_ON_VALGRIND=1 4537db96d56Sopenharmony_ci - Make your tool intercept the function RunningOnValgrind() and 4547db96d56Sopenharmony_ci change its return value. 4557db96d56Sopenharmony_ci */ 4567db96d56Sopenharmony_ciint RunningOnValgrind(void); 4577db96d56Sopenharmony_ci 4587db96d56Sopenharmony_ci#ifdef __cplusplus 4597db96d56Sopenharmony_ci} 4607db96d56Sopenharmony_ci#endif 4617db96d56Sopenharmony_ci 4627db96d56Sopenharmony_ci#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) 4637db96d56Sopenharmony_ci 4647db96d56Sopenharmony_ci /* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. 4657db96d56Sopenharmony_ci 4667db96d56Sopenharmony_ci Instead of doing 4677db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_BEGIN(); 4687db96d56Sopenharmony_ci ... = x; 4697db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_END(); 4707db96d56Sopenharmony_ci one can use 4717db96d56Sopenharmony_ci ... = _Py_ANNOTATE_UNPROTECTED_READ(x); */ 4727db96d56Sopenharmony_ci template <class T> 4737db96d56Sopenharmony_ci inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) { 4747db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_BEGIN(); 4757db96d56Sopenharmony_ci T res = x; 4767db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_END(); 4777db96d56Sopenharmony_ci return res; 4787db96d56Sopenharmony_ci } 4797db96d56Sopenharmony_ci /* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ 4807db96d56Sopenharmony_ci#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ 4817db96d56Sopenharmony_ci namespace { \ 4827db96d56Sopenharmony_ci class static_var ## _annotator { \ 4837db96d56Sopenharmony_ci public: \ 4847db96d56Sopenharmony_ci static_var ## _annotator() { \ 4857db96d56Sopenharmony_ci _Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ 4867db96d56Sopenharmony_ci sizeof(static_var), \ 4877db96d56Sopenharmony_ci # static_var ": " description); \ 4887db96d56Sopenharmony_ci } \ 4897db96d56Sopenharmony_ci }; \ 4907db96d56Sopenharmony_ci static static_var ## _annotator the ## static_var ## _annotator;\ 4917db96d56Sopenharmony_ci } 4927db96d56Sopenharmony_ci#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ 4937db96d56Sopenharmony_ci 4947db96d56Sopenharmony_ci#define _Py_ANNOTATE_UNPROTECTED_READ(x) (x) 4957db96d56Sopenharmony_ci#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ 4967db96d56Sopenharmony_ci 4977db96d56Sopenharmony_ci#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ 4987db96d56Sopenharmony_ci 4997db96d56Sopenharmony_ci#endif /* __DYNAMIC_ANNOTATIONS_H__ */ 500