27 #include <lal/LALMalloc.h>
28 #include <lal/LALStdio.h>
29 #include <lal/LALError.h>
32 #define UNUSED __attribute__ ((unused))
47 #define XLAL_TEST_POINTER( ptr, size ) \
48 if ( ! (ptr) && (size) ) \
49 XLAL_ERROR_NULL( XLAL_ENOMEM ); \
51 #define XLAL_TEST_POINTER_LONG( ptr, size, file, line ) \
52 if ( ! (ptr) && (size) ) \
54 XLALPrintError( "XLALError - %s in %s:%d", __func__, file, line ); \
55 XLAL_ERROR_NULL( XLAL_ENOMEM ); \
58 #define XLAL_TEST_POINTER_ALIGNED( ptr, size, retval ) \
59 if ( ! (ptr) && (size) && (retval) ) \
60 XLAL_ERROR_NULL( XLAL_ENOMEM ); \
62 #define XLAL_TEST_POINTER_ALIGNED_LONG( ptr, size, retval, file, line ) \
63 if ( ! (ptr) && (size) && (retval) ) \
65 XLALPrintError( "XLALError - %s in %s:%d", __func__, file, line ); \
66 XLAL_ERROR_NULL( XLAL_ENOMEM ); \
131 #if LAL_FFTW3_MEMALIGN_ENABLED
133 #ifndef HAVE_POSIX_MEMALIGN
134 #error no posix_memalign available
137 int XLALIsMemoryAligned(
void *ptr)
139 return LAL_IS_MEMORY_ALIGNED(ptr);
142 void *XLALMallocAlignedLong(
size_t size,
const char *
file,
int line)
146 retval = posix_memalign(&
p, LAL_MEM_ALIGNMENT, size);
151 void *(XLALMallocAligned)(
size_t size)
155 retval = posix_memalign(&
p, LAL_MEM_ALIGNMENT, size);
160 void *XLALCallocAlignedLong(
size_t nelem,
size_t elsize,
const char *
file,
int line)
162 size_t size = nelem * elsize;
163 void *
p = XLALMallocAlignedLong(size,
file, line);
169 void *(XLALCallocAligned)(
size_t nelem,
size_t elsize)
171 size_t size = nelem * elsize;
172 void *
p = (XLALMallocAligned)(size);
178 void *XLALReallocAlignedLong(
void *ptr,
size_t size,
const char *
file,
int line)
182 return XLALMallocAlignedLong(size,
file, line);
184 XLALFreeAligned(ptr);
187 p = realloc(ptr, size);
188 if (XLALIsMemoryAligned(
p))
191 ptr = XLALMallocAlignedLong(size,
file, line);
192 memcpy(ptr,
p, size);
197 void *(XLALReallocAligned)(
void *ptr,
size_t size)
201 return XLALMallocAligned(size);
203 XLALFreeAligned(ptr);
206 p = realloc(ptr, size);
207 if (XLALIsMemoryAligned(
p))
210 ptr = XLALMallocAligned(size);
211 memcpy(ptr,
p, size);
216 void XLALFreeAligned(
void *ptr)
231 #ifndef LAL_MEMORY_FUNCTIONS_DISABLED
233 #ifdef LAL_PTHREAD_LOCK
235 static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
237 #define pthread_mutex_lock( pmut )
238 #define pthread_mutex_unlock( pmut )
241 #include <lal/LALStdlib.h>
260 static const size_t magic = 0xABadCafe;
262 #define allocsz(n) ((lalDebugLevel & LALMEMPADBIT) ? (padFactor * (n) + prefix) : (n))
278 #define DEL ((struct allocNode*) &hash_del)
281 #define HASHIDX(x) ((int)( ((intptr_t)( (x)->addr )) % alloc_data_len ))
284 #define INCRIDX(i) do { if (++(i) == alloc_data_len) { (i) = 0; } } while(0)
287 #define EQUAL(x, y) ((x)->addr == (y)->addr)
291 #define UNUSED __attribute__ ((unused))
310 for (
int k = 0; k < old_data_len; ++k) {
311 if (old_data[k] != NULL && old_data[k] !=
DEL) {
418 static void *
PadAlloc(
size_t *
p,
size_t n,
int keep,
const char *func,
const char *
file,
int line)
431 XLALPrintError(
"%s meminfo: allocating %zu bytes at address %p in %s:%d\n",
440 for (i = keep ? n : 0; i <
padFactor * n; ++i) {
449 return (
void *) (((
char *)
p) +
prefix);
465 lalRaiseHook(SIGSEGV,
"%s error: tried to free NULL pointer in %s:%d\n",
474 XLALPrintError(
"%s meminfo: freeing %zu bytes at address %p in %s:%d\n",
478 if (n == (
size_t)(-1)) {
480 "%s error: tried to free a freed pointer at address %p in %s:%d\n",
487 "%s error: wrong magic for pointer at address %p in %s:%d\n",
492 if (((
long) n) < 0) {
494 "%s error: corrupt size descriptor for pointer at address %p in %s:%d\n",
502 lalRaiseHook(SIGSEGV,
"%s error: array bounds overwritten\n"
503 "Byte %ld past end of array has changed\n"
504 "Corrupted address: %p\nArray address: %p\n"
513 lalRaiseHook(SIGSEGV,
"%s error: lalMallocTotal too small\n",
519 for (i = keep ? n : 0; i <
padFactor * n; ++i) {
543 if (!(newnode = malloc(
sizeof(*newnode)))) {
584 static void *
ModAlloc(
void *
p,
void *
q,
size_t n,
const char *func,
638 XLALPrintError(
"LALMalloc: failed to allocate %zd bytes of memory\n", n);
676 XLALPrintError(
"LALMalloc: failed to allocate %zd bytes of memory\n", n);
685 return q ? memset(
q, 0, sz) : NULL;
701 return realloc(
q, n);
710 XLALPrintError(
"LALMalloc: failed to allocate %zd bytes of memory\n", n);
735 q =
ModAlloc(
q,
PadAlloc(realloc(
p,
allocsz(n)), n, 1,
"LALRealloc",
file,
line), n,
"LALRealloc",
file,
line);
811 lalRaiseHook(SIGSEGV,
"LALCheckMemoryLeaks: memory leak\n");
814 (
"LALCheckMemoryLeaks meminfo: no memory leaks detected\n");
int(* lalRaiseHook)(int, const char *,...)
static const size_t padFactor
static UNUSED int AllocHashTblResize(void)
#define XLAL_TEST_POINTER(ptr, size)
static UNUSED struct allocNode * AllocHashTblFind(struct allocNode *x)
void XLALFreeLong(void *p, const char *file UNUSED, int line UNUSED)
static UNUSED struct allocNode * AllocHashTblExtract(struct allocNode *x)
static void * ModAlloc(void *p, void *q, size_t n, const char *func, const char *file, int line)
static const size_t prefix
#define XLAL_TEST_POINTER_ALIGNED_LONG(ptr, size, retval, file, line)
static void * PadAlloc(size_t *p, size_t n, int keep, const char *func, const char *file, int line)
static UNUSED int CheckAllocList(void)
#define pthread_mutex_lock(pmut)
static struct allocNode ** alloc_data
static int alloc_data_len
static const size_t repadding
static const void * hash_del
static UNUSED int AllocHashTblAdd(struct allocNode *x)
#define pthread_mutex_unlock(pmut)
static void * UnPadAlloc(void *p, int keep, const char *func, const char *file, int line)
static const size_t magic
void LALCheckMemoryLeaks(void)
static void * PushAlloc(void *p, size_t n, const char *file, int line)
#define XLAL_TEST_POINTER_LONG(ptr, size, file, line)
static void * PopAlloc(void *p, const char *func, const char *file, int line)
static const size_t padding
#define XLAL_TEST_POINTER_ALIGNED(ptr, size, retval)
static UNUSED struct allocNode * FindAlloc(void *p)
int XLALPrintError(const char *fmt,...)
@ LALMEMINFOBIT
enable memory info messages
@ LALMEMPADBIT
enable memory padding
@ LALMEMTRKBIT
enable memory tracking
@ LALMEMDBGBIT
enable memory debugging routines
void LALFreeShort(void *q)
void *() XLALCalloc(size_t m, size_t n)
void LALFreeLong(void *q, const char *file, const int line)
size_t lalMallocTotalPeak
peak amount of memory allocated so far
void * XLALCallocLong(size_t m, size_t n, const char *file, int line)
void * LALCallocShort(size_t m, size_t n)
void * XLALReallocLong(void *p, size_t n, const char *file, int line)
void * LALMallocLong(size_t n, const char *file, int line)
void * LALCallocLong(size_t m, size_t n, const char *file, int line)
void *() XLALMalloc(size_t n)
void * LALReallocLong(void *q, size_t n, const char *file, const int line)
size_t lalMallocTotal
current amount of memory allocated by process
void *() XLALRealloc(void *p, size_t n)
void * XLALMallocLong(size_t n, const char *file, int line)
void * LALReallocShort(void *p, size_t n)
void * LALMallocShort(size_t n)