Commit 3c18dd24 authored by David Goodell's avatar David Goodell
Browse files

[svn-r6103] refactor MPIU trmem and valgrind code to MPL (ticket #898).

This commit moves the existing tracing memory allocation and valgrind
code utilities to MPL.  This permits other code like gforker to use the
trmem code while allowing MPICH2 to remain thread-safe when using
tracing.  gforker is not updated to the MPL routines by this commit.

Reviewed by buntinas@.
parent dcf63939
......@@ -973,7 +973,6 @@ if test "$MPID_NO_SPAWN" = yes ; then
AC_MSG_WARN([The device $with_device does not support MPI dynamic process routines])
fi
# MPL
PAC_CONFIG_SUBDIR(src/mpl, $use_top_srcdir, $ac_configure_args,,AC_ERROR(MPL configure failed))
PAC_PREPEND_FLAG([-lmpl], [WRAPPER_LIBS])
......@@ -5129,9 +5128,6 @@ fi
PAC_C_MACRO_VA_ARGS
# headers for valgrind client requests
AC_CHECK_HEADERS([valgrind.h memcheck.h valgrind/valgrind.h valgrind/memcheck.h])
dnl
dnl If internationalization selected, try to find the needed functions
dnl if test "$enable_internat" = "yes" ; then
......
......@@ -30,6 +30,12 @@
do not want mpi.h to depend on any other files or configure flags */
#include "mpichconf.h"
/* if we are defining this, we must define it before including mpl.h */
#if defined(MPICH_DEBUG_MEMINIT)
#define MPL_VG_ENABLED 1
#endif
#include "mpl.h"
#include <stdio.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
......
......@@ -132,6 +132,20 @@ int MPIU_Str_get_string(char **str_ptr, char *val, int maxlen);
/* ------------------------------------------------------------------------- */
void MPIU_trinit(int);
void *MPIU_trmalloc(unsigned int, int, const char []);
void MPIU_trfree(void *, int, const char []);
int MPIU_trvalid(const char []);
void MPIU_trspace(int *, int *);
void MPIU_trid(int);
void MPIU_trlevel(int);
void MPIU_trDebugLevel(int);
void *MPIU_trcalloc(unsigned int, unsigned int, int, const char []);
void *MPIU_trrealloc(void *, int, int, const char[]);
void *MPIU_trstrdup(const char *, int, const char[]);
void MPIU_TrSetMaxMem(int);
void MPIU_trdump(FILE *, int);
#ifdef USE_MEMORY_TRACING
/*M
MPIU_Malloc - Allocate memory
......@@ -162,8 +176,8 @@ int MPIU_Str_get_string(char **str_ptr, char *val, int maxlen);
Module:
Utility
M*/
#define MPIU_Malloc(a) MPIU_trmalloc((unsigned)(a),__LINE__,__FILE__)
/*M
MPIU_Calloc - Allocate memory that is initialized to zero.
......@@ -237,30 +251,6 @@ int MPIU_Str_get_string(char **str_ptr, char *val, int maxlen);
#undef strdup /* in case strdup is a macro */
#define strdup(a) 'Error use MPIU_Strdup' :::
/* FIXME: Note that some of these prototypes are for old functions in the
src/util/mem/trmem.c package, and are no longer used. Also,
it may be preferable to use trmem.h instead of these definitions */
void MPIU_trinit ( int );
void *MPIU_trmalloc ( unsigned int, int, const char * );
void MPIU_trfree ( void *, int, const char * );
int MPIU_trvalid ( const char * );
void MPIU_trspace ( int *, int * );
void MPIU_trid ( int );
void MPIU_trlevel ( int );
void MPIU_trpush ( int );
void MPIU_trpop (void);
void MPIU_trDebugLevel ( int );
void *MPIU_trstrdup( const char *, int, const char * );
void *MPIU_trcalloc ( unsigned, unsigned, int, const char * );
void *MPIU_trrealloc ( void *, int, int, const char * );
void MPIU_TrSetMaxMem ( int );
#ifndef MPIU_MEM_NOSTDIO
void MPIU_trdump ( FILE *, int );
void MPIU_trSummary ( FILE *, int );
void MPIU_trdumpGrouped ( FILE *, int );
#endif
#else /* USE_MEMORY_TRACING */
/* No memory tracing; just use native functions */
#define MPIU_Malloc(a) malloc((size_t)(a))
......@@ -461,8 +451,8 @@ void MPIU_Basename(char *path, char **basename);
if (len_) { \
MPIU_Assert((dst_) != NULL); \
MPIU_Assert((src_) != NULL); \
MPIU_VG_CHECK_MEM_IS_ADDRESSABLE((dst_),(len_)); \
MPIU_VG_CHECK_MEM_IS_ADDRESSABLE((src_),(len_)); \
MPL_VG_CHECK_MEM_IS_ADDRESSABLE((dst_),(len_)); \
MPL_VG_CHECK_MEM_IS_ADDRESSABLE((src_),(len_)); \
if (((char *)(dst_) >= (char *)(src_) && ((char *)(dst_) < ((char *)(src_) + (len_)))) || \
((char *)(src_) >= (char *)(dst_) && ((char *)(src_) < ((char *)(dst_) + (len_))))) \
{ \
......@@ -475,7 +465,7 @@ void MPIU_Basename(char *path, char **basename);
#define MPIU_MEM_CHECK_MEMCPY(dst_,src_,len_) do {} while(0)
#endif
#include "mpiu_valgrind.h"
/* valgrind macros are now provided by MPL (via mpl.h included in mpiimpl.h) */
/* ------------------------------------------------------------------------- */
/* end of mpimem.h */
......
......@@ -31,6 +31,12 @@
#include "mpichconf.h"
#endif
/* if we are defining this, we must define it before including mpl.h */
#if defined(MPICH_DEBUG_MEMINIT)
#define MPL_VG_ENABLED 1
#endif
#include "mpl.h"
/* The most common MPI error classes */
#ifndef MPI_SUCCESS
#define MPI_SUCCESS 0
......
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2001 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
/* valgrind interaction macros and header include logic
These macros are intended to simplify client request interactions with
valgrind. An MPICH2 source file that needs valgrind client requests if they
are available can include this file instead and use MPIU_VG_ macros without
worrying about whether or not valgrind is actually present, which headers to
include, and how to include them.
For more complicated logic this header will also define/undefine the
preprocessor token "MPIU_VG_AVAILABLE".
*/
#ifndef MPICH_VALGRIND_H_INCLUDED
#define MPICH_VALGRIND_H_INCLUDED
#include "mpichconf.h"
#undef MPIU_VG_AVAILABLE
#if defined(MPICH_DEBUG_MEMINIT) && !defined(NVALGRIND)
# if defined(HAVE_VALGRIND_H) && defined(HAVE_MEMCHECK_H)
# include <valgrind.h>
# include <memcheck.h>
# define MPIU_VG_AVAILABLE 1
# elif defined(HAVE_VALGRIND_VALGRIND_H) && defined(HAVE_VALGRIND_MEMCHECK_H)
# include <valgrind/valgrind.h>
# include <valgrind/memcheck.h>
# define MPIU_VG_AVAILABLE 1
# endif
#endif
/* This is only a modest subset of all of the available client requests defined
in the valgrind headers. As MPICH2 is modified to use more of them, this
list should be expanded appropriately. */
#if defined(MPIU_VG_AVAILABLE)
# if defined(VALGRIND_MAKE_MEM_DEFINED)
/* this valgrind is version 3.2.0 or later */
# define MPIU_VG_MAKE_MEM_DEFINED(addr_,len_) VALGRIND_MAKE_MEM_DEFINED((addr_),(len_))
# define MPIU_VG_MAKE_MEM_NOACCESS(addr_,len_) VALGRIND_MAKE_MEM_NOACCESS((addr_),(len_))
# define MPIU_VG_MAKE_MEM_UNDEFINED(addr_,len_) VALGRIND_MAKE_MEM_UNDEFINED((addr_),(len_))
# define MPIU_VG_CHECK_MEM_IS_DEFINED(addr_,len_) VALGRIND_CHECK_MEM_IS_DEFINED((addr_),(len_))
# define MPIU_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) VALGRIND_CHECK_MEM_IS_ADDRESSABLE((addr_),(len_))
# else
/* this is an older version of valgrind. Use the older (subtly misleading) names */
# define MPIU_VG_MAKE_MEM_DEFINED(addr_,len_) VALGRIND_MAKE_READABLE((addr_),(len_))
# define MPIU_VG_MAKE_MEM_NOACCESS(addr_,len_) VALGRIND_MAKE_NOACCESS((addr_),(len_))
# define MPIU_VG_MAKE_MEM_UNDEFINED(addr_,len_) VALGRIND_MAKE_WRITABLE((addr_),(len_))
# define MPIU_VG_CHECK_MEM_IS_DEFINED(addr_,len_) VALGRIND_CHECK_READABLE((addr_),(len_))
# define MPIU_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) VALGRIND_CHECK_WRITABLE((addr_),(len_))
# endif
# define MPIU_VG_CREATE_BLOCK(addr_,len_,desc_) VALGRIND_CREATE_BLOCK((addr_),(len_),(desc_))
# define MPIU_VG_RUNNING_ON_VALGRIND() RUNNING_ON_VALGRIND
# define MPIU_VG_PRINTF_BACKTRACE VALGRIND_PRINTF_BACKTRACE
/* custom allocator client requests, you probably shouldn't use these unless you
* really know what you are doing */
# define MPIU_VG_CREATE_MEMPOOL(pool, rzB, is_zeroed) VALGRIND_CREATE_MEMPOOL((pool), (rzB), (is_zeroed))
# define MPIU_VG_DESTROY_MEMPOOL(pool) VALGRIND_DESTROY_MEMPOOL((pool))
# define MPIU_VG_MEMPOOL_ALLOC(pool, addr, size) VALGRIND_MEMPOOL_ALLOC((pool), (addr), (size))
# define MPIU_VG_MEMPOOL_FREE(pool, addr) VALGRIND_MEMPOOL_FREE((pool), (addr))
#else /* !defined(MPIU_VG_AVAILABLE) */
# define MPIU_VG_MAKE_MEM_DEFINED(addr_,len_) do{}while(0)
# define MPIU_VG_MAKE_MEM_NOACCESS(addr_,len_) do{}while(0)
# define MPIU_VG_MAKE_MEM_UNDEFINED(addr_,len_) do{}while(0)
# define MPIU_VG_CHECK_MEM_IS_DEFINED(addr_,len_) do{}while(0)
# define MPIU_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) do{}while(0)
# define MPIU_VG_CREATE_BLOCK(addr_,len_,desc_) do{}while(0)
# define MPIU_VG_RUNNING_ON_VALGRIND() (0)/*always false*/
# if defined(HAVE_MACRO_VA_ARGS)
# define MPIU_VG_PRINTF_BACKTRACE(...) do{}while(0)
# else
# define MPIU_VG_PRINTF_BACKTRACE MPIU_VG_printf_do_nothing_func
static inline void MPIU_VG_printf_do_nothing_func(char *fmt, ...)
{
/* do nothing */
}
# endif /* defined(HAVE_MACRO_VA_ARGS) */
# define MPIU_VG_CREATE_MEMPOOL(pool, rzB, is_zeroed) do{}while(0)
# define MPIU_VG_DESTROY_MEMPOOL(pool) do{}while(0)
# define MPIU_VG_MEMPOOL_ALLOC(pool, addr, size) do{}while(0)
# define MPIU_VG_MEMPOOL_FREE(pool, addr) do{}while(0)
#endif /* defined(MPIU_VG_AVAILABLE) */
#endif /* !defined(MPICH_VALGRIND_H_INCLUDED) */
......@@ -110,7 +110,7 @@ int MPID_Abort( struct MPID_Comm *comm, int mpi_errno, int exit_code, const char
#if (!defined(NDEBUG) && defined(HAVE_ERROR_CHECKING))
# if defined(HAVE_MACRO_VA_ARGS)
# include "mpiu_valgrind.h" /* for MPIU_VG_ macros */
# include "mpl.h" /* for MPL_VG_ macros */
# define MPIU_ASSERT_FMT_MSG_MAX_SIZE 2048
/* newlines are added internally by this macro, callers do not need to include them */
......@@ -119,9 +119,9 @@ int MPID_Abort( struct MPID_Comm *comm, int mpi_errno, int exit_code, const char
if (!(cond_)) { \
char *msg_ = MPIU_Malloc(MPIU_ASSERT_FMT_MSG_MAX_SIZE); \
MPIU_Assert_fmt_msg_snprintf_ fmt_arg_parens_; \
MPIU_VG_PRINTF_BACKTRACE("Assertion failed in file %s at line %d: %s\n", \
MPL_VG_PRINTF_BACKTRACE("Assertion failed in file %s at line %d: %s\n", \
__FILE__, __LINE__, MPIU_QUOTE(cond_)); \
MPIU_VG_PRINTF_BACKTRACE("%s\n", msg_); \
MPL_VG_PRINTF_BACKTRACE("%s\n", msg_); \
MPIU_Internal_error_printf("Assertion failed in file %s at line %d: %s\n", \
__FILE__, __LINE__, MPIU_QUOTE(cond_)); \
MPIU_Internal_error_printf("%s\n", msg_); \
......@@ -145,9 +145,9 @@ int MPID_Abort( struct MPID_Comm *comm, int mpi_errno, int exit_code, const char
if (!(cond_)) { \
const char *unable_msg_ = \
"macro __VA_ARGS__ not supported, unable to print user message"; \
MPIU_VG_PRINTF_BACKTRACE("Assertion failed in file %s at line %d: %s\n", \
MPL_VG_PRINTF_BACKTRACE("Assertion failed in file %s at line %d: %s\n", \
__FILE__, __LINE__, MPIU_QUOTE(cond_)); \
MPIU_VG_PRINTF_BACKTRACE("%s\n", unable_msg_); \
MPL_VG_PRINTF_BACKTRACE("%s\n", unable_msg_); \
MPIU_Internal_error_printf("Assertion failed in file %s at line %d: %s\n", \
__FILE__, __LINE__, MPIU_QUOTE(cond_)); \
MPIU_Internal_error_printf("%s\n", unable_msg_); \
......
......@@ -169,8 +169,8 @@ PMPI_LOCAL int MPIR_Comm_create_calculate_mapping(MPID_Group *group_ptr,
MPIU_Assert(mapping != NULL);
*mapping_vcr_out = vcr;
*mapping_out = mapping;
MPIU_VG_CHECK_MEM_IS_DEFINED(*mapping_vcr_out, vcr_size * sizeof(**mapping_vcr_out));
MPIU_VG_CHECK_MEM_IS_DEFINED(*mapping_out, n * sizeof(**mapping_out));
MPL_VG_CHECK_MEM_IS_DEFINED(*mapping_vcr_out, vcr_size * sizeof(**mapping_vcr_out));
MPL_VG_CHECK_MEM_IS_DEFINED(*mapping_out, n * sizeof(**mapping_out));
MPIU_CHKPMEM_COMMIT();
fn_exit:
......
......@@ -529,7 +529,7 @@ static int MPIDI_CH3I_Send_rma_msg(MPIDI_RMA_ops *rma_op, MPID_Win *win_ptr,
MPIDI_FUNC_EXIT(MPID_STATE_MEMCPY);
/* the dataloop can have undefined padding sections, so we need to let
* valgrind know that it is OK to pass this data to writev later on */
MPIU_VG_MAKE_MEM_DEFINED(*dataloop, target_dtp->dataloop_size);
MPL_VG_MAKE_MEM_DEFINED(*dataloop, target_dtp->dataloop_size);
if (rma_op->type == MPIDI_RMA_PUT)
{
......@@ -757,7 +757,7 @@ static int MPIDI_CH3I_Recv_rma_msg(MPIDI_RMA_ops *rma_op, MPID_Win *win_ptr,
/* the dataloop can have undefined padding sections, so we need to let
* valgrind know that it is OK to pass this data to writev later on */
MPIU_VG_MAKE_MEM_DEFINED(*dataloop, dtp->dataloop_size);
MPL_VG_MAKE_MEM_DEFINED(*dataloop, dtp->dataloop_size);
get_pkt->dataloop_size = dtp->dataloop_size;
......
......@@ -8,4 +8,4 @@ ACLOCAL_AMFLAGS = -I confdb
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
lib_LIBRARIES = libmpl.a
libmpl_a_SOURCES = src/mplstr.c
libmpl_a_SOURCES = src/mplstr.c src/mpltrmem.c
......@@ -23,12 +23,17 @@ AC_PROG_RANLIB
AC_C_CONST
AC_C_RESTRICT
PAC_C_MACRO_VA_ARGS
dnl Check if the necessary headers are available
AC_CHECK_HEADERS(stdio.h stdlib.h string.h stdarg.h ctype.h)
# A C99 compliant compiler should have inttypes.h for fixed-size int types
AC_CHECK_HEADERS(inttypes.h stdint.h)
# headers for valgrind client requests
AC_CHECK_HEADERS([valgrind.h memcheck.h valgrind/valgrind.h valgrind/memcheck.h])
dnl Check for strdup
AC_CHECK_FUNCS(strdup)
if test "$ac_cv_func_strdup" = "yes" ; then
......
......@@ -53,6 +53,12 @@
# endif /* MPL_HAVE_GCC_ATTRIBUTE */
#endif /* ATTRIBUTE */
#include "mplstr.h"
/* must come before mpltrmem.h */
#include "mpl_valgrind.h"
#include "mpltrmem.h"
#endif /* MPL_H_INCLUDED */
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2009 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
/* IMPORTANT!!!: you must define MPL_VG_ENABLED before including mpl.h if you
want the the actual valgrind macros to be expanded when an MPL_VG_ macro is
used */
/* this file should not be included directly, it expects to be included from
* mpl.h with the results of various configure tests and several system
* libraries already included */
#if !defined(MPL_H_INCLUDED)
#error do not include mpl_valgrind.h directly, use mpl.h instead
#endif
/* valgrind interaction macros and header include logic
These macros are intended to simplify client request interactions with
valgrind. A client source file that needs valgrind client requests if they
are available can include this file instead and use MPL_VG_ macros without
worrying about whether or not valgrind is actually present, which headers to
include, and how to include them.
For more complicated logic this header will also define/undefine the
preprocessor token "MPL_VG_AVAILABLE".
*/
#ifndef MPL_VALGRIND_H_INCLUDED
#define MPL_VALGRIND_H_INCLUDED
#undef MPL_VG_AVAILABLE
#if defined(MPL_VG_ENABLED)
# if defined(MPICH_DEBUG_MEMINIT) && !defined(NVALGRIND)
# if defined(MPL_HAVE_VALGRIND_H) && defined(MPL_HAVE_MEMCHECK_H)
# include <valgrind.h>
# include <memcheck.h>
# define MPL_VG_AVAILABLE 1
# elif defined(MPL_HAVE_VALGRIND_VALGRIND_H) && defined(MPL_HAVE_VALGRIND_MEMCHECK_H)
# include <valgrind/valgrind.h>
# include <valgrind/memcheck.h>
# define MPL_VG_AVAILABLE 1
# endif
# endif
#endif
/* This is only a modest subset of all of the available client requests defined
in the valgrind headers. As MPICH2 is modified to use more of them, this
list should be expanded appropriately. */
#if defined(MPL_VG_AVAILABLE)
# if defined(VALGRIND_MAKE_MEM_DEFINED)
/* this valgrind is version 3.2.0 or later */
# define MPL_VG_MAKE_MEM_DEFINED(addr_,len_) VALGRIND_MAKE_MEM_DEFINED((addr_),(len_))
# define MPL_VG_MAKE_MEM_NOACCESS(addr_,len_) VALGRIND_MAKE_MEM_NOACCESS((addr_),(len_))
# define MPL_VG_MAKE_MEM_UNDEFINED(addr_,len_) VALGRIND_MAKE_MEM_UNDEFINED((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_DEFINED(addr_,len_) VALGRIND_CHECK_MEM_IS_DEFINED((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) VALGRIND_CHECK_MEM_IS_ADDRESSABLE((addr_),(len_))
# else
/* this is an older version of valgrind. Use the older (subtly misleading) names */
# define MPL_VG_MAKE_MEM_DEFINED(addr_,len_) VALGRIND_MAKE_READABLE((addr_),(len_))
# define MPL_VG_MAKE_MEM_NOACCESS(addr_,len_) VALGRIND_MAKE_NOACCESS((addr_),(len_))
# define MPL_VG_MAKE_MEM_UNDEFINED(addr_,len_) VALGRIND_MAKE_WRITABLE((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_DEFINED(addr_,len_) VALGRIND_CHECK_READABLE((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) VALGRIND_CHECK_WRITABLE((addr_),(len_))
# endif
# define MPL_VG_CREATE_BLOCK(addr_,len_,desc_) VALGRIND_CREATE_BLOCK((addr_),(len_),(desc_))
# define MPL_VG_RUNNING_ON_VALGRIND() RUNNING_ON_VALGRIND
# define MPL_VG_PRINTF_BACKTRACE VALGRIND_PRINTF_BACKTRACE
/* custom allocator client requests, you probably shouldn't use these unless you
* really know what you are doing */
# define MPL_VG_CREATE_MEMPOOL(pool, rzB, is_zeroed) VALGRIND_CREATE_MEMPOOL((pool), (rzB), (is_zeroed))
# define MPL_VG_DESTROY_MEMPOOL(pool) VALGRIND_DESTROY_MEMPOOL((pool))
# define MPL_VG_MEMPOOL_ALLOC(pool, addr, size) VALGRIND_MEMPOOL_ALLOC((pool), (addr), (size))
# define MPL_VG_MEMPOOL_FREE(pool, addr) VALGRIND_MEMPOOL_FREE((pool), (addr))
#else /* !defined(MPL_VG_AVAILABLE) */
# define MPL_VG_MAKE_MEM_DEFINED(addr_,len_) do{}while(0)
# define MPL_VG_MAKE_MEM_NOACCESS(addr_,len_) do{}while(0)
# define MPL_VG_MAKE_MEM_UNDEFINED(addr_,len_) do{}while(0)
# define MPL_VG_CHECK_MEM_IS_DEFINED(addr_,len_) do{}while(0)
# define MPL_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) do{}while(0)
# define MPL_VG_CREATE_BLOCK(addr_,len_,desc_) do{}while(0)
# define MPL_VG_RUNNING_ON_VALGRIND() (0)/*always false*/
# if defined(MPL_HAVE_MACRO_VA_ARGS)
# define MPL_VG_PRINTF_BACKTRACE(...) do{}while(0)
# else
# define MPL_VG_PRINTF_BACKTRACE MPL_VG_printf_do_nothing_func
static inline void MPL_VG_printf_do_nothing_func(char *fmt, ...)
{
/* do nothing */
}
# endif /* defined(MPL_HAVE_MACRO_VA_ARGS) */
# define MPL_VG_CREATE_MEMPOOL(pool, rzB, is_zeroed) do{}while(0)
# define MPL_VG_DESTROY_MEMPOOL(pool) do{}while(0)
# define MPL_VG_MEMPOOL_ALLOC(pool, addr, size) do{}while(0)
# define MPL_VG_MEMPOOL_FREE(pool, addr) do{}while(0)
#endif /* defined(MPL_VG_AVAILABLE) */
#endif /* !defined(MPL_VALGRIND_H_INCLUDED) */
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2001 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
#ifndef MPLTRMEM_H_INCLUDED
#define MPLTRMEM_H_INCLUDED
/* FIXME: Consider an option of specifying __attribute__((malloc)) for
gcc - this lets gcc-style compilers know that the returned pointer
does not alias any pointer prior to the call.
*/
void MPL_trinit(int);
void *MPL_trmalloc(unsigned int, int, const char []);
void MPL_trfree(void *, int, const char []);
int MPL_trvalid(const char []);
void MPL_trspace(int *, int *);
void MPL_trid(int);
void MPL_trlevel(int);
void MPL_trDebugLevel(int);
void *MPL_trcalloc(unsigned int, unsigned int, int, const char []);
void *MPL_trrealloc(void *, int, int, const char[]);
void *MPL_trstrdup(const char *, int, const char[]);
void MPL_TrSetMaxMem(int);
/* Make sure that FILE is defined */
#include <stdio.h>
void MPL_trdump(FILE *, int);
void MPL_trSummary(FILE *, int);
void MPL_trdumpGrouped(FILE *, int);
#endif /* !defined(MPLTRMEM_H_INCLUDED) */
This diff is collapsed.
......@@ -8,4 +8,4 @@ ACLOCAL_AMFLAGS = -I confdb
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
lib_LIBRARIES = libmpl.a
libmpl_a_SOURCES = src/mplstr.c
libmpl_a_SOURCES = src/mplstr.c src/mpltrmem.c
......@@ -23,12 +23,17 @@ AC_PROG_RANLIB
AC_C_CONST
AC_C_RESTRICT
PAC_C_MACRO_VA_ARGS
dnl Check if the necessary headers are available
AC_CHECK_HEADERS(stdio.h stdlib.h string.h stdarg.h ctype.h)
# A C99 compliant compiler should have inttypes.h for fixed-size int types
AC_CHECK_HEADERS(inttypes.h stdint.h)
# headers for valgrind client requests
AC_CHECK_HEADERS([valgrind.h memcheck.h valgrind/valgrind.h valgrind/memcheck.h])
dnl Check for strdup
AC_CHECK_FUNCS(strdup)
if test "$ac_cv_func_strdup" = "yes" ; then
......
......@@ -53,6 +53,12 @@
# endif /* MPL_HAVE_GCC_ATTRIBUTE */
#endif /* ATTRIBUTE */
#include "mplstr.h"
/* must come before mpltrmem.h */
#include "mpl_valgrind.h"
#include "mpltrmem.h"
#endif /* MPL_H_INCLUDED */
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2009 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
/* IMPORTANT!!!: you must define MPL_VG_ENABLED before including mpl.h if you
want the the actual valgrind macros to be expanded when an MPL_VG_ macro is
used */
/* this file should not be included directly, it expects to be included from
* mpl.h with the results of various configure tests and several system
* libraries already included */
#if !defined(MPL_H_INCLUDED)
#error do not include mpl_valgrind.h directly, use mpl.h instead
#endif
/* valgrind interaction macros and header include logic
These macros are intended to simplify client request interactions with
valgrind. A client source file that needs valgrind client requests if they
are available can include this file instead and use MPL_VG_ macros without
worrying about whether or not valgrind is actually present, which headers to
include, and how to include them.
For more complicated logic this header will also define/undefine the
preprocessor token "MPL_VG_AVAILABLE".
*/
#ifndef MPL_VALGRIND_H_INCLUDED
#define MPL_VALGRIND_H_INCLUDED
#undef MPL_VG_AVAILABLE
#if defined(MPL_VG_ENABLED)
# if defined(MPICH_DEBUG_MEMINIT) && !defined(NVALGRIND)
# if defined(MPL_HAVE_VALGRIND_H) && defined(MPL_HAVE_MEMCHECK_H)
# include <valgrind.h>
# include <memcheck.h>
# define MPL_VG_AVAILABLE 1
# elif defined(MPL_HAVE_VALGRIND_VALGRIND_H) && defined(MPL_HAVE_VALGRIND_MEMCHECK_H)
# include <valgrind/valgrind.h>
# include <valgrind/memcheck.h>
# define MPL_VG_AVAILABLE 1
# endif
# endif
#endif
/* This is only a modest subset of all of the available client requests defined
in the valgrind headers. As MPICH2 is modified to use more of them, this
list should be expanded appropriately. */
#if defined(MPL_VG_AVAILABLE)
# if defined(VALGRIND_MAKE_MEM_DEFINED)
/* this valgrind is version 3.2.0 or later */
# define MPL_VG_MAKE_MEM_DEFINED(addr_,len_) VALGRIND_MAKE_MEM_DEFINED((addr_),(len_))
# define MPL_VG_MAKE_MEM_NOACCESS(addr_,len_) VALGRIND_MAKE_MEM_NOACCESS((addr_),(len_))
# define MPL_VG_MAKE_MEM_UNDEFINED(addr_,len_) VALGRIND_MAKE_MEM_UNDEFINED((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_DEFINED(addr_,len_) VALGRIND_CHECK_MEM_IS_DEFINED((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) VALGRIND_CHECK_MEM_IS_ADDRESSABLE((addr_),(len_))
# else
/* this is an older version of valgrind. Use the older (subtly misleading) names */
# define MPL_VG_MAKE_MEM_DEFINED(addr_,len_) VALGRIND_MAKE_READABLE((addr_),(len_))
# define MPL_VG_MAKE_MEM_NOACCESS(addr_,len_) VALGRIND_MAKE_NOACCESS((addr_),(len_))
# define MPL_VG_MAKE_MEM_UNDEFINED(addr_,len_) VALGRIND_MAKE_WRITABLE((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_DEFINED(addr_,len_) VALGRIND_CHECK_READABLE((addr_),(len_))
# define MPL_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) VALGRIND_CHECK_WRITABLE((addr_),(len_))
# endif
# define MPL_VG_CREATE_BLOCK(addr_,len_,desc_) VALGRIND_CREATE_BLOCK((addr_),(len_),(desc_))
# define MPL_VG_RUNNING_ON_VALGRIND() RUNNING_ON_VALGRIND
# define MPL_VG_PRINTF_BACKTRACE VALGRIND_PRINTF_BACKTRACE
/* custom allocator client requests, you probably shouldn't use these unless you
* really know what you are doing */
# define MPL_VG_CREATE_MEMPOOL(pool, rzB, is_zeroed) VALGRIND_CREATE_MEMPOOL((pool), (rzB), (is_zeroed))
# define MPL_VG_DESTROY_MEMPOOL(pool) VALGRIND_DESTROY_MEMPOOL((pool))
# define MPL_VG_MEMPOOL_ALLOC(pool, addr, size) VALGRIND_MEMPOOL_ALLOC((pool), (addr), (size))
# define MPL_VG_MEMPOOL_FREE(pool, addr) VALGRIND_MEMPOOL_FREE((pool), (addr))
#else /* !defined(MPL_VG_AVAILABLE) */
# define MPL_VG_MAKE_MEM_DEFINED(addr_,len_) do{}while(0)
# define MPL_VG_MAKE_MEM_NOACCESS(addr_,len_) do{}while(0)
# define MPL_VG_MAKE_MEM_UNDEFINED(addr_,len_) do{}while(0)
# define MPL_VG_CHECK_MEM_IS_DEFINED(addr_,len_) do{}while(0)
# define MPL_VG_CHECK_MEM_IS_ADDRESSABLE(addr_,len_) do{}while(0)
# define MPL_VG_CREATE_BLOCK(addr_,len_,desc_) do{}while(0)
# define MPL_VG_RUNNING_ON_VALGRIND() (0)/*always false*/
# if defined(MPL_HAVE_MACRO_VA_ARGS)
# define MPL_VG_PRINTF_BACKTRACE(...) do{}while(0)
# else
# define MPL_VG_PRINTF_BACKTRACE MPL_VG_printf_do_nothing_func
static inline void MPL_VG_printf_do_nothing_func(char *fmt, ...)
{
/* do nothing */
}
# endif /* defined(MPL_HAVE_MACRO_VA_ARGS) */
# define MPL_VG_CREATE_MEMPOOL(pool, rzB, is_zeroed) do{}while(0)
# define MPL_VG_DESTROY_MEMPOOL(pool) do{}while(0)
# define MPL_VG_MEMPOOL_ALLOC(pool, addr, size) do{}while(0)
# define MPL_VG_MEMPOOL_FREE(pool, addr) do{}while(0)
#endif /* defined(MPL_VG_AVAILABLE) */
#endif /* !defined(MPL_VALGRIND_H_INCLUDED) */
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2001 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
#ifndef MPLTRMEM_H_INCLUDED
#define MPLTRMEM_H_INCLUDED
/* FIXME: Consider an option of specifying __attribute__((malloc)) for
gcc - this lets gcc-style compilers know that the returned pointer
does not alias any pointer prior to the call.
*/
void MPL_trinit(int);