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