Home | History | Annotate | Download | only in drd
      1 /*
      2   ----------------------------------------------------------------
      3 
      4   Notice that the following BSD-style license applies to this one
      5   file (drd.h) only.  The rest of Valgrind is licensed under the
      6   terms of the GNU General Public License, version 2, unless
      7   otherwise indicated.  See the COPYING file in the source
      8   distribution for details.
      9 
     10   ----------------------------------------------------------------
     11 
     12   This file is part of DRD, a Valgrind tool for verification of
     13   multithreaded programs.
     14 
     15   Copyright (C) 2006-2013 Bart Van Assche <bvanassche (at) acm.org>.
     16   All rights reserved.
     17 
     18   Redistribution and use in source and binary forms, with or without
     19   modification, are permitted provided that the following conditions
     20   are met:
     21 
     22   1. Redistributions of source code must retain the above copyright
     23   notice, this list of conditions and the following disclaimer.
     24 
     25   2. The origin of this software must not be misrepresented; you must
     26   not claim that you wrote the original software.  If you use this
     27   software in a product, an acknowledgment in the product
     28   documentation would be appreciated but is not required.
     29 
     30   3. Altered source versions must be plainly marked as such, and must
     31   not be misrepresented as being the original software.
     32 
     33   4. The name of the author may not be used to endorse or promote
     34   products derived from this software without specific prior written
     35   permission.
     36 
     37   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     38   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     39   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     40   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     41   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     42   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     43   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     44   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     45   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     46   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     47   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     48 
     49   ----------------------------------------------------------------
     50 
     51   Notice that the above BSD-style license applies to this one file
     52   (drd.h) only.  The entire rest of Valgrind is licensed under
     53   the terms of the GNU General Public License, version 2.  See the
     54   COPYING file in the source distribution for details.
     55 
     56   ----------------------------------------------------------------
     57 */
     58 
     59 #ifndef __VALGRIND_DRD_H
     60 #define __VALGRIND_DRD_H
     61 
     62 
     63 #include "valgrind.h"
     64 
     65 
     66 /** Obtain the thread ID assigned by Valgrind's core. */
     67 #define DRD_GET_VALGRIND_THREADID                                          \
     68     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                           \
     69                                    VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID, \
     70                                    0, 0, 0, 0, 0)
     71 
     72 /** Obtain the thread ID assigned by DRD. */
     73 #define DRD_GET_DRD_THREADID                                            \
     74     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
     75                                    VG_USERREQ__DRD_GET_DRD_THREAD_ID,   \
     76                                    0, 0, 0, 0, 0)
     77 
     78 
     79 /** Tell DRD not to complain about data races for the specified variable. */
     80 #define DRD_IGNORE_VAR(x) ANNOTATE_BENIGN_RACE_SIZED(&(x), sizeof(x), "")
     81 
     82 /** Tell DRD to no longer ignore data races for the specified variable. */
     83 #define DRD_STOP_IGNORING_VAR(x)                                       \
     84    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_FINISH_SUPPRESSION, \
     85                                    &(x), sizeof(x), 0, 0, 0)
     86 
     87 /**
     88  * Tell DRD to trace all memory accesses for the specified variable
     89  * until the memory that was allocated for the variable is freed.
     90  */
     91 #define DRD_TRACE_VAR(x)                                             \
     92    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_TRACE_ADDR, \
     93                                    &(x), sizeof(x), 0, 0, 0)
     94 
     95 /**
     96  * Tell DRD to stop tracing memory accesses for the specified variable.
     97  */
     98 #define DRD_STOP_TRACING_VAR(x)                                       \
     99    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_STOP_TRACE_ADDR, \
    100                                    &(x), sizeof(x), 0, 0, 0)
    101 
    102 /**
    103  * @defgroup RaceDetectionAnnotations Data race detection annotations.
    104  *
    105  * @see See also the source file <a href="http://code.google.com/p/data-race-test/source/browse/trunk/dynamic_annotations/dynamic_annotations.h</a>
    106 
    107  * in the ThreadSanitizer project.
    108  */
    109 /*@{*/
    110 
    111 #ifndef __HELGRIND_H
    112 
    113 /**
    114  * Tell DRD to insert a happens-before mark. addr is the address of an object
    115  * that is not a pthread synchronization object.
    116  */
    117 #define ANNOTATE_HAPPENS_BEFORE(addr)                                       \
    118    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE, \
    119                                    addr, 0, 0, 0, 0)
    120 
    121 /**
    122  * Tell DRD that the memory accesses executed after this annotation will
    123  * happen after all memory accesses performed before all preceding
    124  * ANNOTATE_HAPPENS_BEFORE(addr). addr is the address of an object that is not
    125  * a pthread synchronization object. Inserting a happens-after annotation
    126  * before any other thread has passed by a happens-before annotation for the
    127  * same address is an error.
    128  */
    129 #define ANNOTATE_HAPPENS_AFTER(addr)                                       \
    130    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER, \
    131                                    addr, 0, 0, 0, 0)
    132 
    133 #else /* __HELGRIND_H */
    134 
    135 #undef ANNOTATE_CONDVAR_LOCK_WAIT
    136 #undef ANNOTATE_CONDVAR_WAIT
    137 #undef ANNOTATE_CONDVAR_SIGNAL
    138 #undef ANNOTATE_CONDVAR_SIGNAL_ALL
    139 #undef ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX
    140 #undef ANNOTATE_PUBLISH_MEMORY_RANGE
    141 #undef ANNOTATE_BARRIER_INIT
    142 #undef ANNOTATE_BARRIER_WAIT_BEFORE
    143 #undef ANNOTATE_BARRIER_WAIT_AFTER
    144 #undef ANNOTATE_BARRIER_DESTROY
    145 #undef ANNOTATE_PCQ_CREATE
    146 #undef ANNOTATE_PCQ_DESTROY
    147 #undef ANNOTATE_PCQ_PUT
    148 #undef ANNOTATE_PCQ_GET
    149 #undef ANNOTATE_BENIGN_RACE
    150 #undef ANNOTATE_BENIGN_RACE_SIZED
    151 #undef ANNOTATE_IGNORE_READS_BEGIN
    152 #undef ANNOTATE_IGNORE_READS_END
    153 #undef ANNOTATE_IGNORE_WRITES_BEGIN
    154 #undef ANNOTATE_IGNORE_WRITES_END
    155 #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN
    156 #undef ANNOTATE_IGNORE_READS_AND_WRITES_END
    157 #undef ANNOTATE_NEW_MEMORY
    158 #undef ANNOTATE_TRACE_MEMORY
    159 #undef ANNOTATE_THREAD_NAME
    160 
    161 #endif /* __HELGRIND_H */
    162 
    163 /**
    164  * Tell DRD that waiting on the condition variable at address cv has succeeded
    165  * and a lock on the mutex at address mtx is now held. Since DRD always inserts
    166  * a happens before relation between the pthread_cond_signal() or
    167  * pthread_cond_broadcast() call that wakes up a pthread_cond_wait() or
    168  * pthread_cond_timedwait() call and the woken up thread, this macro has been
    169  * defined such that it has no effect.
    170  */
    171 #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, mtx) do { } while(0)
    172 
    173 /**
    174  * Tell DRD that the condition variable at address cv is about to be signaled.
    175  */
    176 #define ANNOTATE_CONDVAR_SIGNAL(cv) do { } while(0)
    177 
    178 /**
    179  * Tell DRD that the condition variable at address cv is about to be signaled.
    180  */
    181 #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) do { } while(0)
    182 
    183 /**
    184  * Tell DRD that waiting on condition variable at address cv succeeded and that
    185  * the memory operations performed after this annotation should be considered
    186  * to happen after the matching ANNOTATE_CONDVAR_SIGNAL(cv). Since this is the
    187  * default behavior of DRD, this macro and the macro above have been defined
    188  * such that they have no effect.
    189  */
    190 #define ANNOTATE_CONDVAR_WAIT(cv) do { } while(0)
    191 
    192 /**
    193  * Tell DRD to consider the memory operations that happened before a mutex
    194  * unlock event and after the subsequent mutex lock event on the same mutex as
    195  * ordered. This is how DRD always behaves, so this macro has been defined
    196  * such that it has no effect.
    197  */
    198 #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mtx) do { } while(0)
    199 
    200 /** Deprecated -- don't use this annotation. */
    201 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mtx) do { } while(0)
    202 
    203 /**
    204  * Tell DRD to handle the specified memory range like a pure happens-before
    205  * detector would do. Since this is how DRD always behaves, this annotation
    206  * has been defined such that it has no effect.
    207  */
    208 #define ANNOTATE_PUBLISH_MEMORY_RANGE(addr, size) do { } while(0)
    209 
    210 /** Deprecated -- don't use this annotation. */
    211 #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(addr, size) do { } while(0)
    212 
    213 /** Deprecated -- don't use this annotation. */
    214 #define ANNOTATE_SWAP_MEMORY_RANGE(addr, size) do { } while(0)
    215 
    216 #ifndef __HELGRIND_H
    217 
    218 /** Tell DRD that a reader-writer lock object has been initialized. */
    219 #define ANNOTATE_RWLOCK_CREATE(rwlock)                                     \
    220    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE, \
    221                                    rwlock, 0, 0, 0, 0);
    222 
    223 /** Tell DRD that a reader-writer lock object has been destroyed. */
    224 #define ANNOTATE_RWLOCK_DESTROY(rwlock)                                     \
    225    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY, \
    226                                    rwlock, 0, 0, 0, 0);
    227 
    228 /**
    229  * Tell DRD that a reader-writer lock has been acquired. is_w == 1 means that
    230  * a write lock has been obtained, is_w == 0 means that a read lock has been
    231  * obtained.
    232  */
    233 #define ANNOTATE_RWLOCK_ACQUIRED(rwlock, is_w)                               \
    234    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED, \
    235                                    rwlock, is_w, 0, 0, 0)
    236 
    237 #endif /* __HELGRIND_H */
    238 
    239 /**
    240  * Tell DRD that a reader lock has been acquired on a reader-writer
    241  * synchronization object.
    242  */
    243 #define ANNOTATE_READERLOCK_ACQUIRED(rwlock) ANNOTATE_RWLOCK_ACQUIRED(rwlock, 0)
    244 
    245 /**
    246  * Tell DRD that a writer lock has been acquired on a reader-writer
    247  * synchronization object.
    248  */
    249 #define ANNOTATE_WRITERLOCK_ACQUIRED(rwlock) ANNOTATE_RWLOCK_ACQUIRED(rwlock, 1)
    250 
    251 #ifndef __HELGRIND_H
    252 
    253 /**
    254  * Tell DRD that a reader-writer lock is about to be released. is_w == 1 means
    255  * that a write lock is about to be released, is_w == 0 means that a read lock
    256  * is about to be released.
    257  */
    258 #define ANNOTATE_RWLOCK_RELEASED(rwlock, is_w)                               \
    259    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED, \
    260                                    rwlock, is_w, 0, 0, 0);
    261 
    262 #endif /* __HELGRIND_H */
    263 
    264 /**
    265  * Tell DRD that a reader lock is about to be released.
    266  */
    267 #define ANNOTATE_READERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 0)
    268 
    269 /**
    270  * Tell DRD that a writer lock is about to be released.
    271  */
    272 #define ANNOTATE_WRITERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 1)
    273 
    274 /** Tell DRD that a semaphore object is going to be initialized. */
    275 #define ANNOTATE_SEM_INIT_PRE(sem, value)                                 \
    276    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_INIT_PRE, \
    277                                    sem, value, 0, 0, 0);
    278 
    279 /** Tell DRD that a semaphore object has been destroyed. */
    280 #define ANNOTATE_SEM_DESTROY_POST(sem)                                        \
    281    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_DESTROY_POST, \
    282                                    sem, 0, 0, 0, 0);
    283 
    284 /** Tell DRD that a semaphore is going to be acquired. */
    285 #define ANNOTATE_SEM_WAIT_PRE(sem)                                        \
    286    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_PRE, \
    287                                    sem, 0, 0, 0, 0)
    288 
    289 /** Tell DRD that a semaphore has been acquired. */
    290 #define ANNOTATE_SEM_WAIT_POST(sem)                                        \
    291    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_POST, \
    292                                    sem, 0, 0, 0, 0)
    293 
    294 /** Tell DRD that a semaphore is going to be released. */
    295 #define ANNOTATE_SEM_POST_PRE(sem)                                        \
    296    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_POST_PRE, \
    297                                    sem, 0, 0, 0, 0)
    298 
    299 /*
    300  * Report that a barrier has been initialized with a given barrier count.  The
    301  * third argument specifies whether or not reinitialization is allowed, that
    302  * is, whether or not it is allowed to call barrier_init() several times
    303  * without calling barrier_destroy().
    304  */
    305 #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
    306    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
    307                                    "ANNOTATE_BARRIER_INIT", barrier,    \
    308                                    count, reinitialization_allowed, 0)
    309 
    310 /* Report that a barrier has been destroyed. */
    311 #define ANNOTATE_BARRIER_DESTROY(barrier)                               \
    312    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
    313                                    "ANNOTATE_BARRIER_DESTROY",          \
    314                                    barrier, 0, 0, 0)
    315 
    316 /* Report that the calling thread is about to start waiting for a barrier. */
    317 #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier)                           \
    318    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
    319                                    "ANNOTATE_BARRIER_WAIT_BEFORE",      \
    320                                    barrier, 0, 0, 0)
    321 
    322 /* Report that the calling thread has just finished waiting for a barrier. */
    323 #define ANNOTATE_BARRIER_WAIT_AFTER(barrier)                            \
    324    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
    325                                    "ANNOTATE_BARRIER_WAIT_AFTER",       \
    326                                    barrier, 0, 0, 0)
    327 
    328 /**
    329  * Tell DRD that a FIFO queue has been created. The abbreviation PCQ stands for
    330  * <em>producer-consumer</em>.
    331  */
    332 #define ANNOTATE_PCQ_CREATE(pcq) do { } while(0)
    333 
    334 /** Tell DRD that a FIFO queue has been destroyed. */
    335 #define ANNOTATE_PCQ_DESTROY(pcq) do { } while(0)
    336 
    337 /**
    338  * Tell DRD that an element has been added to the FIFO queue at address pcq.
    339  */
    340 #define ANNOTATE_PCQ_PUT(pcq) do { } while(0)
    341 
    342 /**
    343  * Tell DRD that an element has been removed from the FIFO queue at address pcq,
    344  * and that DRD should insert a happens-before relationship between the memory
    345  * accesses that occurred before the corresponding ANNOTATE_PCQ_PUT(pcq)
    346  * annotation and the memory accesses after this annotation. Correspondence
    347  * between PUT and GET annotations happens in FIFO order. Since locking
    348  * of the queue is needed anyway to add elements to or to remove elements from
    349  * the queue, for DRD all four FIFO annotations are defined as no-ops.
    350  */
    351 #define ANNOTATE_PCQ_GET(pcq) do { } while(0)
    352 
    353 /**
    354  * Tell DRD that data races at the specified address are expected and must not
    355  * be reported.
    356  */
    357 #define ANNOTATE_BENIGN_RACE(addr, descr) \
    358    ANNOTATE_BENIGN_RACE_SIZED(addr, sizeof(*addr), descr)
    359 
    360 /* Same as ANNOTATE_BENIGN_RACE(addr, descr), but applies to
    361    the memory range [addr, addr + size). */
    362 #define ANNOTATE_BENIGN_RACE_SIZED(addr, size, descr)                   \
    363    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_SUPPRESSION,   \
    364                                    addr, size, 0, 0, 0)
    365 
    366 /** Tell DRD to ignore all reads performed by the current thread. */
    367 #define ANNOTATE_IGNORE_READS_BEGIN()                                \
    368    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_LOADS,     \
    369                                    0, 0, 0, 0, 0);
    370 
    371 
    372 /** Tell DRD to no longer ignore the reads performed by the current thread. */
    373 #define ANNOTATE_IGNORE_READS_END()                                  \
    374    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_LOADS,     \
    375                                    1, 0, 0, 0, 0);
    376 
    377 /** Tell DRD to ignore all writes performed by the current thread. */
    378 #define ANNOTATE_IGNORE_WRITES_BEGIN()                                \
    379    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_STORES,     \
    380                                    0, 0, 0, 0, 0)
    381 
    382 /** Tell DRD to no longer ignore the writes performed by the current thread. */
    383 #define ANNOTATE_IGNORE_WRITES_END()                                  \
    384    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_STORES,     \
    385                                    1, 0, 0, 0, 0)
    386 
    387 /** Tell DRD to ignore all memory accesses performed by the current thread. */
    388 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
    389    do { ANNOTATE_IGNORE_READS_BEGIN(); ANNOTATE_IGNORE_WRITES_BEGIN(); } while(0)
    390 
    391 /**
    392  * Tell DRD to no longer ignore the memory accesses performed by the current
    393  * thread.
    394  */
    395 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
    396    do { ANNOTATE_IGNORE_READS_END(); ANNOTATE_IGNORE_WRITES_END(); } while(0)
    397 
    398 /**
    399  * Tell DRD that size bytes starting at addr has been allocated by a custom
    400  * memory allocator.
    401  */
    402 #define ANNOTATE_NEW_MEMORY(addr, size)                           \
    403    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_CLEAN_MEMORY,  \
    404                                    addr, size, 0, 0, 0)
    405 
    406 /** Ask DRD to report every access to the specified address. */
    407 #define ANNOTATE_TRACE_MEMORY(addr) DRD_TRACE_VAR(*(char*)(addr))
    408 
    409 /**
    410  * Tell DRD to assign the specified name to the current thread. This name will
    411  * be used in error messages printed by DRD.
    412  */
    413 #define ANNOTATE_THREAD_NAME(name)                                      \
    414    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_SET_THREAD_NAME,     \
    415                                    name, 0, 0, 0, 0)
    416 
    417 /*@}*/
    418 
    419 
    420 /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
    421    This enum comprises an ABI exported by Valgrind to programs
    422    which use client requests.  DO NOT CHANGE THE ORDER OF THESE
    423    ENTRIES, NOR DELETE ANY -- add new ones at the end.
    424 */
    425 enum {
    426    /* Ask the DRD tool to discard all information about memory accesses   */
    427    /* and client objects for the specified range. This client request is  */
    428    /* binary compatible with the similarly named Helgrind client request. */
    429    VG_USERREQ__DRD_CLEAN_MEMORY = VG_USERREQ_TOOL_BASE('H','G'),
    430    /* args: Addr, SizeT. */
    431 
    432    /* Ask the DRD tool the thread ID assigned by Valgrind. */
    433    VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID = VG_USERREQ_TOOL_BASE('D','R'),
    434    /* args: none. */
    435    /* Ask the DRD tool the thread ID assigned by DRD. */
    436    VG_USERREQ__DRD_GET_DRD_THREAD_ID,
    437    /* args: none. */
    438 
    439    /* To tell the DRD tool to suppress data race detection on the */
    440    /* specified address range. */
    441    VG_USERREQ__DRD_START_SUPPRESSION,
    442    /* args: start address, size in bytes */
    443    /* To tell the DRD tool no longer to suppress data race detection on */
    444    /* the specified address range. */
    445    VG_USERREQ__DRD_FINISH_SUPPRESSION,
    446    /* args: start address, size in bytes */
    447 
    448    /* To ask the DRD tool to trace all accesses to the specified range. */
    449    VG_USERREQ__DRD_START_TRACE_ADDR,
    450    /* args: Addr, SizeT. */
    451    /* To ask the DRD tool to stop tracing accesses to the specified range. */
    452    VG_USERREQ__DRD_STOP_TRACE_ADDR,
    453    /* args: Addr, SizeT. */
    454 
    455    /* Tell DRD whether or not to record memory loads in the calling thread. */
    456    VG_USERREQ__DRD_RECORD_LOADS,
    457    /* args: Bool. */
    458    /* Tell DRD whether or not to record memory stores in the calling thread. */
    459    VG_USERREQ__DRD_RECORD_STORES,
    460    /* args: Bool. */
    461 
    462    /* Set the name of the thread that performs this client request. */
    463    VG_USERREQ__DRD_SET_THREAD_NAME,
    464    /* args: null-terminated character string. */
    465 
    466    /* Tell DRD that a DRD annotation has not yet been implemented. */
    467    VG_USERREQ__DRD_ANNOTATION_UNIMP,
    468    /* args: char*. */
    469 
    470    /* Tell DRD that a user-defined semaphore synchronization object
    471     * is about to be created. */
    472    VG_USERREQ__DRD_ANNOTATE_SEM_INIT_PRE,
    473    /* args: Addr, UInt value. */
    474    /* Tell DRD that a user-defined semaphore synchronization object
    475     * has been destroyed. */
    476    VG_USERREQ__DRD_ANNOTATE_SEM_DESTROY_POST,
    477    /* args: Addr. */
    478    /* Tell DRD that a user-defined semaphore synchronization
    479     * object is going to be acquired (semaphore wait). */
    480    VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_PRE,
    481    /* args: Addr. */
    482    /* Tell DRD that a user-defined semaphore synchronization
    483     * object has been acquired (semaphore wait). */
    484    VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_POST,
    485    /* args: Addr. */
    486    /* Tell DRD that a user-defined semaphore synchronization
    487     * object is about to be released (semaphore post). */
    488    VG_USERREQ__DRD_ANNOTATE_SEM_POST_PRE,
    489    /* args: Addr. */
    490 
    491    /* Tell DRD that a user-defined reader-writer synchronization object
    492     * has been created. */
    493    VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE
    494       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 14,
    495    /* args: Addr. */
    496    /* Tell DRD that a user-defined reader-writer synchronization object
    497     * is about to be destroyed. */
    498    VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY
    499       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 15,
    500    /* args: Addr. */
    501    /* Tell DRD that a lock on a user-defined reader-writer synchronization
    502     * object has been acquired. */
    503    VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED
    504       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 17,
    505    /* args: Addr, Int is_rw. */
    506    /* Tell DRD that a lock on a user-defined reader-writer synchronization
    507     * object is about to be released. */
    508    VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED
    509       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 18,
    510    /* args: Addr, Int is_rw. */
    511 
    512    /* Tell DRD that a Helgrind annotation has not yet been implemented. */
    513    VG_USERREQ__HELGRIND_ANNOTATION_UNIMP
    514       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 32,
    515    /* args: char*. */
    516 
    517    /* Tell DRD to insert a happens-before annotation. */
    518    VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE
    519       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 33,
    520    /* args: Addr. */
    521    /* Tell DRD to insert a happens-after annotation. */
    522    VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER
    523       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 34,
    524    /* args: Addr. */
    525 
    526 };
    527 
    528 
    529 /**
    530  * @addtogroup RaceDetectionAnnotations
    531  */
    532 /*@{*/
    533 
    534 #ifdef __cplusplus
    535 /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racy reads.
    536 
    537    Instead of doing
    538    ANNOTATE_IGNORE_READS_BEGIN();
    539    ... = x;
    540    ANNOTATE_IGNORE_READS_END();
    541    one can use
    542    ... = ANNOTATE_UNPROTECTED_READ(x); */
    543 template <typename T>
    544 inline T ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
    545    ANNOTATE_IGNORE_READS_BEGIN();
    546    const T result = x;
    547    ANNOTATE_IGNORE_READS_END();
    548    return result;
    549 }
    550 /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
    551 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)		\
    552    namespace {								\
    553       static class static_var##_annotator				\
    554       {									\
    555       public:								\
    556 	 static_var##_annotator()					\
    557 	 {								\
    558 	    ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var),	\
    559 				       #static_var ": " description);	\
    560 	 }								\
    561       } the_##static_var##_annotator;					\
    562    }
    563 #endif
    564 
    565 /*@}*/
    566 
    567 #endif /* __VALGRIND_DRD_H */
    568