Vendor valgrind headers
All checks were successful
Tests / Release [gcc] total: 583, passed: 583
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Reference build: <a href="https://jenkins.weaselab.dev/job/weaselab/job/conflict-set/job/main/31//gcc">weaselab » conflict-set » main #31</a>
Tests / Coverage total: 581, passed: 581
weaselab/conflict-set/pipeline/head This commit looks good
All checks were successful
Tests / Release [gcc] total: 583, passed: 583
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Reference build: <a href="https://jenkins.weaselab.dev/job/weaselab/job/conflict-set/job/main/31//gcc">weaselab » conflict-set » main #31</a>
Tests / Coverage total: 581, passed: 581
weaselab/conflict-set/pipeline/head This commit looks good
This is encouraged according to https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
This commit is contained in:
98
third_party/valgrind/cachegrind.h
vendored
Normal file
98
third_party/valgrind/cachegrind.h
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the following BSD-style license applies to this one
|
||||
file (cachegrind.h) only. The rest of Valgrind is licensed under the
|
||||
terms of the GNU General Public License, version 2, unless
|
||||
otherwise indicated. See the COPYING file in the source
|
||||
distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
This file is part of Cachegrind, a high-precision tracing profiler
|
||||
built with Valgrind.
|
||||
|
||||
Copyright (C) 2023-2023 Nicholas Nethercote. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the above BSD-style license applies to this one file
|
||||
(cachegrind.h) only. The entire rest of Valgrind is licensed under
|
||||
the terms of the GNU General Public License, version 2. See the
|
||||
COPYING file in the source distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __CACHEGRIND_H
|
||||
#define __CACHEGRIND_H
|
||||
|
||||
#include "valgrind.h"
|
||||
|
||||
/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
|
||||
This enum comprises an ABI exported by Valgrind to programs
|
||||
which use client requests. DO NOT CHANGE THE ORDER OF THESE
|
||||
ENTRIES, NOR DELETE ANY -- add new ones at the end.
|
||||
*/
|
||||
|
||||
typedef
|
||||
enum {
|
||||
/* The `CG_` is required to distinguish these from the Callgrind
|
||||
* client requests of the same name. Otherwise compile errors occur if
|
||||
* you include both `cachegrind.h` and `callgrind.h`.
|
||||
*/
|
||||
VG_USERREQ__CG_START_INSTRUMENTATION = VG_USERREQ_TOOL_BASE('C','G'),
|
||||
VG_USERREQ__CG_STOP_INSTRUMENTATION
|
||||
} Vg_CachegrindClientRequest;
|
||||
|
||||
/* Start Cachegrind instrumentation if not already enabled. Use this
|
||||
* in combination with `CACHEGRIND_STOP_INSTRUMENTATION` and
|
||||
* `--instr-at-start` to measure only part of a client program's
|
||||
* execution.
|
||||
*/
|
||||
#define CACHEGRIND_START_INSTRUMENTATION \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CG_START_INSTRUMENTATION, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/* Stop Cachegrind instrumentation if not already disabled. Use this
|
||||
* in combination with `CACHEGRIND_START_INSTRUMENTATION` and
|
||||
* `--instr-at-start` to measure only part of a client program's
|
||||
* execution.
|
||||
*/
|
||||
#define CACHEGRIND_STOP_INSTRUMENTATION \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CG_STOP_INSTRUMENTATION, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
#endif /* __CACHEGRIND_H */
|
||||
|
129
third_party/valgrind/callgrind.h
vendored
Normal file
129
third_party/valgrind/callgrind.h
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the following BSD-style license applies to this one
|
||||
file (callgrind.h) only. The rest of Valgrind is licensed under the
|
||||
terms of the GNU General Public License, version 2, unless
|
||||
otherwise indicated. See the COPYING file in the source
|
||||
distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
This file is part of callgrind, a valgrind tool for cache simulation
|
||||
and call tree tracing.
|
||||
|
||||
Copyright (C) 2003-2017 Josef Weidendorfer. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the above BSD-style license applies to this one file
|
||||
(callgrind.h) only. The entire rest of Valgrind is licensed under
|
||||
the terms of the GNU General Public License, version 2. See the
|
||||
COPYING file in the source distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __CALLGRIND_H
|
||||
#define __CALLGRIND_H
|
||||
|
||||
#include "valgrind.h"
|
||||
|
||||
/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
|
||||
This enum comprises an ABI exported by Valgrind to programs
|
||||
which use client requests. DO NOT CHANGE THE ORDER OF THESE
|
||||
ENTRIES, NOR DELETE ANY -- add new ones at the end.
|
||||
|
||||
The identification ('C','T') for Callgrind has historical
|
||||
reasons: it was called "Calltree" before. Besides, ('C','G') would
|
||||
clash with cachegrind.
|
||||
*/
|
||||
|
||||
typedef
|
||||
enum {
|
||||
VG_USERREQ__DUMP_STATS = VG_USERREQ_TOOL_BASE('C','T'),
|
||||
VG_USERREQ__ZERO_STATS,
|
||||
VG_USERREQ__TOGGLE_COLLECT,
|
||||
VG_USERREQ__DUMP_STATS_AT,
|
||||
VG_USERREQ__START_INSTRUMENTATION,
|
||||
VG_USERREQ__STOP_INSTRUMENTATION
|
||||
} Vg_CallgrindClientRequest;
|
||||
|
||||
/* Dump current state of cost centers, and zero them afterwards */
|
||||
#define CALLGRIND_DUMP_STATS \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DUMP_STATS, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/* Dump current state of cost centers, and zero them afterwards.
|
||||
The argument is appended to a string stating the reason which triggered
|
||||
the dump. This string is written as a description field into the
|
||||
profile data dump. */
|
||||
#define CALLGRIND_DUMP_STATS_AT(pos_str) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DUMP_STATS_AT, \
|
||||
pos_str, 0, 0, 0, 0)
|
||||
|
||||
/* Zero cost centers */
|
||||
#define CALLGRIND_ZERO_STATS \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__ZERO_STATS, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/* Toggles collection state.
|
||||
The collection state specifies whether the happening of events
|
||||
should be noted or if they are to be ignored. Events are noted
|
||||
by increment of counters in a cost center */
|
||||
#define CALLGRIND_TOGGLE_COLLECT \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__TOGGLE_COLLECT, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/* Start full callgrind instrumentation if not already switched on.
|
||||
When cache simulation is done, it will flush the simulated cache;
|
||||
this will lead to an artificial cache warmup phase afterwards with
|
||||
cache misses which would not have happened in reality. */
|
||||
#define CALLGRIND_START_INSTRUMENTATION \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__START_INSTRUMENTATION, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/* Stop full callgrind instrumentation if not already switched off.
|
||||
This flushes Valgrinds translation cache, and does no additional
|
||||
instrumentation afterwards, which effectivly will run at the same
|
||||
speed as the "none" tool (ie. at minimal slowdown).
|
||||
Use this to bypass Callgrind aggregation for uninteresting code parts.
|
||||
To start Callgrind in this mode to ignore the setup phase, use
|
||||
the option "--instr-atstart=no". */
|
||||
#define CALLGRIND_STOP_INSTRUMENTATION \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STOP_INSTRUMENTATION, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
#endif /* __CALLGRIND_H */
|
86
third_party/valgrind/dhat.h
vendored
Normal file
86
third_party/valgrind/dhat.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the following BSD-style license applies to this one
|
||||
file (dhat.h) only. The rest of Valgrind is licensed under the
|
||||
terms of the GNU General Public License, version 2, unless
|
||||
otherwise indicated. See the COPYING file in the source
|
||||
distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
This file is part of DHAT, a Valgrind tool for profiling the
|
||||
heap usage of programs.
|
||||
|
||||
Copyright (C) 2020 Nicholas Nethercote. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the above BSD-style license applies to this one file
|
||||
(memcheck.h) only. The entire rest of Valgrind is licensed under
|
||||
the terms of the GNU General Public License, version 2. See the
|
||||
COPYING file in the source distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined(VALGRIND_DHAT_H)
|
||||
#define VALGRIND_DHAT_H
|
||||
|
||||
#include "valgrind.h"
|
||||
|
||||
typedef
|
||||
enum {
|
||||
VG_USERREQ__DHAT_AD_HOC_EVENT = VG_USERREQ_TOOL_BASE('D', 'H'),
|
||||
VG_USERREQ__DHAT_HISTOGRAM_MEMORY,
|
||||
|
||||
// This is just for DHAT's internal use. Don't use it.
|
||||
_VG_USERREQ__DHAT_COPY = VG_USERREQ_TOOL_BASE('D','H') + 256
|
||||
} Vg_DHATClientRequest;
|
||||
|
||||
// Record an ad hoc event. The meaning of the weight argument will depend on
|
||||
// what the event represents, which is up to the user. If no meaningful weight
|
||||
// argument exists, just use 1.
|
||||
#define DHAT_AD_HOC_EVENT(_qzz_weight) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DHAT_AD_HOC_EVENT, \
|
||||
(_qzz_weight), 0, 0, 0, 0)
|
||||
|
||||
// for access count histograms of memory larger than 1k
|
||||
#define DHAT_HISTOGRAM_MEMORY(_qzz_address) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DHAT_HISTOGRAM_MEMORY, \
|
||||
(_qzz_address), 0, 0, 0, 0)
|
||||
|
||||
#endif
|
||||
|
571
third_party/valgrind/drd.h
vendored
Normal file
571
third_party/valgrind/drd.h
vendored
Normal file
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the following BSD-style license applies to this one
|
||||
file (drd.h) only. The rest of Valgrind is licensed under the
|
||||
terms of the GNU General Public License, version 2, unless
|
||||
otherwise indicated. See the COPYING file in the source
|
||||
distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
This file is part of DRD, a Valgrind tool for verification of
|
||||
multithreaded programs.
|
||||
|
||||
Copyright (C) 2006-2020 Bart Van Assche <bvanassche@acm.org>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the above BSD-style license applies to this one file
|
||||
(drd.h) only. The entire rest of Valgrind is licensed under
|
||||
the terms of the GNU General Public License, version 2. See the
|
||||
COPYING file in the source distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __VALGRIND_DRD_H
|
||||
#define __VALGRIND_DRD_H
|
||||
|
||||
|
||||
#include "valgrind.h"
|
||||
|
||||
|
||||
/** Obtain the thread ID assigned by Valgrind's core. */
|
||||
#define DRD_GET_VALGRIND_THREADID \
|
||||
(unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
|
||||
VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/** Obtain the thread ID assigned by DRD. */
|
||||
#define DRD_GET_DRD_THREADID \
|
||||
(unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
|
||||
VG_USERREQ__DRD_GET_DRD_THREAD_ID, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
|
||||
/** Tell DRD not to complain about data races for the specified variable. */
|
||||
#define DRD_IGNORE_VAR(x) ANNOTATE_BENIGN_RACE_SIZED(&(x), sizeof(x), "")
|
||||
|
||||
/** Tell DRD to no longer ignore data races for the specified variable. */
|
||||
#define DRD_STOP_IGNORING_VAR(x) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_FINISH_SUPPRESSION, \
|
||||
&(x), sizeof(x), 0, 0, 0)
|
||||
|
||||
/**
|
||||
* Tell DRD to trace all memory accesses for the specified variable
|
||||
* until the memory that was allocated for the variable is freed.
|
||||
*/
|
||||
#define DRD_TRACE_VAR(x) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_TRACE_ADDR, \
|
||||
&(x), sizeof(x), 0, 0, 0)
|
||||
|
||||
/**
|
||||
* Tell DRD to stop tracing memory accesses for the specified variable.
|
||||
*/
|
||||
#define DRD_STOP_TRACING_VAR(x) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_STOP_TRACE_ADDR, \
|
||||
&(x), sizeof(x), 0, 0, 0)
|
||||
|
||||
/**
|
||||
* @defgroup RaceDetectionAnnotations Data race detection annotations.
|
||||
*
|
||||
* @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>
|
||||
|
||||
* in the ThreadSanitizer project.
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
#ifndef __HELGRIND_H
|
||||
|
||||
/**
|
||||
* Tell DRD to insert a happens-before mark. addr is the address of an object
|
||||
* that is not a pthread synchronization object.
|
||||
*/
|
||||
#define ANNOTATE_HAPPENS_BEFORE(addr) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE, \
|
||||
addr, 0, 0, 0, 0)
|
||||
|
||||
/**
|
||||
* Tell DRD that the memory accesses executed after this annotation will
|
||||
* happen after all memory accesses performed before all preceding
|
||||
* ANNOTATE_HAPPENS_BEFORE(addr). addr is the address of an object that is not
|
||||
* a pthread synchronization object. Inserting a happens-after annotation
|
||||
* before any other thread has passed by a happens-before annotation for the
|
||||
* same address is an error.
|
||||
*/
|
||||
#define ANNOTATE_HAPPENS_AFTER(addr) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER, \
|
||||
addr, 0, 0, 0, 0)
|
||||
|
||||
#else /* __HELGRIND_H */
|
||||
|
||||
#undef ANNOTATE_CONDVAR_LOCK_WAIT
|
||||
#undef ANNOTATE_CONDVAR_WAIT
|
||||
#undef ANNOTATE_CONDVAR_SIGNAL
|
||||
#undef ANNOTATE_CONDVAR_SIGNAL_ALL
|
||||
#undef ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX
|
||||
#undef ANNOTATE_PUBLISH_MEMORY_RANGE
|
||||
#undef ANNOTATE_BARRIER_INIT
|
||||
#undef ANNOTATE_BARRIER_WAIT_BEFORE
|
||||
#undef ANNOTATE_BARRIER_WAIT_AFTER
|
||||
#undef ANNOTATE_BARRIER_DESTROY
|
||||
#undef ANNOTATE_PCQ_CREATE
|
||||
#undef ANNOTATE_PCQ_DESTROY
|
||||
#undef ANNOTATE_PCQ_PUT
|
||||
#undef ANNOTATE_PCQ_GET
|
||||
#undef ANNOTATE_BENIGN_RACE
|
||||
#undef ANNOTATE_BENIGN_RACE_SIZED
|
||||
#undef ANNOTATE_IGNORE_READS_BEGIN
|
||||
#undef ANNOTATE_IGNORE_READS_END
|
||||
#undef ANNOTATE_IGNORE_WRITES_BEGIN
|
||||
#undef ANNOTATE_IGNORE_WRITES_END
|
||||
#undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN
|
||||
#undef ANNOTATE_IGNORE_READS_AND_WRITES_END
|
||||
#undef ANNOTATE_NEW_MEMORY
|
||||
#undef ANNOTATE_TRACE_MEMORY
|
||||
#undef ANNOTATE_THREAD_NAME
|
||||
|
||||
#endif /* __HELGRIND_H */
|
||||
|
||||
/**
|
||||
* Tell DRD that waiting on the condition variable at address cv has succeeded
|
||||
* and a lock on the mutex at address mtx is now held. Since DRD always inserts
|
||||
* a happens before relation between the pthread_cond_signal() or
|
||||
* pthread_cond_broadcast() call that wakes up a pthread_cond_wait() or
|
||||
* pthread_cond_timedwait() call and the woken up thread, this macro has been
|
||||
* defined such that it has no effect.
|
||||
*/
|
||||
#define ANNOTATE_CONDVAR_LOCK_WAIT(cv, mtx) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD that the condition variable at address cv is about to be signaled.
|
||||
*/
|
||||
#define ANNOTATE_CONDVAR_SIGNAL(cv) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD that the condition variable at address cv is about to be signaled.
|
||||
*/
|
||||
#define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD that waiting on condition variable at address cv succeeded and that
|
||||
* the memory operations performed after this annotation should be considered
|
||||
* to happen after the matching ANNOTATE_CONDVAR_SIGNAL(cv). Since this is the
|
||||
* default behavior of DRD, this macro and the macro above have been defined
|
||||
* such that they have no effect.
|
||||
*/
|
||||
#define ANNOTATE_CONDVAR_WAIT(cv) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD to consider the memory operations that happened before a mutex
|
||||
* unlock event and after the subsequent mutex lock event on the same mutex as
|
||||
* ordered. This is how DRD always behaves, so this macro has been defined
|
||||
* such that it has no effect.
|
||||
*/
|
||||
#define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mtx) do { } while(0)
|
||||
|
||||
/** Deprecated -- don't use this annotation. */
|
||||
#define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mtx) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD to handle the specified memory range like a pure happens-before
|
||||
* detector would do. Since this is how DRD always behaves, this annotation
|
||||
* has been defined such that it has no effect.
|
||||
*/
|
||||
#define ANNOTATE_PUBLISH_MEMORY_RANGE(addr, size) do { } while(0)
|
||||
|
||||
/** Deprecated -- don't use this annotation. */
|
||||
#define ANNOTATE_UNPUBLISH_MEMORY_RANGE(addr, size) do { } while(0)
|
||||
|
||||
/** Deprecated -- don't use this annotation. */
|
||||
#define ANNOTATE_SWAP_MEMORY_RANGE(addr, size) do { } while(0)
|
||||
|
||||
#ifndef __HELGRIND_H
|
||||
|
||||
/** Tell DRD that a reader-writer lock object has been initialized. */
|
||||
#define ANNOTATE_RWLOCK_CREATE(rwlock) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE, \
|
||||
rwlock, 0, 0, 0, 0);
|
||||
|
||||
/** Tell DRD that a reader-writer lock object has been destroyed. */
|
||||
#define ANNOTATE_RWLOCK_DESTROY(rwlock) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY, \
|
||||
rwlock, 0, 0, 0, 0);
|
||||
|
||||
/**
|
||||
* Tell DRD that a reader-writer lock has been acquired. is_w == 1 means that
|
||||
* a write lock has been obtained, is_w == 0 means that a read lock has been
|
||||
* obtained.
|
||||
*/
|
||||
#define ANNOTATE_RWLOCK_ACQUIRED(rwlock, is_w) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED, \
|
||||
rwlock, is_w, 0, 0, 0)
|
||||
|
||||
#endif /* __HELGRIND_H */
|
||||
|
||||
/**
|
||||
* Tell DRD that a reader lock has been acquired on a reader-writer
|
||||
* synchronization object.
|
||||
*/
|
||||
#define ANNOTATE_READERLOCK_ACQUIRED(rwlock) ANNOTATE_RWLOCK_ACQUIRED(rwlock, 0)
|
||||
|
||||
/**
|
||||
* Tell DRD that a writer lock has been acquired on a reader-writer
|
||||
* synchronization object.
|
||||
*/
|
||||
#define ANNOTATE_WRITERLOCK_ACQUIRED(rwlock) ANNOTATE_RWLOCK_ACQUIRED(rwlock, 1)
|
||||
|
||||
#ifndef __HELGRIND_H
|
||||
|
||||
/**
|
||||
* Tell DRD that a reader-writer lock is about to be released. is_w == 1 means
|
||||
* that a write lock is about to be released, is_w == 0 means that a read lock
|
||||
* is about to be released.
|
||||
*/
|
||||
#define ANNOTATE_RWLOCK_RELEASED(rwlock, is_w) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED, \
|
||||
rwlock, is_w, 0, 0, 0);
|
||||
|
||||
#endif /* __HELGRIND_H */
|
||||
|
||||
/**
|
||||
* Tell DRD that a reader lock is about to be released.
|
||||
*/
|
||||
#define ANNOTATE_READERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 0)
|
||||
|
||||
/**
|
||||
* Tell DRD that a writer lock is about to be released.
|
||||
*/
|
||||
#define ANNOTATE_WRITERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 1)
|
||||
|
||||
/** Tell DRD that a semaphore object is going to be initialized. */
|
||||
#define ANNOTATE_SEM_INIT_PRE(sem, value) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_INIT_PRE, \
|
||||
sem, value, 0, 0, 0);
|
||||
|
||||
/** Tell DRD that a semaphore object has been destroyed. */
|
||||
#define ANNOTATE_SEM_DESTROY_POST(sem) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_DESTROY_POST, \
|
||||
sem, 0, 0, 0, 0);
|
||||
|
||||
/** Tell DRD that a semaphore is going to be acquired. */
|
||||
#define ANNOTATE_SEM_WAIT_PRE(sem) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_PRE, \
|
||||
sem, 0, 0, 0, 0)
|
||||
|
||||
/** Tell DRD that a semaphore has been acquired. */
|
||||
#define ANNOTATE_SEM_WAIT_POST(sem) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_POST, \
|
||||
sem, 0, 0, 0, 0)
|
||||
|
||||
/** Tell DRD that a semaphore is going to be released. */
|
||||
#define ANNOTATE_SEM_POST_PRE(sem) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATE_SEM_POST_PRE, \
|
||||
sem, 0, 0, 0, 0)
|
||||
|
||||
/*
|
||||
* Report that a barrier has been initialized with a given barrier count. The
|
||||
* third argument specifies whether or not reinitialization is allowed, that
|
||||
* is, whether or not it is allowed to call barrier_init() several times
|
||||
* without calling barrier_destroy().
|
||||
*/
|
||||
#define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP, \
|
||||
"ANNOTATE_BARRIER_INIT", barrier, \
|
||||
count, reinitialization_allowed, 0)
|
||||
|
||||
/* Report that a barrier has been destroyed. */
|
||||
#define ANNOTATE_BARRIER_DESTROY(barrier) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP, \
|
||||
"ANNOTATE_BARRIER_DESTROY", \
|
||||
barrier, 0, 0, 0)
|
||||
|
||||
/* Report that the calling thread is about to start waiting for a barrier. */
|
||||
#define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP, \
|
||||
"ANNOTATE_BARRIER_WAIT_BEFORE", \
|
||||
barrier, 0, 0, 0)
|
||||
|
||||
/* Report that the calling thread has just finished waiting for a barrier. */
|
||||
#define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_ANNOTATION_UNIMP, \
|
||||
"ANNOTATE_BARRIER_WAIT_AFTER", \
|
||||
barrier, 0, 0, 0)
|
||||
|
||||
/**
|
||||
* Tell DRD that a FIFO queue has been created. The abbreviation PCQ stands for
|
||||
* <em>producer-consumer</em>.
|
||||
*/
|
||||
#define ANNOTATE_PCQ_CREATE(pcq) do { } while(0)
|
||||
|
||||
/** Tell DRD that a FIFO queue has been destroyed. */
|
||||
#define ANNOTATE_PCQ_DESTROY(pcq) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD that an element has been added to the FIFO queue at address pcq.
|
||||
*/
|
||||
#define ANNOTATE_PCQ_PUT(pcq) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD that an element has been removed from the FIFO queue at address pcq,
|
||||
* and that DRD should insert a happens-before relationship between the memory
|
||||
* accesses that occurred before the corresponding ANNOTATE_PCQ_PUT(pcq)
|
||||
* annotation and the memory accesses after this annotation. Correspondence
|
||||
* between PUT and GET annotations happens in FIFO order. Since locking
|
||||
* of the queue is needed anyway to add elements to or to remove elements from
|
||||
* the queue, for DRD all four FIFO annotations are defined as no-ops.
|
||||
*/
|
||||
#define ANNOTATE_PCQ_GET(pcq) do { } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD that data races at the specified address are expected and must not
|
||||
* be reported.
|
||||
*/
|
||||
#define ANNOTATE_BENIGN_RACE(addr, descr) \
|
||||
ANNOTATE_BENIGN_RACE_SIZED(addr, sizeof(*addr), descr)
|
||||
|
||||
/* Same as ANNOTATE_BENIGN_RACE(addr, descr), but applies to
|
||||
the memory range [addr, addr + size). */
|
||||
#define ANNOTATE_BENIGN_RACE_SIZED(addr, size, descr) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_SUPPRESSION, \
|
||||
addr, size, 0, 0, 0)
|
||||
|
||||
/** Tell DRD to ignore all reads performed by the current thread. */
|
||||
#define ANNOTATE_IGNORE_READS_BEGIN() \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_LOADS, \
|
||||
0, 0, 0, 0, 0);
|
||||
|
||||
|
||||
/** Tell DRD to no longer ignore the reads performed by the current thread. */
|
||||
#define ANNOTATE_IGNORE_READS_END() \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_LOADS, \
|
||||
1, 0, 0, 0, 0);
|
||||
|
||||
/** Tell DRD to ignore all writes performed by the current thread. */
|
||||
#define ANNOTATE_IGNORE_WRITES_BEGIN() \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_STORES, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/** Tell DRD to no longer ignore the writes performed by the current thread. */
|
||||
#define ANNOTATE_IGNORE_WRITES_END() \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_RECORD_STORES, \
|
||||
1, 0, 0, 0, 0)
|
||||
|
||||
/** Tell DRD to ignore all memory accesses performed by the current thread. */
|
||||
#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
|
||||
do { ANNOTATE_IGNORE_READS_BEGIN(); ANNOTATE_IGNORE_WRITES_BEGIN(); } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD to no longer ignore the memory accesses performed by the current
|
||||
* thread.
|
||||
*/
|
||||
#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
|
||||
do { ANNOTATE_IGNORE_READS_END(); ANNOTATE_IGNORE_WRITES_END(); } while(0)
|
||||
|
||||
/**
|
||||
* Tell DRD that size bytes starting at addr has been allocated by a custom
|
||||
* memory allocator.
|
||||
*/
|
||||
#define ANNOTATE_NEW_MEMORY(addr, size) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_CLEAN_MEMORY, \
|
||||
addr, size, 0, 0, 0)
|
||||
|
||||
/** Ask DRD to report every access to the specified address. */
|
||||
#define ANNOTATE_TRACE_MEMORY(addr) DRD_TRACE_VAR(*(char*)(addr))
|
||||
|
||||
/**
|
||||
* Tell DRD to assign the specified name to the current thread. This name will
|
||||
* be used in error messages printed by DRD.
|
||||
*/
|
||||
#define ANNOTATE_THREAD_NAME(name) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_SET_THREAD_NAME, \
|
||||
name, 0, 0, 0, 0)
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
|
||||
This enum comprises an ABI exported by Valgrind to programs
|
||||
which use client requests. DO NOT CHANGE THE ORDER OF THESE
|
||||
ENTRIES, NOR DELETE ANY -- add new ones at the end.
|
||||
*/
|
||||
enum {
|
||||
/* Ask the DRD tool to discard all information about memory accesses */
|
||||
/* and client objects for the specified range. This client request is */
|
||||
/* binary compatible with the similarly named Helgrind client request. */
|
||||
VG_USERREQ__DRD_CLEAN_MEMORY = VG_USERREQ_TOOL_BASE('H','G'),
|
||||
/* args: Addr, SizeT. */
|
||||
|
||||
/* Ask the DRD tool the thread ID assigned by Valgrind. */
|
||||
VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID = VG_USERREQ_TOOL_BASE('D','R'),
|
||||
/* args: none. */
|
||||
/* Ask the DRD tool the thread ID assigned by DRD. */
|
||||
VG_USERREQ__DRD_GET_DRD_THREAD_ID,
|
||||
/* args: none. */
|
||||
|
||||
/* To tell the DRD tool to suppress data race detection on the */
|
||||
/* specified address range. */
|
||||
VG_USERREQ__DRD_START_SUPPRESSION,
|
||||
/* args: start address, size in bytes */
|
||||
/* To tell the DRD tool no longer to suppress data race detection on */
|
||||
/* the specified address range. */
|
||||
VG_USERREQ__DRD_FINISH_SUPPRESSION,
|
||||
/* args: start address, size in bytes */
|
||||
|
||||
/* To ask the DRD tool to trace all accesses to the specified range. */
|
||||
VG_USERREQ__DRD_START_TRACE_ADDR,
|
||||
/* args: Addr, SizeT. */
|
||||
/* To ask the DRD tool to stop tracing accesses to the specified range. */
|
||||
VG_USERREQ__DRD_STOP_TRACE_ADDR,
|
||||
/* args: Addr, SizeT. */
|
||||
|
||||
/* Tell DRD whether or not to record memory loads in the calling thread. */
|
||||
VG_USERREQ__DRD_RECORD_LOADS,
|
||||
/* args: Bool. */
|
||||
/* Tell DRD whether or not to record memory stores in the calling thread. */
|
||||
VG_USERREQ__DRD_RECORD_STORES,
|
||||
/* args: Bool. */
|
||||
|
||||
/* Set the name of the thread that performs this client request. */
|
||||
VG_USERREQ__DRD_SET_THREAD_NAME,
|
||||
/* args: null-terminated character string. */
|
||||
|
||||
/* Tell DRD that a DRD annotation has not yet been implemented. */
|
||||
VG_USERREQ__DRD_ANNOTATION_UNIMP,
|
||||
/* args: char*. */
|
||||
|
||||
/* Tell DRD that a user-defined semaphore synchronization object
|
||||
* is about to be created. */
|
||||
VG_USERREQ__DRD_ANNOTATE_SEM_INIT_PRE,
|
||||
/* args: Addr, UInt value. */
|
||||
/* Tell DRD that a user-defined semaphore synchronization object
|
||||
* has been destroyed. */
|
||||
VG_USERREQ__DRD_ANNOTATE_SEM_DESTROY_POST,
|
||||
/* args: Addr. */
|
||||
/* Tell DRD that a user-defined semaphore synchronization
|
||||
* object is going to be acquired (semaphore wait). */
|
||||
VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_PRE,
|
||||
/* args: Addr. */
|
||||
/* Tell DRD that a user-defined semaphore synchronization
|
||||
* object has been acquired (semaphore wait). */
|
||||
VG_USERREQ__DRD_ANNOTATE_SEM_WAIT_POST,
|
||||
/* args: Addr. */
|
||||
/* Tell DRD that a user-defined semaphore synchronization
|
||||
* object is about to be released (semaphore post). */
|
||||
VG_USERREQ__DRD_ANNOTATE_SEM_POST_PRE,
|
||||
/* args: Addr. */
|
||||
|
||||
/* Tell DRD to ignore the inter-thread ordering introduced by a mutex. */
|
||||
VG_USERREQ__DRD_IGNORE_MUTEX_ORDERING,
|
||||
/* args: Addr. */
|
||||
|
||||
/* Tell DRD that a user-defined reader-writer synchronization object
|
||||
* has been created. */
|
||||
VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE
|
||||
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 14,
|
||||
/* args: Addr. */
|
||||
/* Tell DRD that a user-defined reader-writer synchronization object
|
||||
* is about to be destroyed. */
|
||||
VG_USERREQ__DRD_ANNOTATE_RWLOCK_DESTROY
|
||||
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 15,
|
||||
/* args: Addr. */
|
||||
/* Tell DRD that a lock on a user-defined reader-writer synchronization
|
||||
* object has been acquired. */
|
||||
VG_USERREQ__DRD_ANNOTATE_RWLOCK_ACQUIRED
|
||||
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 17,
|
||||
/* args: Addr, Int is_rw. */
|
||||
/* Tell DRD that a lock on a user-defined reader-writer synchronization
|
||||
* object is about to be released. */
|
||||
VG_USERREQ__DRD_ANNOTATE_RWLOCK_RELEASED
|
||||
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 18,
|
||||
/* args: Addr, Int is_rw. */
|
||||
|
||||
/* Tell DRD that a Helgrind annotation has not yet been implemented. */
|
||||
VG_USERREQ__HELGRIND_ANNOTATION_UNIMP
|
||||
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 32,
|
||||
/* args: char*. */
|
||||
|
||||
/* Tell DRD to insert a happens-before annotation. */
|
||||
VG_USERREQ__DRD_ANNOTATE_HAPPENS_BEFORE
|
||||
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 33,
|
||||
/* args: Addr. */
|
||||
/* Tell DRD to insert a happens-after annotation. */
|
||||
VG_USERREQ__DRD_ANNOTATE_HAPPENS_AFTER
|
||||
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 34,
|
||||
/* args: Addr. */
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup RaceDetectionAnnotations
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racy reads.
|
||||
|
||||
Instead of doing
|
||||
ANNOTATE_IGNORE_READS_BEGIN();
|
||||
... = x;
|
||||
ANNOTATE_IGNORE_READS_END();
|
||||
one can use
|
||||
... = ANNOTATE_UNPROTECTED_READ(x); */
|
||||
template <typename T>
|
||||
inline T ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
|
||||
ANNOTATE_IGNORE_READS_BEGIN();
|
||||
const T result = x;
|
||||
ANNOTATE_IGNORE_READS_END();
|
||||
return result;
|
||||
}
|
||||
/* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
|
||||
#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
|
||||
namespace { \
|
||||
static class static_var##_annotator \
|
||||
{ \
|
||||
public: \
|
||||
static_var##_annotator() \
|
||||
{ \
|
||||
ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \
|
||||
#static_var ": " description); \
|
||||
} \
|
||||
} the_##static_var##_annotator; \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* __VALGRIND_DRD_H */
|
830
third_party/valgrind/helgrind.h
vendored
Normal file
830
third_party/valgrind/helgrind.h
vendored
Normal file
@@ -0,0 +1,830 @@
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the above BSD-style license applies to this one file
|
||||
(helgrind.h) only. The entire rest of Valgrind is licensed under
|
||||
the terms of the GNU General Public License, version 2. See the
|
||||
COPYING file in the source distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
This file is part of Helgrind, a Valgrind tool for detecting errors
|
||||
in threaded programs.
|
||||
|
||||
Copyright (C) 2007-2017 OpenWorks LLP
|
||||
info@open-works.co.uk
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the above BSD-style license applies to this one file
|
||||
(helgrind.h) only. The entire rest of Valgrind is licensed under
|
||||
the terms of the GNU General Public License, version 2. See the
|
||||
COPYING file in the source distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __HELGRIND_H
|
||||
#define __HELGRIND_H
|
||||
|
||||
#include "valgrind.h"
|
||||
|
||||
/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
|
||||
This enum comprises an ABI exported by Valgrind to programs
|
||||
which use client requests. DO NOT CHANGE THE ORDER OF THESE
|
||||
ENTRIES, NOR DELETE ANY -- add new ones at the end. */
|
||||
typedef
|
||||
enum {
|
||||
VG_USERREQ__HG_CLEAN_MEMORY = VG_USERREQ_TOOL_BASE('H','G'),
|
||||
|
||||
/* The rest are for Helgrind's internal use. Not for end-user
|
||||
use. Do not use them unless you are a Valgrind developer. */
|
||||
|
||||
/* Notify the tool what this thread's pthread_t is. */
|
||||
_VG_USERREQ__HG_SET_MY_PTHREAD_T = VG_USERREQ_TOOL_BASE('H','G')
|
||||
+ 256,
|
||||
_VG_USERREQ__HG_PTH_API_ERROR, /* char*, int */
|
||||
_VG_USERREQ__HG_PTHREAD_JOIN_POST, /* pthread_t of quitter */
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_INIT_POST, /* pth_mx_t*, long mbRec */
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_DESTROY_PRE, /* pth_mx_t*, long isInit */
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE, /* pth_mx_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_POST, /* pth_mx_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_ACQUIRE_PRE, /* void*, long isTryLock */
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_ACQUIRE_POST, /* void* */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_SIGNAL_PRE, /* pth_cond_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_BROADCAST_PRE, /* pth_cond_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_WAIT_PRE, /* pth_cond_t*, pth_mx_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_WAIT_POST, /* pth_cond_t*, pth_mx_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_DESTROY_PRE, /* pth_cond_t*, long isInit */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_INIT_POST, /* pth_rwlk_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_DESTROY_PRE, /* pth_rwlk_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE, /* pth_rwlk_t*, long isW */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_ACQUIRED, /* void*, long isW */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_RELEASED, /* void* */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_UNLOCK_POST, /* pth_rwlk_t* */
|
||||
_VG_USERREQ__HG_POSIX_SEM_INIT_POST, /* sem_t*, ulong value */
|
||||
_VG_USERREQ__HG_POSIX_SEM_DESTROY_PRE, /* sem_t* */
|
||||
_VG_USERREQ__HG_POSIX_SEM_RELEASED, /* void* */
|
||||
_VG_USERREQ__HG_POSIX_SEM_ACQUIRED, /* void* */
|
||||
_VG_USERREQ__HG_PTHREAD_BARRIER_INIT_PRE, /* pth_bar_t*, ulong, ulong */
|
||||
_VG_USERREQ__HG_PTHREAD_BARRIER_WAIT_PRE, /* pth_bar_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_BARRIER_DESTROY_PRE, /* pth_bar_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_PRE, /* pth_slk_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_SPIN_INIT_OR_UNLOCK_POST, /* pth_slk_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_SPIN_LOCK_PRE, /* pth_slk_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_SPIN_LOCK_POST, /* pth_slk_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_SPIN_DESTROY_PRE, /* pth_slk_t* */
|
||||
_VG_USERREQ__HG_CLIENTREQ_UNIMP, /* char* */
|
||||
_VG_USERREQ__HG_USERSO_SEND_PRE, /* arbitrary UWord SO-tag */
|
||||
_VG_USERREQ__HG_USERSO_RECV_POST, /* arbitrary UWord SO-tag */
|
||||
_VG_USERREQ__HG_USERSO_FORGET_ALL, /* arbitrary UWord SO-tag */
|
||||
_VG_USERREQ__HG_RESERVED2, /* Do not use */
|
||||
_VG_USERREQ__HG_RESERVED3, /* Do not use */
|
||||
_VG_USERREQ__HG_RESERVED4, /* Do not use */
|
||||
_VG_USERREQ__HG_ARANGE_MAKE_UNTRACKED, /* Addr a, ulong len */
|
||||
_VG_USERREQ__HG_ARANGE_MAKE_TRACKED, /* Addr a, ulong len */
|
||||
_VG_USERREQ__HG_PTHREAD_BARRIER_RESIZE_PRE, /* pth_bar_t*, ulong */
|
||||
_VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK, /* Addr start_of_block */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_INIT_POST, /* pth_cond_t*, pth_cond_attr_t*/
|
||||
_VG_USERREQ__HG_GNAT_MASTER_HOOK, /* void*d,void*m,Word ml */
|
||||
_VG_USERREQ__HG_GNAT_MASTER_COMPLETED_HOOK, /* void*s,Word ml */
|
||||
_VG_USERREQ__HG_GET_ABITS, /* Addr a,Addr abits, ulong len */
|
||||
_VG_USERREQ__HG_PTHREAD_CREATE_BEGIN,
|
||||
_VG_USERREQ__HG_PTHREAD_CREATE_END,
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_PRE, /* pth_mx_t*,long isTryLock */
|
||||
_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST, /* pth_mx_t *,long tookLock */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST, /* pth_rwlk_t*,long isW,long */
|
||||
_VG_USERREQ__HG_PTHREAD_RWLOCK_UNLOCK_PRE, /* pth_rwlk_t* */
|
||||
_VG_USERREQ__HG_POSIX_SEM_POST_PRE, /* sem_t* */
|
||||
_VG_USERREQ__HG_POSIX_SEM_POST_POST, /* sem_t* */
|
||||
_VG_USERREQ__HG_POSIX_SEM_WAIT_PRE, /* sem_t* */
|
||||
_VG_USERREQ__HG_POSIX_SEM_WAIT_POST, /* sem_t*, long tookLock */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_SIGNAL_POST, /* pth_cond_t* */
|
||||
_VG_USERREQ__HG_PTHREAD_COND_BROADCAST_POST,/* pth_cond_t* */
|
||||
_VG_USERREQ__HG_RTLD_BIND_GUARD, /* int flags */
|
||||
_VG_USERREQ__HG_RTLD_BIND_CLEAR, /* int flags */
|
||||
_VG_USERREQ__HG_GNAT_DEPENDENT_MASTER_JOIN /* void*d, void*m */
|
||||
} Vg_TCheckClientRequest;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/*--- ---*/
|
||||
/*--- Implementation-only facilities. Not for end-user use. ---*/
|
||||
/*--- For end-user facilities see below (the next section in ---*/
|
||||
/*--- this file.) ---*/
|
||||
/*--- ---*/
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* Do a client request. These are macros rather than a functions so
|
||||
as to avoid having an extra frame in stack traces.
|
||||
|
||||
NB: these duplicate definitions in hg_intercepts.c. But here, we
|
||||
have to make do with weaker typing (no definition of Word etc) and
|
||||
no assertions, whereas in helgrind.h we can use those facilities.
|
||||
Obviously it's important the two sets of definitions are kept in
|
||||
sync.
|
||||
|
||||
The commented-out asserts should actually hold, but unfortunately
|
||||
they can't be allowed to be visible here, because that would
|
||||
require the end-user code to #include <assert.h>.
|
||||
*/
|
||||
|
||||
#define DO_CREQ_v_W(_creqF, _ty1F,_arg1F) \
|
||||
do { \
|
||||
long int _arg1; \
|
||||
/* assert(sizeof(_ty1F) == sizeof(long int)); */ \
|
||||
_arg1 = (long int)(_arg1F); \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT( \
|
||||
(_creqF), \
|
||||
_arg1, 0,0,0,0); \
|
||||
} while (0)
|
||||
|
||||
#define DO_CREQ_W_W(_resF, _dfltF, _creqF, _ty1F,_arg1F) \
|
||||
do { \
|
||||
long int _arg1; \
|
||||
/* assert(sizeof(_ty1F) == sizeof(long int)); */ \
|
||||
_arg1 = (long int)(_arg1F); \
|
||||
_qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR( \
|
||||
(_dfltF), \
|
||||
(_creqF), \
|
||||
_arg1, 0,0,0,0); \
|
||||
_resF = _qzz_res; \
|
||||
} while (0)
|
||||
|
||||
#define DO_CREQ_v_WW(_creqF, _ty1F,_arg1F, _ty2F,_arg2F) \
|
||||
do { \
|
||||
long int _arg1, _arg2; \
|
||||
/* assert(sizeof(_ty1F) == sizeof(long int)); */ \
|
||||
/* assert(sizeof(_ty2F) == sizeof(long int)); */ \
|
||||
_arg1 = (long int)(_arg1F); \
|
||||
_arg2 = (long int)(_arg2F); \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT( \
|
||||
(_creqF), \
|
||||
_arg1,_arg2,0,0,0); \
|
||||
} while (0)
|
||||
|
||||
#define DO_CREQ_v_WWW(_creqF, _ty1F,_arg1F, \
|
||||
_ty2F,_arg2F, _ty3F, _arg3F) \
|
||||
do { \
|
||||
long int _arg1, _arg2, _arg3; \
|
||||
/* assert(sizeof(_ty1F) == sizeof(long int)); */ \
|
||||
/* assert(sizeof(_ty2F) == sizeof(long int)); */ \
|
||||
/* assert(sizeof(_ty3F) == sizeof(long int)); */ \
|
||||
_arg1 = (long int)(_arg1F); \
|
||||
_arg2 = (long int)(_arg2F); \
|
||||
_arg3 = (long int)(_arg3F); \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT( \
|
||||
(_creqF), \
|
||||
_arg1,_arg2,_arg3,0,0); \
|
||||
} while (0)
|
||||
|
||||
#define DO_CREQ_W_WWW(_resF, _dfltF, _creqF, _ty1F,_arg1F, \
|
||||
_ty2F,_arg2F, _ty3F, _arg3F) \
|
||||
do { \
|
||||
long int _qzz_res; \
|
||||
long int _arg1, _arg2, _arg3; \
|
||||
/* assert(sizeof(_ty1F) == sizeof(long int)); */ \
|
||||
_arg1 = (long int)(_arg1F); \
|
||||
_arg2 = (long int)(_arg2F); \
|
||||
_arg3 = (long int)(_arg3F); \
|
||||
_qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR( \
|
||||
(_dfltF), \
|
||||
(_creqF), \
|
||||
_arg1,_arg2,_arg3,0,0); \
|
||||
_resF = _qzz_res; \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
#define _HG_CLIENTREQ_UNIMP(_qzz_str) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_CLIENTREQ_UNIMP, \
|
||||
(char*),(_qzz_str))
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/*--- ---*/
|
||||
/*--- Helgrind-native requests. These allow access to ---*/
|
||||
/*--- the same set of annotation primitives that are used ---*/
|
||||
/*--- to build the POSIX pthread wrappers. ---*/
|
||||
/*--- ---*/
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* ----------------------------------------------------------
|
||||
For describing ordinary mutexes (non-rwlocks). For rwlock
|
||||
descriptions see ANNOTATE_RWLOCK_* below.
|
||||
---------------------------------------------------------- */
|
||||
|
||||
/* Notify here immediately after mutex creation. _mbRec == 0 for a
|
||||
non-recursive mutex, 1 for a recursive mutex. */
|
||||
#define VALGRIND_HG_MUTEX_INIT_POST(_mutex, _mbRec) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_MUTEX_INIT_POST, \
|
||||
void*,(_mutex), long,(_mbRec))
|
||||
|
||||
/* Notify here immediately before mutex acquisition. _isTryLock == 0
|
||||
for a normal acquisition, 1 for a "try" style acquisition. */
|
||||
#define VALGRIND_HG_MUTEX_LOCK_PRE(_mutex, _isTryLock) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_MUTEX_ACQUIRE_PRE, \
|
||||
void*,(_mutex), long,(_isTryLock))
|
||||
|
||||
/* Notify here immediately after a successful mutex acquisition. */
|
||||
#define VALGRIND_HG_MUTEX_LOCK_POST(_mutex) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_ACQUIRE_POST, \
|
||||
void*,(_mutex))
|
||||
|
||||
/* Notify here immediately before a mutex release. */
|
||||
#define VALGRIND_HG_MUTEX_UNLOCK_PRE(_mutex) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE, \
|
||||
void*,(_mutex))
|
||||
|
||||
/* Notify here immediately after a mutex release. */
|
||||
#define VALGRIND_HG_MUTEX_UNLOCK_POST(_mutex) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_POST, \
|
||||
void*,(_mutex))
|
||||
|
||||
/* Notify here immediately before mutex destruction. */
|
||||
#define VALGRIND_HG_MUTEX_DESTROY_PRE(_mutex) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_DESTROY_PRE, \
|
||||
void*,(_mutex))
|
||||
|
||||
/* ----------------------------------------------------------
|
||||
For describing semaphores.
|
||||
---------------------------------------------------------- */
|
||||
|
||||
/* Notify here immediately after semaphore creation. */
|
||||
#define VALGRIND_HG_SEM_INIT_POST(_sem, _value) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_POSIX_SEM_INIT_POST, \
|
||||
void*, (_sem), unsigned long, (_value))
|
||||
|
||||
/* Notify here immediately after a semaphore wait (an acquire-style
|
||||
operation) */
|
||||
#define VALGRIND_HG_SEM_WAIT_POST(_sem) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_POSIX_SEM_ACQUIRED, \
|
||||
void*,(_sem))
|
||||
|
||||
/* Notify here immediately before semaphore post (a release-style
|
||||
operation) */
|
||||
#define VALGRIND_HG_SEM_POST_PRE(_sem) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_POSIX_SEM_RELEASED, \
|
||||
void*,(_sem))
|
||||
|
||||
/* Notify here immediately before semaphore destruction. */
|
||||
#define VALGRIND_HG_SEM_DESTROY_PRE(_sem) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_POSIX_SEM_DESTROY_PRE, \
|
||||
void*, (_sem))
|
||||
|
||||
/* ----------------------------------------------------------
|
||||
For describing barriers.
|
||||
---------------------------------------------------------- */
|
||||
|
||||
/* Notify here immediately before barrier creation. _count is the
|
||||
capacity. _resizable == 0 means the barrier may not be resized, 1
|
||||
means it may be. */
|
||||
#define VALGRIND_HG_BARRIER_INIT_PRE(_bar, _count, _resizable) \
|
||||
DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_BARRIER_INIT_PRE, \
|
||||
void*,(_bar), \
|
||||
unsigned long,(_count), \
|
||||
unsigned long,(_resizable))
|
||||
|
||||
/* Notify here immediately before arrival at a barrier. */
|
||||
#define VALGRIND_HG_BARRIER_WAIT_PRE(_bar) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_BARRIER_WAIT_PRE, \
|
||||
void*,(_bar))
|
||||
|
||||
/* Notify here immediately before a resize (change of barrier
|
||||
capacity). If _newcount >= the existing capacity, then there is no
|
||||
change in the state of any threads waiting at the barrier. If
|
||||
_newcount < the existing capacity, and >= _newcount threads are
|
||||
currently waiting at the barrier, then this notification is
|
||||
considered to also have the effect of telling the checker that all
|
||||
waiting threads have now moved past the barrier. (I can't think of
|
||||
any other sane semantics.) */
|
||||
#define VALGRIND_HG_BARRIER_RESIZE_PRE(_bar, _newcount) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_BARRIER_RESIZE_PRE, \
|
||||
void*,(_bar), \
|
||||
unsigned long,(_newcount))
|
||||
|
||||
/* Notify here immediately before barrier destruction. */
|
||||
#define VALGRIND_HG_BARRIER_DESTROY_PRE(_bar) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_BARRIER_DESTROY_PRE, \
|
||||
void*,(_bar))
|
||||
|
||||
/* ----------------------------------------------------------
|
||||
For describing memory ownership changes.
|
||||
---------------------------------------------------------- */
|
||||
|
||||
/* Clean memory state. This makes Helgrind forget everything it knew
|
||||
about the specified memory range. Effectively this announces that
|
||||
the specified memory range now "belongs" to the calling thread, so
|
||||
that: (1) the calling thread can access it safely without
|
||||
synchronisation, and (2) all other threads must sync with this one
|
||||
to access it safely. This is particularly useful for memory
|
||||
allocators that wish to recycle memory. */
|
||||
#define VALGRIND_HG_CLEAN_MEMORY(_qzz_start, _qzz_len) \
|
||||
DO_CREQ_v_WW(VG_USERREQ__HG_CLEAN_MEMORY, \
|
||||
void*,(_qzz_start), \
|
||||
unsigned long,(_qzz_len))
|
||||
|
||||
/* The same, but for the heap block starting at _qzz_blockstart. This
|
||||
allows painting when we only know the address of an object, but not
|
||||
its size, which is sometimes the case in C++ code involving
|
||||
inheritance, and in which RTTI is not, for whatever reason,
|
||||
available. Returns the number of bytes painted, which can be zero
|
||||
for a zero-sized block. Hence, return values >= 0 indicate success
|
||||
(the block was found), and the value -1 indicates block not
|
||||
found, and -2 is returned when not running on Helgrind. */
|
||||
#define VALGRIND_HG_CLEAN_MEMORY_HEAPBLOCK(_qzz_blockstart) \
|
||||
(__extension__ \
|
||||
({long int _npainted; \
|
||||
DO_CREQ_W_W(_npainted, (-2)/*default*/, \
|
||||
_VG_USERREQ__HG_CLEAN_MEMORY_HEAPBLOCK, \
|
||||
void*,(_qzz_blockstart)); \
|
||||
_npainted; \
|
||||
}))
|
||||
|
||||
/* ----------------------------------------------------------
|
||||
For error control.
|
||||
---------------------------------------------------------- */
|
||||
|
||||
/* Tell H that an address range is not to be "tracked" until further
|
||||
notice. This puts it in the NOACCESS state, in which case we
|
||||
ignore all reads and writes to it. Useful for ignoring ranges of
|
||||
memory where there might be races we don't want to see. If the
|
||||
memory is subsequently reallocated via malloc/new/stack allocation,
|
||||
then it is put back in the trackable state. Hence it is safe in
|
||||
the situation where checking is disabled, the containing area is
|
||||
deallocated and later reallocated for some other purpose. */
|
||||
#define VALGRIND_HG_DISABLE_CHECKING(_qzz_start, _qzz_len) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_ARANGE_MAKE_UNTRACKED, \
|
||||
void*,(_qzz_start), \
|
||||
unsigned long,(_qzz_len))
|
||||
|
||||
/* And put it back into the normal "tracked" state, that is, make it
|
||||
once again subject to the normal race-checking machinery. This
|
||||
puts it in the same state as new memory allocated by this thread --
|
||||
that is, basically owned exclusively by this thread. */
|
||||
#define VALGRIND_HG_ENABLE_CHECKING(_qzz_start, _qzz_len) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_ARANGE_MAKE_TRACKED, \
|
||||
void*,(_qzz_start), \
|
||||
unsigned long,(_qzz_len))
|
||||
|
||||
|
||||
/* Checks the accessibility bits for addresses [zza..zza+zznbytes-1].
|
||||
If zzabits array is provided, copy the accessibility bits in zzabits.
|
||||
Return values:
|
||||
-2 if not running on helgrind
|
||||
-1 if any parts of zzabits is not addressable
|
||||
>= 0 : success.
|
||||
When success, it returns the nr of addressable bytes found.
|
||||
So, to check that a whole range is addressable, check
|
||||
VALGRIND_HG_GET_ABITS(addr,NULL,len) == len
|
||||
In addition, if you want to examine the addressability of each
|
||||
byte of the range, you need to provide a non NULL ptr as
|
||||
second argument, pointing to an array of unsigned char
|
||||
of length len.
|
||||
Addressable bytes are indicated with 0xff.
|
||||
Non-addressable bytes are indicated with 0x00.
|
||||
*/
|
||||
#define VALGRIND_HG_GET_ABITS(zza,zzabits,zznbytes) \
|
||||
(__extension__ \
|
||||
({long int _res; \
|
||||
DO_CREQ_W_WWW(_res, (-2)/*default*/, \
|
||||
_VG_USERREQ__HG_GET_ABITS, \
|
||||
void*,(zza), void*,(zzabits), \
|
||||
unsigned long,(zznbytes)); \
|
||||
_res; \
|
||||
}))
|
||||
|
||||
/* End-user request for Ada applications compiled with GNAT.
|
||||
Helgrind understands the Ada concept of Ada task dependencies and
|
||||
terminations. See Ada Reference Manual section 9.3 "Task Dependence
|
||||
- Termination of Tasks".
|
||||
However, in some cases, the master of (terminated) tasks completes
|
||||
only when the application exits. An example of this is dynamically
|
||||
allocated tasks with an access type defined at Library Level.
|
||||
By default, the state of such tasks in Helgrind will be 'exited but
|
||||
join not done yet'. Many tasks in such a state are however causing
|
||||
Helgrind CPU and memory to increase significantly.
|
||||
VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN can be used to indicate
|
||||
to Helgrind that a not yet completed master has however already
|
||||
'seen' the termination of a dependent : this is conceptually the
|
||||
same as a pthread_join and causes the cleanup of the dependent
|
||||
as done by Helgrind when a master completes.
|
||||
This allows to avoid the overhead in helgrind caused by such tasks.
|
||||
A typical usage for a master to indicate it has done conceptually a join
|
||||
with a dependent task before the master completes is:
|
||||
while not Dep_Task'Terminated loop
|
||||
... do whatever to wait for Dep_Task termination.
|
||||
end loop;
|
||||
VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN
|
||||
(Dep_Task'Identity,
|
||||
Ada.Task_Identification.Current_Task);
|
||||
Note that VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN should be a binding
|
||||
to a C function built with the below macro. */
|
||||
#define VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN(_qzz_dep, _qzz_master) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_GNAT_DEPENDENT_MASTER_JOIN, \
|
||||
void*,(_qzz_dep), \
|
||||
void*,(_qzz_master))
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
/*--- ---*/
|
||||
/*--- ThreadSanitizer-compatible requests ---*/
|
||||
/*--- (mostly unimplemented) ---*/
|
||||
/*--- ---*/
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* A quite-broad set of annotations, as used in the ThreadSanitizer
|
||||
project. This implementation aims to be a (source-level)
|
||||
compatible implementation of the macros defined in:
|
||||
|
||||
http://code.google.com/p/data-race-test/source
|
||||
/browse/trunk/dynamic_annotations/dynamic_annotations.h
|
||||
|
||||
(some of the comments below are taken from the above file)
|
||||
|
||||
The implementation here is very incomplete, and intended as a
|
||||
starting point. Many of the macros are unimplemented. Rather than
|
||||
allowing unimplemented macros to silently do nothing, they cause an
|
||||
assertion. Intention is to implement them on demand.
|
||||
|
||||
The major use of these macros is to make visible to race detectors,
|
||||
the behaviour (effects) of user-implemented synchronisation
|
||||
primitives, that the detectors could not otherwise deduce from the
|
||||
normal observation of pthread etc calls.
|
||||
|
||||
Some of the macros are no-ops in Helgrind. That's because Helgrind
|
||||
is a pure happens-before detector, whereas ThreadSanitizer uses a
|
||||
hybrid lockset and happens-before scheme, which requires more
|
||||
accurate annotations for correct operation.
|
||||
|
||||
The macros are listed in the same order as in dynamic_annotations.h
|
||||
(URL just above).
|
||||
|
||||
I should point out that I am less than clear about the intended
|
||||
semantics of quite a number of them. Comments and clarifications
|
||||
welcomed!
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
These four allow description of user-level condition variables,
|
||||
apparently in the style of POSIX's pthread_cond_t. Currently
|
||||
unimplemented and will assert.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
/* Report that wait on the condition variable at address CV has
|
||||
succeeded and the lock at address LOCK is now held. CV and LOCK
|
||||
are completely arbitrary memory addresses which presumably mean
|
||||
something to the application, but are meaningless to Helgrind. */
|
||||
#define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_CONDVAR_LOCK_WAIT")
|
||||
|
||||
/* Report that wait on the condition variable at CV has succeeded.
|
||||
Variant w/o lock. */
|
||||
#define ANNOTATE_CONDVAR_WAIT(cv) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_CONDVAR_WAIT")
|
||||
|
||||
/* Report that we are about to signal on the condition variable at
|
||||
address CV. */
|
||||
#define ANNOTATE_CONDVAR_SIGNAL(cv) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_CONDVAR_SIGNAL")
|
||||
|
||||
/* Report that we are about to signal_all on the condition variable at
|
||||
CV. */
|
||||
#define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_CONDVAR_SIGNAL_ALL")
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Create completely arbitrary happens-before edges between threads.
|
||||
|
||||
If threads T1 .. Tn all do ANNOTATE_HAPPENS_BEFORE(obj) and later
|
||||
(w.r.t. some notional global clock for the computation) thread Tm
|
||||
does ANNOTATE_HAPPENS_AFTER(obj), then Helgrind will regard all
|
||||
memory accesses done by T1 .. Tn before the ..BEFORE.. call as
|
||||
happening-before all memory accesses done by Tm after the
|
||||
..AFTER.. call. Hence Helgrind won't complain about races if Tm's
|
||||
accesses afterwards are to the same locations as accesses before by
|
||||
any of T1 .. Tn.
|
||||
|
||||
OBJ is a machine word (unsigned long, or void*), is completely
|
||||
arbitrary, and denotes the identity of some synchronisation object
|
||||
you're modelling.
|
||||
|
||||
You must do the _BEFORE call just before the real sync event on the
|
||||
signaller's side, and _AFTER just after the real sync event on the
|
||||
waiter's side.
|
||||
|
||||
If none of the rest of these macros make sense to you, at least
|
||||
take the time to understand these two. They form the very essence
|
||||
of describing arbitrary inter-thread synchronisation events to
|
||||
Helgrind. You can get a long way just with them alone.
|
||||
|
||||
See also, extensive discussion on semantics of this in
|
||||
https://bugs.kde.org/show_bug.cgi?id=243935
|
||||
|
||||
ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(obj) is interim until such time
|
||||
as bug 243935 is fully resolved. It instructs Helgrind to forget
|
||||
about any ANNOTATE_HAPPENS_BEFORE calls on the specified object, in
|
||||
effect putting it back in its original state. Once in that state,
|
||||
a use of ANNOTATE_HAPPENS_AFTER on it has no effect on the calling
|
||||
thread.
|
||||
|
||||
An implementation may optionally release resources it has
|
||||
associated with 'obj' when ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(obj)
|
||||
happens. Users are recommended to use
|
||||
ANNOTATE_HAPPENS_BEFORE_FORGET_ALL to indicate when a
|
||||
synchronisation object is no longer needed, so as to avoid
|
||||
potential indefinite resource leaks.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
#define ANNOTATE_HAPPENS_BEFORE(obj) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_USERSO_SEND_PRE, void*,(obj))
|
||||
|
||||
#define ANNOTATE_HAPPENS_AFTER(obj) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_USERSO_RECV_POST, void*,(obj))
|
||||
|
||||
#define ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(obj) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_USERSO_FORGET_ALL, void*,(obj))
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Memory publishing. The TSan sources say:
|
||||
|
||||
Report that the bytes in the range [pointer, pointer+size) are about
|
||||
to be published safely. The race checker will create a happens-before
|
||||
arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to
|
||||
subsequent accesses to this memory.
|
||||
|
||||
I'm not sure I understand what this means exactly, nor whether it
|
||||
is relevant for a pure h-b detector. Leaving unimplemented for
|
||||
now.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
#define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_PUBLISH_MEMORY_RANGE")
|
||||
|
||||
/* DEPRECATED. Don't use it. */
|
||||
/* #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) */
|
||||
|
||||
/* DEPRECATED. Don't use it. */
|
||||
/* #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size) */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
TSan sources say:
|
||||
|
||||
Instruct the tool to create a happens-before arc between
|
||||
MU->Unlock() and MU->Lock(). This annotation may slow down the
|
||||
race detector; normally it is used only when it would be
|
||||
difficult to annotate each of the mutex's critical sections
|
||||
individually using the annotations above.
|
||||
|
||||
If MU is a posix pthread_mutex_t then Helgrind will do this anyway.
|
||||
In any case, leave as unimp for now. I'm unsure about the intended
|
||||
behaviour.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
#define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX")
|
||||
|
||||
/* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */
|
||||
/* #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
TSan sources say:
|
||||
|
||||
Annotations useful when defining memory allocators, or when
|
||||
memory that was protected in one way starts to be protected in
|
||||
another.
|
||||
|
||||
Report that a new memory at "address" of size "size" has been
|
||||
allocated. This might be used when the memory has been retrieved
|
||||
from a free list and is about to be reused, or when a the locking
|
||||
discipline for a variable changes.
|
||||
|
||||
AFAICS this is the same as VALGRIND_HG_CLEAN_MEMORY.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
#define ANNOTATE_NEW_MEMORY(address, size) \
|
||||
VALGRIND_HG_CLEAN_MEMORY((address), (size))
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
TSan sources say:
|
||||
|
||||
Annotations useful when defining FIFO queues that transfer data
|
||||
between threads.
|
||||
|
||||
All unimplemented. Am not claiming to understand this (yet).
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Report that the producer-consumer queue object at address PCQ has
|
||||
been created. The ANNOTATE_PCQ_* annotations should be used only
|
||||
for FIFO queues. For non-FIFO queues use ANNOTATE_HAPPENS_BEFORE
|
||||
(for put) and ANNOTATE_HAPPENS_AFTER (for get). */
|
||||
#define ANNOTATE_PCQ_CREATE(pcq) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_PCQ_CREATE")
|
||||
|
||||
/* Report that the queue at address PCQ is about to be destroyed. */
|
||||
#define ANNOTATE_PCQ_DESTROY(pcq) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_PCQ_DESTROY")
|
||||
|
||||
/* Report that we are about to put an element into a FIFO queue at
|
||||
address PCQ. */
|
||||
#define ANNOTATE_PCQ_PUT(pcq) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_PCQ_PUT")
|
||||
|
||||
/* Report that we've just got an element from a FIFO queue at address
|
||||
PCQ. */
|
||||
#define ANNOTATE_PCQ_GET(pcq) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_PCQ_GET")
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Annotations that suppress errors. It is usually better to express
|
||||
the program's synchronization using the other annotations, but
|
||||
these can be used when all else fails.
|
||||
|
||||
Currently these are all unimplemented. I can't think of a simple
|
||||
way to implement them without at least some performance overhead.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Report that we may have a benign race at "pointer", with size
|
||||
"sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the
|
||||
point where "pointer" has been allocated, preferably close to the point
|
||||
where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC.
|
||||
|
||||
XXX: what's this actually supposed to do? And what's the type of
|
||||
DESCRIPTION? When does the annotation stop having an effect?
|
||||
*/
|
||||
#define ANNOTATE_BENIGN_RACE(pointer, description) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_BENIGN_RACE")
|
||||
|
||||
/* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to
|
||||
the memory range [address, address+size). */
|
||||
#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
|
||||
VALGRIND_HG_DISABLE_CHECKING(address, size)
|
||||
|
||||
/* Request the analysis tool to ignore all reads in the current thread
|
||||
until ANNOTATE_IGNORE_READS_END is called. Useful to ignore
|
||||
intentional racey reads, while still checking other reads and all
|
||||
writes. */
|
||||
#define ANNOTATE_IGNORE_READS_BEGIN() \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_IGNORE_READS_BEGIN")
|
||||
|
||||
/* Stop ignoring reads. */
|
||||
#define ANNOTATE_IGNORE_READS_END() \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_IGNORE_READS_END")
|
||||
|
||||
/* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */
|
||||
#define ANNOTATE_IGNORE_WRITES_BEGIN() \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_IGNORE_WRITES_BEGIN")
|
||||
|
||||
/* Stop ignoring writes. */
|
||||
#define ANNOTATE_IGNORE_WRITES_END() \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_IGNORE_WRITES_END")
|
||||
|
||||
/* Start ignoring all memory accesses (reads and writes). */
|
||||
#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
|
||||
do { \
|
||||
ANNOTATE_IGNORE_READS_BEGIN(); \
|
||||
ANNOTATE_IGNORE_WRITES_BEGIN(); \
|
||||
} while (0)
|
||||
|
||||
/* Stop ignoring all memory accesses. */
|
||||
#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
|
||||
do { \
|
||||
ANNOTATE_IGNORE_WRITES_END(); \
|
||||
ANNOTATE_IGNORE_READS_END(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Annotations useful for debugging.
|
||||
|
||||
Again, so for unimplemented, partly for performance reasons.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Request to trace every access to ADDRESS. */
|
||||
#define ANNOTATE_TRACE_MEMORY(address) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_TRACE_MEMORY")
|
||||
|
||||
/* Report the current thread name to a race detector. */
|
||||
#define ANNOTATE_THREAD_NAME(name) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_THREAD_NAME")
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Annotations for describing behaviour of user-implemented lock
|
||||
primitives. In all cases, the LOCK argument is a completely
|
||||
arbitrary machine word (unsigned long, or void*) and can be any
|
||||
value which gives a unique identity to the lock objects being
|
||||
modelled.
|
||||
|
||||
We just pretend they're ordinary posix rwlocks. That'll probably
|
||||
give some rather confusing wording in error messages, claiming that
|
||||
the arbitrary LOCK values are pthread_rwlock_t*'s, when in fact
|
||||
they are not. Ah well.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
/* Report that a lock has just been created at address LOCK. */
|
||||
#define ANNOTATE_RWLOCK_CREATE(lock) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_RWLOCK_INIT_POST, \
|
||||
void*,(lock))
|
||||
|
||||
/* Report that the lock at address LOCK is about to be destroyed. */
|
||||
#define ANNOTATE_RWLOCK_DESTROY(lock) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_RWLOCK_DESTROY_PRE, \
|
||||
void*,(lock))
|
||||
|
||||
/* Report that the lock at address LOCK has just been acquired.
|
||||
is_w=1 for writer lock, is_w=0 for reader lock. */
|
||||
#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
|
||||
DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_RWLOCK_ACQUIRED, \
|
||||
void*,(lock), unsigned long,(is_w))
|
||||
|
||||
/* Report that the lock at address LOCK is about to be released. */
|
||||
#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
|
||||
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_RWLOCK_RELEASED, \
|
||||
void*,(lock)) /* is_w is ignored */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful when implementing barriers. They are not
|
||||
normally needed by modules that merely use barriers.
|
||||
The "barrier" argument is a pointer to the barrier object.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Report that the "barrier" has been initialized with initial
|
||||
"count". If 'reinitialization_allowed' is true, initialization is
|
||||
allowed to happen multiple times w/o calling barrier_destroy() */
|
||||
#define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_BARRIER_INIT")
|
||||
|
||||
/* Report that we are about to enter barrier_wait("barrier"). */
|
||||
#define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_BARRIER_DESTROY")
|
||||
|
||||
/* Report that we just exited barrier_wait("barrier"). */
|
||||
#define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_BARRIER_DESTROY")
|
||||
|
||||
/* Report that the "barrier" has been destroyed. */
|
||||
#define ANNOTATE_BARRIER_DESTROY(barrier) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_BARRIER_DESTROY")
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Annotations useful for testing race detectors.
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Report that we expect a race on the variable at ADDRESS. Use only
|
||||
in unit tests for a race detector. */
|
||||
#define ANNOTATE_EXPECT_RACE(address, description) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_EXPECT_RACE")
|
||||
|
||||
/* A no-op. Insert where you like to test the interceptors. */
|
||||
#define ANNOTATE_NO_OP(arg) \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_NO_OP")
|
||||
|
||||
/* Force the race detector to flush its state. The actual effect depends on
|
||||
* the implementation of the detector. */
|
||||
#define ANNOTATE_FLUSH_STATE() \
|
||||
_HG_CLIENTREQ_UNIMP("ANNOTATE_FLUSH_STATE")
|
||||
|
||||
#endif /* __HELGRIND_H */
|
310
third_party/valgrind/memcheck.h
vendored
Normal file
310
third_party/valgrind/memcheck.h
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the following BSD-style license applies to this one
|
||||
file (memcheck.h) only. The rest of Valgrind is licensed under the
|
||||
terms of the GNU General Public License, version 2, unless
|
||||
otherwise indicated. See the COPYING file in the source
|
||||
distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
This file is part of MemCheck, a heavyweight Valgrind tool for
|
||||
detecting memory errors.
|
||||
|
||||
Copyright (C) 2000-2017 Julian Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Notice that the above BSD-style license applies to this one file
|
||||
(memcheck.h) only. The entire rest of Valgrind is licensed under
|
||||
the terms of the GNU General Public License, version 2. See the
|
||||
COPYING file in the source distribution for details.
|
||||
|
||||
----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __MEMCHECK_H
|
||||
#define __MEMCHECK_H
|
||||
|
||||
|
||||
/* This file is for inclusion into client (your!) code.
|
||||
|
||||
You can use these macros to manipulate and query memory permissions
|
||||
inside your own programs.
|
||||
|
||||
See comment near the top of valgrind.h on how to use them.
|
||||
*/
|
||||
|
||||
#include "valgrind.h"
|
||||
|
||||
/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
|
||||
This enum comprises an ABI exported by Valgrind to programs
|
||||
which use client requests. DO NOT CHANGE THE ORDER OF THESE
|
||||
ENTRIES, NOR DELETE ANY -- add new ones at the end. */
|
||||
typedef
|
||||
enum {
|
||||
VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'),
|
||||
VG_USERREQ__MAKE_MEM_UNDEFINED,
|
||||
VG_USERREQ__MAKE_MEM_DEFINED,
|
||||
VG_USERREQ__DISCARD,
|
||||
VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,
|
||||
VG_USERREQ__CHECK_MEM_IS_DEFINED,
|
||||
VG_USERREQ__DO_LEAK_CHECK,
|
||||
VG_USERREQ__COUNT_LEAKS,
|
||||
|
||||
VG_USERREQ__GET_VBITS,
|
||||
VG_USERREQ__SET_VBITS,
|
||||
|
||||
VG_USERREQ__CREATE_BLOCK,
|
||||
|
||||
VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE,
|
||||
|
||||
/* Not next to VG_USERREQ__COUNT_LEAKS because it was added later. */
|
||||
VG_USERREQ__COUNT_LEAK_BLOCKS,
|
||||
|
||||
VG_USERREQ__ENABLE_ADDR_ERROR_REPORTING_IN_RANGE,
|
||||
VG_USERREQ__DISABLE_ADDR_ERROR_REPORTING_IN_RANGE,
|
||||
|
||||
/* This is just for memcheck's internal use - don't use it */
|
||||
_VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR
|
||||
= VG_USERREQ_TOOL_BASE('M','C') + 256,
|
||||
_VG_USERREQ__MEMCHECK_VERIFY_ALIGNMENT
|
||||
} Vg_MemCheckClientRequest;
|
||||
|
||||
|
||||
|
||||
/* Client-code macros to manipulate the state of memory. */
|
||||
|
||||
/* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */
|
||||
#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__MAKE_MEM_NOACCESS, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
/* Similarly, mark memory at _qzz_addr as addressable but undefined
|
||||
for _qzz_len bytes. */
|
||||
#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__MAKE_MEM_UNDEFINED, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
/* Similarly, mark memory at _qzz_addr as addressable and defined
|
||||
for _qzz_len bytes. */
|
||||
#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__MAKE_MEM_DEFINED, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
/* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is
|
||||
not altered: bytes which are addressable are marked as defined,
|
||||
but those which are not addressable are left unchanged. */
|
||||
#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
/* Create a block-description handle. The description is an ascii
|
||||
string which is included in any messages pertaining to addresses
|
||||
within the specified memory range. Has no other effect on the
|
||||
properties of the memory range. */
|
||||
#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__CREATE_BLOCK, \
|
||||
(_qzz_addr), (_qzz_len), (_qzz_desc), \
|
||||
0, 0)
|
||||
|
||||
/* Discard a block-description-handle. Returns 1 for an
|
||||
invalid handle, 0 for a valid handle. */
|
||||
#define VALGRIND_DISCARD(_qzz_blkindex) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__DISCARD, \
|
||||
0, (_qzz_blkindex), 0, 0, 0)
|
||||
|
||||
|
||||
/* Client-code macros to check the state of memory. */
|
||||
|
||||
/* Check that memory at _qzz_addr is addressable for _qzz_len bytes.
|
||||
If suitable addressibility is not established, Valgrind prints an
|
||||
error message and returns the address of the first offending byte.
|
||||
Otherwise it returns zero. */
|
||||
#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
|
||||
VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
/* Check that memory at _qzz_addr is addressable and defined for
|
||||
_qzz_len bytes. If suitable addressibility and definedness are not
|
||||
established, Valgrind prints an error message and returns the
|
||||
address of the first offending byte. Otherwise it returns zero. */
|
||||
#define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
|
||||
VG_USERREQ__CHECK_MEM_IS_DEFINED, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
/* Use this macro to force the definedness and addressibility of an
|
||||
lvalue to be checked. If suitable addressibility and definedness
|
||||
are not established, Valgrind prints an error message and returns
|
||||
the address of the first offending byte. Otherwise it returns
|
||||
zero. */
|
||||
#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) \
|
||||
VALGRIND_CHECK_MEM_IS_DEFINED( \
|
||||
(volatile unsigned char *)&(__lvalue), \
|
||||
(unsigned long)(sizeof (__lvalue)))
|
||||
|
||||
|
||||
/* Do a full memory leak check (like --leak-check=full) mid-execution. */
|
||||
#define VALGRIND_DO_LEAK_CHECK \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \
|
||||
0, 0, 0, 0, 0)
|
||||
|
||||
/* Same as VALGRIND_DO_LEAK_CHECK but only showing the entries for
|
||||
which there was an increase in leaked bytes or leaked nr of blocks
|
||||
since the previous leak search. */
|
||||
#define VALGRIND_DO_ADDED_LEAK_CHECK \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \
|
||||
0, 1, 0, 0, 0)
|
||||
|
||||
/* Same as VALGRIND_DO_ADDED_LEAK_CHECK but showing entries with
|
||||
increased or decreased leaked bytes/blocks since previous leak
|
||||
search. */
|
||||
#define VALGRIND_DO_CHANGED_LEAK_CHECK \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \
|
||||
0, 2, 0, 0, 0)
|
||||
|
||||
/* Same as VALGRIND_DO_LEAK_CHECK but only showing new entries
|
||||
i.e. loss records that were not there in the previous leak
|
||||
search. */
|
||||
#define VALGRIND_DO_NEW_LEAK_CHECK \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \
|
||||
0, 3, 0, 0, 0)
|
||||
|
||||
/* Do a summary memory leak check (like --leak-check=summary) mid-execution. */
|
||||
#define VALGRIND_DO_QUICK_LEAK_CHECK \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \
|
||||
1, 0, 0, 0, 0)
|
||||
|
||||
/* Return number of leaked, dubious, reachable and suppressed bytes found by
|
||||
all previous leak checks. They must be lvalues. */
|
||||
#define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \
|
||||
/* For safety on 64-bit platforms we assign the results to private
|
||||
unsigned long variables, then assign these to the lvalues the user
|
||||
specified, which works no matter what type 'leaked', 'dubious', etc
|
||||
are. We also initialise '_qzz_leaked', etc because
|
||||
VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
|
||||
defined. */ \
|
||||
{ \
|
||||
unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
|
||||
unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT( \
|
||||
VG_USERREQ__COUNT_LEAKS, \
|
||||
&_qzz_leaked, &_qzz_dubious, \
|
||||
&_qzz_reachable, &_qzz_suppressed, 0); \
|
||||
leaked = _qzz_leaked; \
|
||||
dubious = _qzz_dubious; \
|
||||
reachable = _qzz_reachable; \
|
||||
suppressed = _qzz_suppressed; \
|
||||
}
|
||||
|
||||
/* Return number of leaked, dubious, reachable and suppressed bytes found by
|
||||
all previous leak checks. They must be lvalues. */
|
||||
#define VALGRIND_COUNT_LEAK_BLOCKS(leaked, dubious, reachable, suppressed) \
|
||||
/* For safety on 64-bit platforms we assign the results to private
|
||||
unsigned long variables, then assign these to the lvalues the user
|
||||
specified, which works no matter what type 'leaked', 'dubious', etc
|
||||
are. We also initialise '_qzz_leaked', etc because
|
||||
VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
|
||||
defined. */ \
|
||||
{ \
|
||||
unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
|
||||
unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT( \
|
||||
VG_USERREQ__COUNT_LEAK_BLOCKS, \
|
||||
&_qzz_leaked, &_qzz_dubious, \
|
||||
&_qzz_reachable, &_qzz_suppressed, 0); \
|
||||
leaked = _qzz_leaked; \
|
||||
dubious = _qzz_dubious; \
|
||||
reachable = _qzz_reachable; \
|
||||
suppressed = _qzz_suppressed; \
|
||||
}
|
||||
|
||||
|
||||
/* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it
|
||||
into the provided zzvbits array. Return values:
|
||||
0 if not running on valgrind
|
||||
1 success
|
||||
2 [previously indicated unaligned arrays; these are now allowed]
|
||||
3 if any parts of zzsrc/zzvbits are not addressable.
|
||||
The metadata is not copied in cases 0, 2 or 3 so it should be
|
||||
impossible to segfault your system by using this call.
|
||||
*/
|
||||
#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \
|
||||
(unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
|
||||
VG_USERREQ__GET_VBITS, \
|
||||
(const char*)(zza), \
|
||||
(char*)(zzvbits), \
|
||||
(zznbytes), 0, 0)
|
||||
|
||||
/* Set the validity data for addresses [zza..zza+zznbytes-1], copying it
|
||||
from the provided zzvbits array. Return values:
|
||||
0 if not running on valgrind
|
||||
1 success
|
||||
2 [previously indicated unaligned arrays; these are now allowed]
|
||||
3 if any parts of zza/zzvbits are not addressable.
|
||||
The metadata is not copied in cases 0, 2 or 3 so it should be
|
||||
impossible to segfault your system by using this call.
|
||||
*/
|
||||
#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \
|
||||
(unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
|
||||
VG_USERREQ__SET_VBITS, \
|
||||
(const char*)(zza), \
|
||||
(const char*)(zzvbits), \
|
||||
(zznbytes), 0, 0 )
|
||||
|
||||
/* Disable and re-enable reporting of addressing errors in the
|
||||
specified address range. */
|
||||
#define VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__DISABLE_ADDR_ERROR_REPORTING_IN_RANGE, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
#define VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(_qzz_addr,_qzz_len) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
|
||||
VG_USERREQ__ENABLE_ADDR_ERROR_REPORTING_IN_RANGE, \
|
||||
(_qzz_addr), (_qzz_len), 0, 0, 0)
|
||||
|
||||
#endif
|
||||
|
7165
third_party/valgrind/valgrind.h
vendored
Normal file
7165
third_party/valgrind/valgrind.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user