Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:28

0001 /*
0002   ----------------------------------------------------------------
0003 
0004   Notice that the following BSD-style license applies to this one
0005   file (drd.h) only.  The rest of Valgrind is licensed under the
0006   terms of the GNU General Public License, version 2, unless
0007   otherwise indicated.  See the COPYING file in the source
0008   distribution for details.
0009 
0010   ----------------------------------------------------------------
0011 
0012   This file is part of DRD, a Valgrind tool for verification of
0013   multithreaded programs.
0014 
0015   Copyright (C) 2006-2020 Bart Van Assche <bvanassche@acm.org>.
0016   All rights reserved.
0017 
0018   Redistribution and use in source and binary forms, with or without
0019   modification, are permitted provided that the following conditions
0020   are met:
0021 
0022   1. Redistributions of source code must retain the above copyright
0023   notice, this list of conditions and the following disclaimer.
0024 
0025   2. The origin of this software must not be misrepresented; you must
0026   not claim that you wrote the original software.  If you use this
0027   software in a product, an acknowledgment in the product
0028   documentation would be appreciated but is not required.
0029 
0030   3. Altered source versions must be plainly marked as such, and must
0031   not be misrepresented as being the original software.
0032 
0033   4. The name of the author may not be used to endorse or promote
0034   products derived from this software without specific prior written
0035   permission.
0036 
0037   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
0038   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0039   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0040   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
0041   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0042   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
0043   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0044   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0045   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0046   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0047   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0048 
0049   ----------------------------------------------------------------
0050 
0051   Notice that the above BSD-style license applies to this one file
0052   (drd.h) only.  The entire rest of Valgrind is licensed under
0053   the terms of the GNU General Public License, version 2.  See the
0054   COPYING file in the source distribution for details.
0055 
0056   ----------------------------------------------------------------
0057 */
0058 
0059 #ifndef __VALGRIND_DRD_H
0060 #define __VALGRIND_DRD_H
0061 
0062 
0063 #include "valgrind.h"
0064 
0065 
0066 /** Obtain the thread ID assigned by Valgrind's core. */
0067 #define DRD_GET_VALGRIND_THREADID                                          \
0068     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                           \
0069                                    VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID, \
0070                                    0, 0, 0, 0, 0)
0071 
0072 /** Obtain the thread ID assigned by DRD. */
0073 #define DRD_GET_DRD_THREADID                                            \
0074     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
0075                                    VG_USERREQ__DRD_GET_DRD_THREAD_ID,   \
0076                                    0, 0, 0, 0, 0)
0077 
0078 
0079 /** Tell DRD not to complain about data races for the specified variable. */
0080 #define DRD_IGNORE_VAR(x) ANNOTATE_BENIGN_RACE_SIZED(&(x), sizeof(x), "")
0081 
0082 /** Tell DRD to no longer ignore data races for the specified variable. */
0083 #define DRD_STOP_IGNORING_VAR(x)                                       \
0084    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_FINISH_SUPPRESSION, \
0085                                    &(x), sizeof(x), 0, 0, 0)
0086 
0087 /**
0088  * Tell DRD to trace all memory accesses for the specified variable
0089  * until the memory that was allocated for the variable is freed.
0090  */
0091 #define DRD_TRACE_VAR(x)                                             \
0092    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_TRACE_ADDR, \
0093                                    &(x), sizeof(x), 0, 0, 0)
0094 
0095 /**
0096  * Tell DRD to stop tracing memory accesses for the specified variable.
0097  */
0098 #define DRD_STOP_TRACING_VAR(x)                                       \
0099    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_STOP_TRACE_ADDR, \
0100                                    &(x), sizeof(x), 0, 0, 0)
0101 
0102 /**
0103  * @defgroup RaceDetectionAnnotations Data race detection annotations.
0104  *
0105  * @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>
0106 
0107  * in the ThreadSanitizer project.
0108  */
0109 /*@{*/
0110 
0111 #ifndef __HELGRIND_H
0112 
0113 /**
0114  * Tell DRD to insert a happens-before mark. addr is the address of an object
0115  * that is not a pthread synchronization object.
0116  */
0117 #define ANNOTATE_HAPPENS_BEFORE(addr)                                       \
0118    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE, \
0119                                    addr, 0, 0, 0, 0)
0120 
0121 /**
0122  * Tell DRD that the memory accesses executed after this annotation will
0123  * happen after all memory accesses performed before all preceding
0124  * ANNOTATE_HAPPENS_BEFORE(addr). addr is the address of an object that is not
0125  * a pthread synchronization object. Inserting a happens-after annotation
0126  * before any other thread has passed by a happens-before annotation for the
0127  * same address is an error.
0128  */
0129 #define ANNOTATE_HAPPENS_AFTER(addr)                                       \
0130    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER, \
0131                                    addr, 0, 0, 0, 0)
0132 
0133 #else /* __HELGRIND_H */
0134 
0135 #undef ANNOTATE_CONDVAR_LOCK_WAIT
0136 #undef ANNOTATE_CONDVAR_WAIT
0137 #undef ANNOTATE_CONDVAR_SIGNAL
0138 #undef ANNOTATE_CONDVAR_SIGNAL_ALL
0139 #undef ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX
0140 #undef ANNOTATE_PUBLISH_MEMORY_RANGE
0141 #undef ANNOTATE_BARRIER_INIT
0142 #undef ANNOTATE_BARRIER_WAIT_BEFORE
0143 #undef ANNOTATE_BARRIER_WAIT_AFTER
0144 #undef ANNOTATE_BARRIER_DESTROY
0145 #undef ANNOTATE_PCQ_CREATE
0146 #undef ANNOTATE_PCQ_DESTROY
0147 #undef ANNOTATE_PCQ_PUT
0148 #undef ANNOTATE_PCQ_GET
0149 #undef ANNOTATE_BENIGN_RACE
0150 #undef ANNOTATE_BENIGN_RACE_SIZED
0151 #undef ANNOTATE_IGNORE_READS_BEGIN
0152 #undef ANNOTATE_IGNORE_READS_END
0153 #undef ANNOTATE_IGNORE_WRITES_BEGIN
0154 #undef ANNOTATE_IGNORE_WRITES_END
0155 #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN
0156 #undef ANNOTATE_IGNORE_READS_AND_WRITES_END
0157 #undef ANNOTATE_NEW_MEMORY
0158 #undef ANNOTATE_TRACE_MEMORY
0159 #undef ANNOTATE_THREAD_NAME
0160 
0161 #endif /* __HELGRIND_H */
0162 
0163 /**
0164  * Tell DRD that waiting on the condition variable at address cv has succeeded
0165  * and a lock on the mutex at address mtx is now held. Since DRD always inserts
0166  * a happens before relation between the pthread_cond_signal() or
0167  * pthread_cond_broadcast() call that wakes up a pthread_cond_wait() or
0168  * pthread_cond_timedwait() call and the woken up thread, this macro has been
0169  * defined such that it has no effect.
0170  */
0171 #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, mtx) do { } while(0)
0172 
0173 /**
0174  * Tell DRD that the condition variable at address cv is about to be signaled.
0175  */
0176 #define ANNOTATE_CONDVAR_SIGNAL(cv) do { } while(0)
0177 
0178 /**
0179  * Tell DRD that the condition variable at address cv is about to be signaled.
0180  */
0181 #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) do { } while(0)
0182 
0183 /**
0184  * Tell DRD that waiting on condition variable at address cv succeeded and that
0185  * the memory operations performed after this annotation should be considered
0186  * to happen after the matching ANNOTATE_CONDVAR_SIGNAL(cv). Since this is the
0187  * default behavior of DRD, this macro and the macro above have been defined
0188  * such that they have no effect.
0189  */
0190 #define ANNOTATE_CONDVAR_WAIT(cv) do { } while(0)
0191 
0192 /**
0193  * Tell DRD to consider the memory operations that happened before a mutex
0194  * unlock event and after the subsequent mutex lock event on the same mutex as
0195  * ordered. This is how DRD always behaves, so this macro has been defined
0196  * such that it has no effect.
0197  */
0198 #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mtx) do { } while(0)
0199 
0200 /** Deprecated -- don't use this annotation. */
0201 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mtx) do { } while(0)
0202 
0203 /**
0204  * Tell DRD to handle the specified memory range like a pure happens-before
0205  * detector would do. Since this is how DRD always behaves, this annotation
0206  * has been defined such that it has no effect.
0207  */
0208 #define ANNOTATE_PUBLISH_MEMORY_RANGE(addr, size) do { } while(0)
0209 
0210 /** Deprecated -- don't use this annotation. */
0211 #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(addr, size) do { } while(0)
0212 
0213 /** Deprecated -- don't use this annotation. */
0214 #define ANNOTATE_SWAP_MEMORY_RANGE(addr, size) do { } while(0)
0215 
0216 #ifndef __HELGRIND_H
0217 
0218 /** Tell DRD that a reader-writer lock object has been initialized. */
0219 #define ANNOTATE_RWLOCK_CREATE(rwlock)                                     \
0220    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE, \
0221                                    rwlock, 0, 0, 0, 0);
0222 
0223 /** Tell DRD that a reader-writer lock object has been destroyed. */
0224 #define ANNOTATE_RWLOCK_DESTROY(rwlock)                                     \
0225    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY, \
0226                                    rwlock, 0, 0, 0, 0);
0227 
0228 /**
0229  * Tell DRD that a reader-writer lock has been acquired. is_w == 1 means that
0230  * a write lock has been obtained, is_w == 0 means that a read lock has been
0231  * obtained.
0232  */
0233 #define ANNOTATE_RWLOCK_ACQUIRED(rwlock, is_w)                               \
0234    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED, \
0235                                    rwlock, is_w, 0, 0, 0)
0236 
0237 #endif /* __HELGRIND_H */
0238 
0239 /**
0240  * Tell DRD that a reader lock has been acquired on a reader-writer
0241  * synchronization object.
0242  */
0243 #define ANNOTATE_READERLOCK_ACQUIRED(rwlock) ANNOTATE_RWLOCK_ACQUIRED(rwlock, 0)
0244 
0245 /**
0246  * Tell DRD that a writer lock has been acquired on a reader-writer
0247  * synchronization object.
0248  */
0249 #define ANNOTATE_WRITERLOCK_ACQUIRED(rwlock) ANNOTATE_RWLOCK_ACQUIRED(rwlock, 1)
0250 
0251 #ifndef __HELGRIND_H
0252 
0253 /**
0254  * Tell DRD that a reader-writer lock is about to be released. is_w == 1 means
0255  * that a write lock is about to be released, is_w == 0 means that a read lock
0256  * is about to be released.
0257  */
0258 #define ANNOTATE_RWLOCK_RELEASED(rwlock, is_w)                               \
0259    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED, \
0260                                    rwlock, is_w, 0, 0, 0);
0261 
0262 #endif /* __HELGRIND_H */
0263 
0264 /**
0265  * Tell DRD that a reader lock is about to be released.
0266  */
0267 #define ANNOTATE_READERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 0)
0268 
0269 /**
0270  * Tell DRD that a writer lock is about to be released.
0271  */
0272 #define ANNOTATE_WRITERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 1)
0273 
0274 /** Tell DRD that a semaphore object is going to be initialized. */
0275 #define ANNOTATE_SEM_INIT_PRE(sem, value)                                 \
0276    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_INIT_PRE, \
0277                                    sem, value, 0, 0, 0);
0278 
0279 /** Tell DRD that a semaphore object has been destroyed. */
0280 #define ANNOTATE_SEM_DESTROY_POST(sem)                                        \
0281    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_DESTROY_POST, \
0282                                    sem, 0, 0, 0, 0);
0283 
0284 /** Tell DRD that a semaphore is going to be acquired. */
0285 #define ANNOTATE_SEM_WAIT_PRE(sem)                                        \
0286    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_PRE, \
0287                                    sem, 0, 0, 0, 0)
0288 
0289 /** Tell DRD that a semaphore has been acquired. */
0290 #define ANNOTATE_SEM_WAIT_POST(sem)                                        \
0291    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_POST, \
0292                                    sem, 0, 0, 0, 0)
0293 
0294 /** Tell DRD that a semaphore is going to be released. */
0295 #define ANNOTATE_SEM_POST_PRE(sem)                                        \
0296    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_POST_PRE, \
0297                                    sem, 0, 0, 0, 0)
0298 
0299 /*
0300  * Report that a barrier has been initialized with a given barrier count.  The
0301  * third argument specifies whether or not reinitialization is allowed, that
0302  * is, whether or not it is allowed to call barrier_init() several times
0303  * without calling barrier_destroy().
0304  */
0305 #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
0306    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
0307                                    "ANNOTATE_BARRIER_INIT", barrier,    \
0308                                    count, reinitialization_allowed, 0)
0309 
0310 /* Report that a barrier has been destroyed. */
0311 #define ANNOTATE_BARRIER_DESTROY(barrier)                               \
0312    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
0313                                    "ANNOTATE_BARRIER_DESTROY",          \
0314                                    barrier, 0, 0, 0)
0315 
0316 /* Report that the calling thread is about to start waiting for a barrier. */
0317 #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier)                           \
0318    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
0319                                    "ANNOTATE_BARRIER_WAIT_BEFORE",      \
0320                                    barrier, 0, 0, 0)
0321 
0322 /* Report that the calling thread has just finished waiting for a barrier. */
0323 #define ANNOTATE_BARRIER_WAIT_AFTER(barrier)                            \
0324    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP,    \
0325                                    "ANNOTATE_BARRIER_WAIT_AFTER",       \
0326                                    barrier, 0, 0, 0)
0327 
0328 /**
0329  * Tell DRD that a FIFO queue has been created. The abbreviation PCQ stands for
0330  * <em>producer-consumer</em>.
0331  */
0332 #define ANNOTATE_PCQ_CREATE(pcq) do { } while(0)
0333 
0334 /** Tell DRD that a FIFO queue has been destroyed. */
0335 #define ANNOTATE_PCQ_DESTROY(pcq) do { } while(0)
0336 
0337 /**
0338  * Tell DRD that an element has been added to the FIFO queue at address pcq.
0339  */
0340 #define ANNOTATE_PCQ_PUT(pcq) do { } while(0)
0341 
0342 /**
0343  * Tell DRD that an element has been removed from the FIFO queue at address pcq,
0344  * and that DRD should insert a happens-before relationship between the memory
0345  * accesses that occurred before the corresponding ANNOTATE_PCQ_PUT(pcq)
0346  * annotation and the memory accesses after this annotation. Correspondence
0347  * between PUT and GET annotations happens in FIFO order. Since locking
0348  * of the queue is needed anyway to add elements to or to remove elements from
0349  * the queue, for DRD all four FIFO annotations are defined as no-ops.
0350  */
0351 #define ANNOTATE_PCQ_GET(pcq) do { } while(0)
0352 
0353 /**
0354  * Tell DRD that data races at the specified address are expected and must not
0355  * be reported.
0356  */
0357 #define ANNOTATE_BENIGN_RACE(addr, descr) \
0358    ANNOTATE_BENIGN_RACE_SIZED(addr, sizeof(*addr), descr)
0359 
0360 /* Same as ANNOTATE_BENIGN_RACE(addr, descr), but applies to
0361    the memory range [addr, addr + size). */
0362 #define ANNOTATE_BENIGN_RACE_SIZED(addr, size, descr)                   \
0363    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_SUPPRESSION,   \
0364                                    addr, size, 0, 0, 0)
0365 
0366 /** Tell DRD to ignore all reads performed by the current thread. */
0367 #define ANNOTATE_IGNORE_READS_BEGIN()                                \
0368    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_LOADS,     \
0369                                    0, 0, 0, 0, 0);
0370 
0371 
0372 /** Tell DRD to no longer ignore the reads performed by the current thread. */
0373 #define ANNOTATE_IGNORE_READS_END()                                  \
0374    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_LOADS,     \
0375                                    1, 0, 0, 0, 0);
0376 
0377 /** Tell DRD to ignore all writes performed by the current thread. */
0378 #define ANNOTATE_IGNORE_WRITES_BEGIN()                                \
0379    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_STORES,     \
0380                                    0, 0, 0, 0, 0)
0381 
0382 /** Tell DRD to no longer ignore the writes performed by the current thread. */
0383 #define ANNOTATE_IGNORE_WRITES_END()                                  \
0384    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_STORES,     \
0385                                    1, 0, 0, 0, 0)
0386 
0387 /** Tell DRD to ignore all memory accesses performed by the current thread. */
0388 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
0389    do { ANNOTATE_IGNORE_READS_BEGIN(); ANNOTATE_IGNORE_WRITES_BEGIN(); } while(0)
0390 
0391 /**
0392  * Tell DRD to no longer ignore the memory accesses performed by the current
0393  * thread.
0394  */
0395 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
0396    do { ANNOTATE_IGNORE_READS_END(); ANNOTATE_IGNORE_WRITES_END(); } while(0)
0397 
0398 /**
0399  * Tell DRD that size bytes starting at addr has been allocated by a custom
0400  * memory allocator.
0401  */
0402 #define ANNOTATE_NEW_MEMORY(addr, size)                           \
0403    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_CLEAN_MEMORY,  \
0404                                    addr, size, 0, 0, 0)
0405 
0406 /** Ask DRD to report every access to the specified address. */
0407 #define ANNOTATE_TRACE_MEMORY(addr) DRD_TRACE_VAR(*(char*)(addr))
0408 
0409 /**
0410  * Tell DRD to assign the specified name to the current thread. This name will
0411  * be used in error messages printed by DRD.
0412  */
0413 #define ANNOTATE_THREAD_NAME(name)                                      \
0414    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_SET_THREAD_NAME,     \
0415                                    name, 0, 0, 0, 0)
0416 
0417 /*@}*/
0418 
0419 
0420 /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
0421    This enum comprises an ABI exported by Valgrind to programs
0422    which use client requests.  DO NOT CHANGE THE ORDER OF THESE
0423    ENTRIES, NOR DELETE ANY -- add new ones at the end.
0424 */
0425 enum {
0426    /* Ask the DRD tool to discard all information about memory accesses   */
0427    /* and client objects for the specified range. This client request is  */
0428    /* binary compatible with the similarly named Helgrind client request. */
0429    VG_USERREQ__DRD_CLEAN_MEMORY = VG_USERREQ_TOOL_BASE('H','G'),
0430    /* args: Addr, SizeT. */
0431 
0432    /* Ask the DRD tool the thread ID assigned by Valgrind. */
0433    VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID = VG_USERREQ_TOOL_BASE('D','R'),
0434    /* args: none. */
0435    /* Ask the DRD tool the thread ID assigned by DRD. */
0436    VG_USERREQ__DRD_GET_DRD_THREAD_ID,
0437    /* args: none. */
0438 
0439    /* To tell the DRD tool to suppress data race detection on the */
0440    /* specified address range. */
0441    VG_USERREQ__DRD_START_SUPPRESSION,
0442    /* args: start address, size in bytes */
0443    /* To tell the DRD tool no longer to suppress data race detection on */
0444    /* the specified address range. */
0445    VG_USERREQ__DRD_FINISH_SUPPRESSION,
0446    /* args: start address, size in bytes */
0447 
0448    /* To ask the DRD tool to trace all accesses to the specified range. */
0449    VG_USERREQ__DRD_START_TRACE_ADDR,
0450    /* args: Addr, SizeT. */
0451    /* To ask the DRD tool to stop tracing accesses to the specified range. */
0452    VG_USERREQ__DRD_STOP_TRACE_ADDR,
0453    /* args: Addr, SizeT. */
0454 
0455    /* Tell DRD whether or not to record memory loads in the calling thread. */
0456    VG_USERREQ__DRD_RECORD_LOADS,
0457    /* args: Bool. */
0458    /* Tell DRD whether or not to record memory stores in the calling thread. */
0459    VG_USERREQ__DRD_RECORD_STORES,
0460    /* args: Bool. */
0461 
0462    /* Set the name of the thread that performs this client request. */
0463    VG_USERREQ__DRD_SET_THREAD_NAME,
0464    /* args: null-terminated character string. */
0465 
0466    /* Tell DRD that a DRD annotation has not yet been implemented. */
0467    VG_USERREQ__DRD_ANNOTATION_UNIMP,
0468    /* args: char*. */
0469 
0470    /* Tell DRD that a user-defined semaphore synchronization object
0471     * is about to be created. */
0472    VG_USERREQ__DRD_ANNOTATE_SEM_INIT_PRE,
0473    /* args: Addr, UInt value. */
0474    /* Tell DRD that a user-defined semaphore synchronization object
0475     * has been destroyed. */
0476    VG_USERREQ__DRD_ANNOTATE_SEM_DESTROY_POST,
0477    /* args: Addr. */
0478    /* Tell DRD that a user-defined semaphore synchronization
0479     * object is going to be acquired (semaphore wait). */
0480    VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_PRE,
0481    /* args: Addr. */
0482    /* Tell DRD that a user-defined semaphore synchronization
0483     * object has been acquired (semaphore wait). */
0484    VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_POST,
0485    /* args: Addr. */
0486    /* Tell DRD that a user-defined semaphore synchronization
0487     * object is about to be released (semaphore post). */
0488    VG_USERREQ__DRD_ANNOTATE_SEM_POST_PRE,
0489    /* args: Addr. */
0490 
0491    /* Tell DRD to ignore the inter-thread ordering introduced by a mutex. */
0492    VG_USERREQ__DRD_IGNORE_MUTEX_ORDERING,
0493    /* args: Addr. */
0494 
0495    /* Tell DRD that a user-defined reader-writer synchronization object
0496     * has been created. */
0497    VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE
0498       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 14,
0499    /* args: Addr. */
0500    /* Tell DRD that a user-defined reader-writer synchronization object
0501     * is about to be destroyed. */
0502    VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY
0503       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 15,
0504    /* args: Addr. */
0505    /* Tell DRD that a lock on a user-defined reader-writer synchronization
0506     * object has been acquired. */
0507    VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED
0508       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 17,
0509    /* args: Addr, Int is_rw. */
0510    /* Tell DRD that a lock on a user-defined reader-writer synchronization
0511     * object is about to be released. */
0512    VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED
0513       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 18,
0514    /* args: Addr, Int is_rw. */
0515 
0516    /* Tell DRD that a Helgrind annotation has not yet been implemented. */
0517    VG_USERREQ__HELGRIND_ANNOTATION_UNIMP
0518       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 32,
0519    /* args: char*. */
0520 
0521    /* Tell DRD to insert a happens-before annotation. */
0522    VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE
0523       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 33,
0524    /* args: Addr. */
0525    /* Tell DRD to insert a happens-after annotation. */
0526    VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER
0527       = VG_USERREQ_TOOL_BASE('H','G') + 256 + 34,
0528    /* args: Addr. */
0529 
0530 };
0531 
0532 
0533 /**
0534  * @addtogroup RaceDetectionAnnotations
0535  */
0536 /*@{*/
0537 
0538 #ifdef __cplusplus
0539 /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racy reads.
0540 
0541    Instead of doing
0542    ANNOTATE_IGNORE_READS_BEGIN();
0543    ... = x;
0544    ANNOTATE_IGNORE_READS_END();
0545    one can use
0546    ... = ANNOTATE_UNPROTECTED_READ(x); */
0547 template <typename T>
0548 inline T ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
0549    ANNOTATE_IGNORE_READS_BEGIN();
0550    const T result = x;
0551    ANNOTATE_IGNORE_READS_END();
0552    return result;
0553 }
0554 /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
0555 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)        \
0556    namespace {                              \
0557       static class static_var##_annotator               \
0558       {                                 \
0559       public:                               \
0560      static_var##_annotator()                   \
0561      {                              \
0562         ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \
0563                        #static_var ": " description);   \
0564      }                              \
0565       } the_##static_var##_annotator;                   \
0566    }
0567 #endif
0568 
0569 /*@}*/
0570 
0571 #endif /* __VALGRIND_DRD_H */