In on-going discussion about malloc(0), I made a mention about this approach. As this idea is somehow independent of the malloc(0) stuff, I'm starting a new thread.
Folks, in the attached file you can see how easy is to support coalesced mallocs at runtime. This would enable us to disable the coalesced mallocs for optimized builds and run the code under valgrind to catch invalid memory accesses. The code has memory leaks on purpose to get output from -malloc_dump, you can try it with debug/opt builds, passing -malloc_coalesced [0|1] option and value. If you pass "-n size1,size2" you can control the sizes for the PetscMalloc2 calls. If you use a optimized build, and any of the sizes is 0, and you pass -malloc_coalesced 0, valgrind will be able to catch the invalid writes. $ PETSC_ARCH=arch-linux2-c-opt make TestMalloc $ valgrind -q ./TestMalloc -n 0,1 -malloc_coalesced 1 2>&1 | grep "Invalid write" <no-ouput> $ valgrind -q ./TestMalloc -n 0,1 -malloc_coalesced 0 2>&1 | grep "Invalid write" ==2304== Invalid write of size 1 ==2304== Invalid write of size 4 ==2304== Invalid write of size 8 $ valgrind -q ./TestMalloc -n 0,0 -malloc_coalesced 0 2>&1 | grep "Invalid write" ==2306== Invalid write of size 1 ==2306== Invalid write of size 1 ==2306== Invalid write of size 4 ==2306== Invalid write of size 4 ==2306== Invalid write of size 8 ==2306== Invalid write of size 8 IMHO, we should definitely implement this approach. If you agree, let discuss about when to enable/disable the coalesced mallocs (e.g., if users pass -malloc or -malloc_dump, perhaps we should disable coalescing, and only enable it back if -malloc_coalesced 1 is explicitly asked for). -- Lisandro Dalcin ============ Research Scientist Computer, Electrical and Mathematical Sciences & Engineering (CEMSE) Numerical Porous Media Center (NumPor) King Abdullah University of Science and Technology (KAUST) http://numpor.kaust.edu.sa/ 4700 King Abdullah University of Science and Technology al-Khawarizmi Bldg (Bldg 1), Office # 4332 Thuwal 23955-6900, Kingdom of Saudi Arabia http://www.kaust.edu.sa Office Phone: +966 12 808-0459
#include <petsc.h>
#undef PetscMalloc1
#undef PetscMalloc2
#undef PetscMalloc3
/* ----------------------------------------------------------- */
/* include/petscsys.h */
#define PetscMalloc1(m1,r1) PetscMalloc((m1)*sizeof(**(r1)),r1)
#define PetscMalloc2(m1,r1,m2,r2) \
(PetscLikely(PetscMallocCoalesced) \
? (PetscMalloc((m1)*sizeof(**(r1))+(m2)*sizeof(**(r2))+(PETSC_MEMALIGN-1),r1) || \
(*(void**)(r2) = PetscAddrAlign(*(r1)+(m1)),0)) \
: (PetscMalloc1(m1,r1) || PetscMalloc1(m2,r2)))
#define PetscMalloc3(m1,r1,m2,r2,m3,r3) \
(PetscLikely(PetscMallocCoalesced) \
? (PetscMalloc((m1)*sizeof(**(r1))+(m2)*sizeof(**(r2))+(m3)*sizeof(**(r3))+2*(PETSC_MEMALIGN-1),r1) || \
(*(void**)(r2) = PetscAddrAlign(*(r1)+(m1)), \
*(void**)(r3) = PetscAddrAlign(*(r2)+(m2)),0)) \
: (PetscMalloc1(m1,r1) || PetscMalloc1(m2,r2) || PetscMalloc1(m3,r3)))
PETSC_EXTERN PetscBool PetscMallocCoalesced;
/* ----------------------------------------------------------- */
/* src/sys/memory/mtr.c */
#if defined(PETSC_USE_DEBUG)
PetscBool PetscMallocCoalesced = PETSC_FALSE;
#else
PetscBool PetscMallocCoalesced = PETSC_TRUE;
#endif
/* ----------------------------------------------------------- */
#undef __FUNCT__
#define __FUNCT__ "main"
int main(int argc, char *argv[])
{
PetscInt n[2] = {1,1},nn = 2;
char *c1,*c2;
PetscInt *i1,*i2;
PetscScalar *s1,*s2;
PetscErrorCode ierr;
ierr = PetscInitialize(&argc,&argv,0,0);CHKERRQ(ierr);
/* this line should go inside PetscOptionsCheckInitial_Private() */
ierr = PetscOptionsGetBool(NULL,"-malloc_coalesced",&PetscMallocCoalesced,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetIntArray(NULL,"-n",n,&nn,NULL);CHKERRQ(ierr);
ierr = PetscMalloc2((size_t)n[0],&c1,(size_t)n[1],&c2);CHKERRQ(ierr);
ierr = PetscMalloc2((size_t)n[0],&i1,(size_t)n[1],&i2);CHKERRQ(ierr);
ierr = PetscMalloc2((size_t)n[0],&s1,(size_t)n[1],&s2);CHKERRQ(ierr);
printf("c1=%p c2=%p\n",c1,c2);
printf("i1=%p i2=%p\n",i1,i2);
printf("s1=%p s2=%p\n",s1,s2);
c1[0] = 0; c2[0] = 0;
i1[0] = 0; i2[0] = 0;
s1[0] = 0; s2[0] = 0;
if (0) {
ierr = PetscFree2(c1,c2);CHKERRQ(ierr);
ierr = PetscFree2(i1,i2);CHKERRQ(ierr);
ierr = PetscFree2(s1,s2);CHKERRQ(ierr);
}
ierr = PetscFinalize();CHKERRQ(ierr);
return 0;
}
makefile
Description: Binary data
