/*
DFT++ is a density functional package developed by the research group
of Professor Tomas Arias
Copyright 1996-2003 Sohrab Ismail-Beigi
This file is part of DFT++.
DFT++ is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DFT++ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DFT++; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Please see the file CREDITS for a list of authors.
For academic users, we request that publications using results obtained with
this software reference
"New algebraic formulation of density functional calculation," by Sohrab Ismail-Beigi
and T.A. Arias, Computer Physics Communications 128:1-2, 1-45 (June 2000).
and, if using the wavelet basis, further reference
"Multiresolution analysis of electronic structure: semicardinal and wavelet bases,"
T.A. Arias, Reviews of Modern Physics 71:1, 267-311 (January 1999).
and
"Robust ab initio calculation of condensed matter: transparent convergence through
semicardinal multiresolution analysis,'' I.P. Daykov, T.A. Arias, and
Torkel D. Engeness, Physical Review Letters, 90:21, 216402 (May 2003).
For your convenience, preprints of the above articles may be obtained from
http://arXiv.org/abs/cond-mat/9909130, 9805262, and 0204411, respectively.
*/
/*
* Sohrab Ismail-Beigi Jan. 6, 1997
*
* mem.c: Routines that dynamically allocate/free memory.
*
* void *mymalloc() is just a fancy calloc() that exits with
* provided error messages if it can't allocate memory.
*
*/
/* $Id: mem.cpp,v 1.12.2.3 2003/05/29 18:54:29 ivan Exp $ */
#include "header.h"
#ifndef DFT_TRACE_MEM
/* Allocate size bytes of memory; if it fails, die with some
* information. If it suceeds, it zeroes out the memory before
* returning the pointer. */
void *
mymalloc(int size,const char *what,const char *where)
{
#ifdef DFT_PROFILING
timerOn(8); // Turn on memory allocation timer.
#endif // DFT_PROFILING
void *p;
if (size <= 0)
{
#ifdef DFT_PROFILING
timerOff(8); // Turn off memory allocation timer.
#endif // DFT_PROFILING
return ((void *) 0);
}
#ifdef DFT_MEMALIGN // not all platforms have memalign in standard lib
p = (void *)memalign(32,size);
#else
p = (void *)malloc(size);
#endif
if (p == (void *)0)
die("Can't malloc %d for %s in %s.\n", size, what, where);
else
{
int i;
char *c = (char *)p;
for (i=0; i < size; i++)
c[i] = 0;
#ifdef DFT_PROFILING
timerOff(8); // Turn off memory allocation timer.
#endif // DFT_PROFILING
}
return p;
}
/* Reallocate size bytes of memory; if it fails, die with some
* information. If it suceeds, returns the new block pointer */
void *
myrealloc(void *pold,int size,const char *what,const char *where)
{
#ifdef DFT_PROFILING
timerOn(8); // Turn on memory allocation timer.
#endif // DFT_PROFILING
void *p;
if (size <= 0)
{
#ifdef DFT_PROFILING
timerOff(8); // Turn off memory allocation timer.
#endif // DFT_PROFILING
return ((void *) 0);
}
p = (void *)realloc(pold,size);
if (p == 0)
die("Can't realloc %d for %s in %s.\n", size, what, where);
#ifdef DFT_PROFILING
timerOff(8); // Turn off memory allocation timer.
#endif // DFT_PROFILING
return p;
}
void
myfree(void* ptr)
{
if (ptr != NULL)
free(ptr);
}
#else // DFT_TRACE_MEM : trace memory usage
/*************************************************
* *
* For debugging purpose, use the following *
* memory access routines to trace usage. *
* *
*************************************************/
int num_blocks = 0;
int max_block = 0;
long int accum_alloc = 0L;
long int current_alloc = 0L;
long int max_alloc = 0L;
#define PREFIX 16
#define POSTFIX 16
#define MAGIC1 1234
#define MAGIC2 -9876
#define MAGIC3 "little-dogs"
#define POSTCHECK 10
void
mem_trace_report()
{
int i;
dft_log("\n>Memory Trace Report:\n");
dft_log(">Memory\ttotal allocations\t%d\n",num_blocks);
dft_log(">Memory\tmaximum block allocated\t%d\n",max_block);
dft_log(">Memory\taccumulative memory\t%ld\n", accum_alloc);
dft_log(">Memory\tcurrent memory\t%ld\n", current_alloc);
dft_log(">Memory\tmaximum memory\t%ld\n", max_alloc);
dft_log("\n\n");
dft_log_flush();
}
void *
mymalloc(int size,const char *what,const char *where)
{
#ifdef DFT_PROFILING
timerOn(8); // Turn on memory allocation timer.
#endif // DFT_PROFILING
void *p;
int * pint;
int dieflag = 0;
if (size <= 0)
{
#ifdef DFT_PROFILING
timerOff(8); // Turn off memory allocation timer.
#endif // DFT_PROFILING
return((void*) 0);
}
// Allocating the memory
#ifdef DFT_MEMALIGN // not all platforms have memalign in standard lib
p = (void *) memalign(32, size + PREFIX*sizeof(int) + POSTFIX*sizeof(char) );
#else
p = (void *) malloc(size + PREFIX*sizeof(int) + POSTFIX*sizeof(char) );
#endif
if (p == (void*) 0)
{
mem_trace_report();
die("Can't malloc %d for %s in %s.\n", size, what, where);
}
// Post-allocation work.
// The prefix memory is
// [MAGIC1, SIZE, NUM_BLOCKS, SIZE, MAGIC2, ... content ... ]
//
pint = (int*) p;
pint[0] = MAGIC1;
pint[1] = size;
pint[2] = num_blocks;
pint[3] = size;
pint[4] = MAGIC2;
pint += PREFIX; // PREFIX >= 5
p = (void*) pint;
num_blocks++;
accum_alloc += size;
current_alloc += size;
if (current_alloc > max_alloc)
max_alloc = current_alloc;
if (size > max_block)
max_block = size;
{
int i;
char *c = (char *)p;
for (i=0; i < size; i++)
c[i] = 0;
}
// The postfix memory is
// [ ... content ... , MAGIC3 ]
//
strncpy((char*)p+size, MAGIC3, POSTCHECK);
#ifdef DFT_PROFILING
timerOff(8); // Turn off memory allocation timer.
#endif // DFT_PROFILING
return p;
}
void
myfree(void *ptr)
{
int size, * pint;
char errstr[100];
int error_flag = 0;
// check for prefix MAGICs.
pint = (int*) ptr;
pint -= PREFIX;
if (pint[0] != MAGIC1)
{
// MAGIC string 1 corrupted.
dft_log(DFT_SILENCE,
"MAGIC 1 corrupted in memory trace, block %d, %d != %d\n",
pint[2], pint[0], MAGIC1);
dft_log_flush();
error_flag = 1;
}
if (pint[4] != MAGIC2)
{
// MAGIC string 2 corrupted.
dft_log(DFT_SILENCE,
"MAGIC 2 corrupted in memory trace, block %d, %d != %d\n",
pint[2], pint[4], MAGIC2);
dft_log_flush();
error_flag = 1;
}
size = pint[1];
if (pint[1] != pint[3])
{
// size of blocks mismatch.
dft_log(DFT_SILENCE,
"Size of blocks mismatch, block %d, %d != %d\n",
pint[2], pint[1], pint[3]); dft_log_flush();
error_flag = 1;
}
// check for postfix MAGICs.
if (error_flag == 0) {
char * pchar = (char*) ptr + size;
if (strncmp(pchar,MAGIC3,POSTCHECK)!=0)
{
// MAGIC string 3 corrupted.
dft_log(DFT_SILENCE,
"MAGIC 3 corrupted in memory trace\n");
dft_log_flush();
error_flag = 1;
}
}
if (error_flag == 0) {
size = pint[1];
current_alloc += -size;
free(pint);
}
else
{
mem_trace_report();
dft_log_flush();
die("Die in mem trace.");
}
}
#endif // DFT_TRACE_MEM
syntax highlighted by Code2HTML, v. 0.9.1