static PetscErrorCode PetscHBWFree(void *aa,int lineno,const char function[],const char filename[]) { #if !defined(PETSC_HAVE_MEMKIND) return PetscFreeAlign(aa,lineno,function,filename); #else hbw_free(aa); return 0; #endif }
static PetscErrorCode PetscHBWRealloc(size_t a,int lineno,const char function[],const char filename[],void **result) { #if !defined(PETSC_HAVE_MEMKIND) return PetscReallocAlign(a,lineno,function,filename,result); #else if (!a) { int ierr = PetscFreeAlign(*result,lineno,function,filename); if (ierr) return ierr; *result = NULL; return 0; } *result = hbw_realloc(*result,a); if (!*result) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MEM,"Memory requested %.0f",(PetscLogDouble)a); return 0; #endif }
/* PetscTrFreeDefault - Free with tracing. Input Parameters: . a - pointer to a block allocated with PetscTrMalloc . lineno - line number where used. Use __LINE__ for this . function - function calling routine. Use __FUNCT__ for this . file - file name where used. Use __FILE__ for this */ PetscErrorCode PetscTrFreeDefault(void *aa,int line,const char function[],const char file[]) { char *a = (char*)aa; TRSPACE *head; char *ahead; PetscErrorCode ierr; PetscClassId *nend; PetscFunctionBegin; /* Do not try to handle empty blocks */ if (!a) PetscFunctionReturn(0); if (TRdebugLevel) { ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr); } ahead = a; a = a - sizeof(TrSPACE); head = (TRSPACE*)a; if (head->classid != CLASSID_VALUE) { (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); (*PetscErrorPrintf)("Block at address %p is corrupted; cannot free;\nmay be block not allocated with PetscMalloc()\n",a); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Bad location or corrupted memory"); } nend = (PetscClassId*)(ahead + head->size); if (*nend != CLASSID_VALUE) { if (*nend == ALREADY_FREED) { (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p was already freed\n",head->id,(PetscLogDouble)head->size,a + sizeof(TrSPACE)); if (head->lineno > 0 && head->lineno < 50000 /* sanity check */) { (*PetscErrorPrintf)("Block freed in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); } else { (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,-head->lineno,head->filename); } SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Memory already freed"); } else { /* Damaged tail */ (*PetscErrorPrintf)("PetscTrFreeDefault() called from %s() line %d in %s\n",function,line,file); (*PetscErrorPrintf)("Block [id=%d(%.0f)] at address %p is corrupted (probably write past end of array)\n",head->id,(PetscLogDouble)head->size,a); (*PetscErrorPrintf)("Block allocated in %s() line %d in %s\n",head->functionname,head->lineno,head->filename); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEMC,"Corrupted memory"); } } /* Mark the location freed */ *nend = ALREADY_FREED; /* Save location where freed. If we suspect the line number, mark as allocated location */ if (line > 0 && line < 50000) { head->lineno = line; head->filename = file; head->functionname = function; } else { head->lineno = -head->lineno; } /* zero out memory - helps to find some reuse of already freed memory */ ierr = PetscMemzero(aa,head->size);CHKERRQ(ierr); TRallocated -= head->size; TRfrags--; if (head->prev) head->prev->next = head->next; else TRhead = head->next; if (head->next) head->next->prev = head->prev; ierr = PetscFreeAlign(a,line,function,file);CHKERRQ(ierr); PetscFunctionReturn(0); }