blob: 19c4a82b6adb0a28127632775fce033153e9e80c [file] [log] [blame]
bartbedfd232009-03-26 19:07:15 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
bart3c1e9d82008-06-30 17:10:29 +00002
3/*
bartbedfd232009-03-26 19:07:15 +00004 ----------------------------------------------------------------
bart3c1e9d82008-06-30 17:10:29 +00005
bartbedfd232009-03-26 19:07:15 +00006 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.
bart3c1e9d82008-06-30 17:10:29 +000011
bartbedfd232009-03-26 19:07:15 +000012 ----------------------------------------------------------------
bart3c1e9d82008-06-30 17:10:29 +000013
bartd45d9952009-05-31 18:53:54 +000014 This file is part of DRD, a Valgrind tool for verification of
bartbedfd232009-03-26 19:07:15 +000015 multithreaded programs.
bart3c1e9d82008-06-30 17:10:29 +000016
bartbedfd232009-03-26 19:07:15 +000017 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
18 All rights reserved.
bart3c1e9d82008-06-30 17:10:29 +000019
bartbedfd232009-03-26 19:07:15 +000020 Redistribution and use in source and binary forms, with or without
21 modification, are permitted provided that the following conditions
22 are met:
bart3c1e9d82008-06-30 17:10:29 +000023
bartbedfd232009-03-26 19:07:15 +000024 1. Redistributions of source code must retain the above copyright
25 notice, this list of conditions and the following disclaimer.
bart3c1e9d82008-06-30 17:10:29 +000026
bartbedfd232009-03-26 19:07:15 +000027 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.
bart3c1e9d82008-06-30 17:10:29 +000031
bartbedfd232009-03-26 19:07:15 +000032 3. Altered source versions must be plainly marked as such, and must
33 not be misrepresented as being the original software.
bart3c1e9d82008-06-30 17:10:29 +000034
bartbedfd232009-03-26 19:07:15 +000035 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.
bart3c1e9d82008-06-30 17:10:29 +000038
bartbedfd232009-03-26 19:07:15 +000039 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.
bart3c1e9d82008-06-30 17:10:29 +000050
bartbedfd232009-03-26 19:07:15 +000051 ----------------------------------------------------------------
bart3c1e9d82008-06-30 17:10:29 +000052
bartbedfd232009-03-26 19:07:15 +000053 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.
bart3c1e9d82008-06-30 17:10:29 +000057
bartbedfd232009-03-26 19:07:15 +000058 ----------------------------------------------------------------
bart3c1e9d82008-06-30 17:10:29 +000059*/
60
61#ifndef __VALGRIND_DRD_H
62#define __VALGRIND_DRD_H
63
64
65#include "valgrind.h"
66
67
bartd45d9952009-05-31 18:53:54 +000068/** Prefix for the (inline) functions defined in this header file. */
69#define DRDCL_(str) vgDrdCl_##str
70
71
72/** Obtain the thread ID assigned by Valgrind's core. */
73#define DRD_GET_VALGRIND_THREADID (DRDCL_(get_valgrind_threadid)())
74
75/** Obtain the thread ID assigned by DRD. */
76#define DRD_GET_DRD_THREADID (DRDCL_(get_drd_threadid)())
77
78/** Tell DRD not to complain about data races for the specified variable. */
79#define DRD_IGNORE_VAR(x) DRDCL_(ignore_range)(&(x), sizeof(x))
80
81/**
82 * Tell DRD to trace all memory accesses on the specified variable.
83 * until the memory that was allocated for the variable is freed.
84 */
85#define DRD_TRACE_VAR(x) DRDCL_(trace_range)(&(x), sizeof(x))
86
bart44afe932009-06-01 10:49:38 +000087/* !! APIWARNING !! APIWARNING !! APIWARNING !! APIWARNING !!
88 The semantics and the names of the macro's defined below are still
89 under discussion and subject to change without notice.
90*/
91
bartd45d9952009-05-31 18:53:54 +000092/**
93 * Tell DRD to insert a mark. addr is either the address of a pthread condition
94 * variable or the address of an object that is not a pthread synchronization
95 * object. Inserting two 'happens before' annotations while
96 * no thread has passed by a 'happens after' annotation is an error.
97 */
98#define ANNOTATE_HAPPENS_BEFORE(addr) DRDCL_(annotate_happens_before)(addr)
99
100/**
101 * Tell DRD that the memory accesses executed after this annotation will happen
102 * after the memory accesses performed before the most recent
103 * ANNOTATE_HAPPENS_BEFORE(addr). addr is either the address of a pthread
104 * condition variable or the address of an object that is not a pthread
105 * synchronization object. Inserting a 'happens after' annotation before any
106 * other thread has passed by a 'happens before' annotation for the same
107 * address or inserting two 'happens after' annotations while no thread has
108 * passed by a 'happens before' annotation is an error.
109 */
110#define ANNOTATE_HAPPENS_AFTER(addr) DRDCL_(annotate_happens_after)(addr)
111
112/**
113 * Tell DRD that no more ANNOTATE_HAPPENS_AFTER(addr) annotations
114 * will be inserted before the next ANNOTATE_HAPPENS_BEFORE(addr).
115 */
116#define ANNOTATE_HAPPENS_AFTER_DONE(addr) \
117 DRDCL_(annotate_happens_after_done)(addr)
118
119/**
120 * Tell DRD that waiting on the condition variable at address cv has succeeded
121 * and a lock on the mutex at address mtx is now held. Since DRD always inserts
122 * a happens before relation between the pthread_cond_signal() or
123 * pthread_cond_broadcast() call that wakes up a pthread_cond_wait() or
124 * pthread_cond_timedwait() call and the woken up thread, this macro has been
125 * left empty.
126 */
127#define ANNOTATE_CONDVAR_LOCK_WAIT(cv, mtx)
128
129/**
130 * Tell DRD that the condition variable at address cv is about to be signaled.
131 * cv is either the address of a condition variable or the address of an object
132 * that is not a POSIX synchronization object.
133 */
134#define ANNOTATE_CONDVAR_SIGNAL(cv) ANNOTATE_HAPPENS_BEFORE(cv)
135
136/**
137 * Tell DRD that waiting on condition variable at address cv succeeded.
138 * cv is either the address of a condition variable or the address of an object
139 * that is not a POSIX synchronization object.
140 */
141#define ANNOTATE_CONDVAR_WAIT(cv) ANNOTATE_HAPPENS_AFTER(cv)
142
143/**
144 * Tell DRD to consider the memory operations that happened before a mutex
145 * unlock event and after the subsequent mutex lock event on the same mutex as
146 * ordered. This is how DRD always behaves, so this macro has been left empty.
147 */
148#define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mtx)
149
150/** Tell DRD that a reader-writer lock object has been initialized. */
151#define ANNOTATE_RWLOCK_CREATE(rwlock) \
152 DRDCL_(annotate_rwlock)(rwlock, 0, 0)
153
154/** Tell DRD that a reader-writer lock object has been destroyed. */
155#define ANNOTATE_RWLOCK_DESTROY(rwlock) \
156 DRDCL_(annotate_rwlock)(rwlock, 1, 0)
157
158/**
159 * Tell DRD that a reader-writer lock has been acquired. is_w == 1 means that
160 * a write lock has been obtained, is_w == 0 means that a read lock has been
161 * obtained.
162 */
163#define ANNOTATE_RWLOCK_ACQUIRED(rwlock, is_w) \
164 DRDCL_(annotate_rwlock)(rwlock, 2, is_w)
165
166/**
167 * Tell DRD that a reader-writer lock is about to be released. is_w == 1 means
168 * that a write lock is about to be released, is_w == 0 means that a read lock
169 * is about to be released.
170 */
171#define ANNOTATE_RWLOCK_RELEASED(rwlock, is_w) \
172 DRDCL_(annotate_rwlock)(rwlock, 3, is_w)
173
174/**
175 * Tell DRD that data races in the specified address range are expected and
176 * must not be reported.
177 */
178#define ANNOTATE_BENIGN_RACE(addr, descr) DRDCL_(ignore_range)(addr, 4)
179
180/** Tell DRD to ignore all reads performed by the current thread. */
181#define ANNOTATE_IGNORE_READS_BEGIN() DRDCL_(set_record_loads)(0)
182
183/** Tell DRD to no longer ignore the reads performed by the current thread. */
184#define ANNOTATE_IGNORE_READS_END() DRDCL_(set_record_loads)(1)
185
186/** Tell DRD to ignore all writes performed by the current thread. */
187#define ANNOTATE_IGNORE_WRITES_BEGIN() DRDCL_(set_record_stores)(0)
188
189/** Tell DRD to no longer ignore the writes performed by the current thread. */
190#define ANNOTATE_IGNORE_WRITES_END() DRDCL_(set_record_stores)(1)
191
192/** Tell DRD to ignore all memory accesses performed by the current thread. */
193#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
194 do { DRDCL_(set_record_loads)(0); DRD_(set_record_stores)(0); } while(0)
195
196/**
197 * Tell DRD to no longer ignore the memory accesses performed by the current
198 * thread.
199 */
200#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
201 do { DRDCL_(set_record_loads)(1); DRD_(set_record_stores)(1); } while(0)
202
203/**
204 * Tell DRD that size bytes starting at addr has been allocated by a custom
205 * memory allocator.
206 */
207#define ANNOTATE_NEW_MEMORY(addr, size) DRDCL_(clean_memory)(addr, size)
208
209/** Ask DRD to report every access to the specified address range. */
210#define ANNOTATE_TRACE_MEMORY(addr) DRDCL_(trace_range)(addr, 1)
211
212/**
213 * Tell DRD to assign the specified name to the current thread. This name will
214 * be used in error messages printed by DRD.
215 */
216#define ANNOTATE_THREAD_NAME(name) DRDCL_(set_thread_name)(name)
217
bart44afe932009-06-01 10:49:38 +0000218/* !! APIWARNING !! APIWARNING !! APIWARNING !! APIWARNING !!
219 The semantics and the names of the macro's defined above are still
220 under discussion and subject to change without notice.
221*/
222
bartd45d9952009-05-31 18:53:54 +0000223
bart3c1e9d82008-06-30 17:10:29 +0000224/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
225 This enum comprises an ABI exported by Valgrind to programs
226 which use client requests. DO NOT CHANGE THE ORDER OF THESE
227 ENTRIES, NOR DELETE ANY -- add new ones at the end.
bartbedfd232009-03-26 19:07:15 +0000228*/
bartd45d9952009-05-31 18:53:54 +0000229enum {
230 /* Ask the DRD tool to discard all information about memory accesses */
231 /* and client objects for the specified range. This client request is */
232 /* binary compatible with the similarly named Helgrind client request. */
233 VG_USERREQ__DRD_CLEAN_MEMORY = VG_USERREQ_TOOL_BASE('H','G'),
234 /* args: Addr, SizeT. */
bart3c1e9d82008-06-30 17:10:29 +0000235
bartd45d9952009-05-31 18:53:54 +0000236 /* Ask the DRD tool the thread ID assigned by Valgrind. */
237 VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID = VG_USERREQ_TOOL_BASE('D','R'),
238 /* args: none. */
239 /* Ask the DRD tool the thread ID assigned by DRD. */
240 VG_USERREQ__DRD_GET_DRD_THREAD_ID,
241 /* args: none. */
bart3c1e9d82008-06-30 17:10:29 +0000242
bartd45d9952009-05-31 18:53:54 +0000243 /* To tell the DRD tool to suppress data race detection on the */
244 /* specified address range. */
245 VG_USERREQ__DRD_START_SUPPRESSION,
246 /* args: start address, size in bytes */
247 /* To tell the DRD tool no longer to suppress data race detection on */
248 /* the specified address range. */
249 VG_USERREQ__DRD_FINISH_SUPPRESSION,
250 /* args: start address, size in bytes */
barte7471762009-03-11 18:51:22 +0000251
bartd45d9952009-05-31 18:53:54 +0000252 /* To ask the DRD tool to trace all accesses to the specified range. */
253 VG_USERREQ__DRD_START_TRACE_ADDR,
254 /* args: Addr, SizeT. */
255 /* To ask the DRD tool to stop tracing accesses to the specified range. */
256 VG_USERREQ__DRD_STOP_TRACE_ADDR,
257 /* args: Addr, SizeT. */
258
259 /* Tell DRD whether or not to record memory loads in the calling thread. */
260 VG_USERREQ__DRD_RECORD_LOADS,
261 /* args: Bool. */
262 /* Tell DRD whether or not to record memory stores in the calling thread. */
263 VG_USERREQ__DRD_RECORD_STORES,
264 /* args: Bool. */
265
266 /* Set the name of the thread that performs this client request. */
267 VG_USERREQ__DRD_SET_THREAD_NAME,
268 /* args: null-terminated character string. */
269
270 /* Tell DRD to insert a happens before annotation. */
271 VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE,
272 /* args: Addr. */
273 /* Tell DRD to insert a happens after annotation. */
274 VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER,
275 /* args: Addr. */
276 /* Tell DRD that no more happens after annotations will follow until the
277 * next happens before annotation. */
278 VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER_DONE,
279 /* args: Addr. */
280
281 /* Tell DRD about an operation performed on a user-defined reader-writer
282 * synchronization object. */
283 VG_USERREQ__DRD_ANNOTATE_RWLOCK,
284 /* args: Addr, Int operation_type, Int is_rw. */
285};
bart3c1e9d82008-06-30 17:10:29 +0000286
287
bartd45d9952009-05-31 18:53:54 +0000288/*
289 * Do not call the inline functions below directly but use the macro's defined
290 * above. The names of these inline functions may change from one release to
291 * another.
bart8e1033f2008-12-25 09:31:40 +0000292 */
bart8e1033f2008-12-25 09:31:40 +0000293
bart3c1e9d82008-06-30 17:10:29 +0000294static __inline__
bartd45d9952009-05-31 18:53:54 +0000295void DRDCL_(clean_memory)(const void* const addr, const int size)
296{
297 int res;
298 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_CLEAN_MEMORY,
299 addr, size, 0, 0, 0);
300}
301
302static __inline__
303int DRDCL_(get_valgrind_threadid)(void)
bart5f57be92008-07-01 08:48:56 +0000304{
bartbedfd232009-03-26 19:07:15 +0000305 int res;
306 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID,
307 0, 0, 0, 0, 0);
308 return res;
bart5f57be92008-07-01 08:48:56 +0000309}
310
311static __inline__
bartd45d9952009-05-31 18:53:54 +0000312int DRDCL_(get_drd_threadid)(void)
bart3c1e9d82008-06-30 17:10:29 +0000313{
bartbedfd232009-03-26 19:07:15 +0000314 int res;
315 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_GET_DRD_THREAD_ID,
316 0, 0, 0, 0, 0);
317 return res;
bart3c1e9d82008-06-30 17:10:29 +0000318}
319
320static __inline__
bartd45d9952009-05-31 18:53:54 +0000321void DRDCL_(ignore_range)(const void* const addr, const int size)
bart3c1e9d82008-06-30 17:10:29 +0000322{
bartbedfd232009-03-26 19:07:15 +0000323 int res;
324 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_SUPPRESSION,
bartd45d9952009-05-31 18:53:54 +0000325 addr, size, 0, 0, 0);
bart3c1e9d82008-06-30 17:10:29 +0000326}
327
328static __inline__
bartd45d9952009-05-31 18:53:54 +0000329void DRDCL_(trace_range)(const void* const addr, const int size)
bart3c1e9d82008-06-30 17:10:29 +0000330{
bartbedfd232009-03-26 19:07:15 +0000331 int res;
332 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_TRACE_ADDR,
bartd45d9952009-05-31 18:53:54 +0000333 addr, size, 0, 0, 0);
bart3c1e9d82008-06-30 17:10:29 +0000334}
335
bartd45d9952009-05-31 18:53:54 +0000336static __inline__
337void DRDCL_(set_record_loads)(const int enabled)
338{
339 int res;
340 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_RECORD_LOADS,
341 enabled, 0, 0, 0, 0);
342}
343
344static __inline__
345void DRDCL_(set_record_stores)(const int enabled)
346{
347 int res;
348 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_RECORD_STORES,
349 enabled, 0, 0, 0, 0);
350}
351
352static __inline__
353void DRDCL_(set_thread_name)(const char* const name)
354{
355 int res;
356 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_SET_THREAD_NAME,
357 name, 0, 0, 0, 0);
358}
359
360static __inline__
361void DRDCL_(annotate_happens_before)(const void* const addr)
362{
363 int res;
364 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE,
365 addr, 0, 0, 0, 0);
366}
367
368static __inline__
369void DRDCL_(annotate_happens_after)(const void* const addr)
370{
371 int res;
372 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER,
373 addr, 0, 0, 0, 0);
374}
375
376static __inline__
377void DRDCL_(annotate_happens_after_done)(const void* const addr)
378{
379 int res;
380 VALGRIND_DO_CLIENT_REQUEST(res, 0,
381 VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER_DONE,
382 addr, 0, 0, 0, 0);
383}
384
385static __inline__
386void DRDCL_(annotate_rwlock)(const void* const rwlock, const int op,
387 const int is_w)
388{
389 int res;
390 VALGRIND_DO_CLIENT_REQUEST(res, 0,
391 VG_USERREQ__DRD_ANNOTATE_RWLOCK,
392 rwlock, op, is_w, 0, 0);
393}
bart3c1e9d82008-06-30 17:10:29 +0000394
395#endif /* __VALGRIND_DRD_H */