3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROningen Mixture of Alchemy and Childrens' Stories
39 /* This file is completely threadsafe - keep it that way! */
42 #include "thread_mpi/threads.h"
49 #include "gmx_fatal.h"
57 static void log_action(int bMal, const char *what, const char *file, int line,
58 int nelem, int size, void *ptr)
71 tMPI_Thread_mutex_lock(&gmx_logfile_mtx);
74 /* This total memory count is not correct, since with realloc
75 * it adds the whole size again, not just the increment.
77 /* This static variable is protected by the mutex too... */
81 if (debug && (bytes != 0))
83 fprintf(debug, "%s:%d kB (%7d kB) [%s, line %d, nelem %d, size %d]\n",
84 what ? what : NN, bytes, btot/1024,
85 file ? file : NN, line, nelem, size);
87 /* Print to stderr for things larger than 1 MB */
88 if (bytes >= 1024 || bytes <= -1024)
93 fname = strrchr(file, DIR_SEPARATOR);
103 printf("%s: %.1f MB [%s, line %d, nelem %d, size %d]\n",
104 what ? what : NN, bytes/1024.0,
105 file ? fname : NN, line, nelem, size);
107 #ifdef GMX_THREAD_MPI
108 tMPI_Thread_mutex_unlock(&gmx_logfile_mtx);
113 static char *gmx_large_int_str(gmx_large_int_t i, char *buf)
115 sprintf(buf, gmx_large_int_pfmt, i);
120 void *save_malloc(const char *name, const char *file, int line, size_t size)
131 if ((p = malloc(size)) == NULL)
134 gmx_fatal(errno, __FILE__, __LINE__,
135 "Not enough memory. Failed to malloc %s bytes for %s\n"
136 "(called from file %s, line %d)",
137 gmx_large_int_str((gmx_large_int_t)size, cbuf),
140 (void) memset(p, 0, size);
143 log_action(1, name, file, line, 1, size, p);
148 void *save_calloc(const char *name, const char *file, int line,
149 size_t nelem, size_t elsize)
154 if ((nelem == 0) || (elsize == 0))
160 #ifdef PRINT_ALLOC_KB
162 if (nelem*elsize >= PRINT_ALLOC_KB*1024)
166 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
168 printf("Allocating %.1f MB for %s (called from file %s, line %d on %d)\n",
169 nelem*elsize/1048576.0, name, file, line, rank);
172 #ifdef GMX_BROKEN_CALLOC
173 /* emulate calloc(3) with malloc/memset on machines with
174 a broken calloc, e.g. in -lgmalloc on cray xt3. */
175 if ((p = malloc((size_t)nelem*(size_t)elsize)) == NULL)
177 gmx_fatal(errno, __FILE__, __LINE__,
178 "Not enough memory. Failed to calloc %"gmx_large_int_fmt
179 " elements of size %"gmx_large_int_fmt
180 " for %s\n(called from file %s, line %d)",
181 (gmx_large_int_t)nelem, (gmx_large_int_t)elsize,
184 memset(p, 0, (size_t) (nelem * elsize));
186 if ((p = calloc((size_t)nelem, (size_t)elsize)) == NULL)
188 gmx_fatal(errno, __FILE__, __LINE__,
189 "Not enough memory. Failed to calloc %"gmx_large_int_fmt
190 " elements of size %"gmx_large_int_fmt
191 " for %s\n(called from file %s, line %d)",
192 (gmx_large_int_t)nelem, (gmx_large_int_t)elsize, name, file, line);
197 log_action(1, name, file, line, nelem, elsize, p);
202 void *save_realloc(const char *name, const char *file, int line, void *ptr,
203 size_t nelem, size_t elsize)
206 size_t size = nelem*elsize;
211 save_free(name, file, line, ptr);
215 #ifdef PRINT_ALLOC_KB
217 if (size >= PRINT_ALLOC_KB*1024)
221 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
223 printf("Reallocating %.1f MB for %s (called from file %s, line %d on %d)\n",
224 size/1048576.0, name, file, line, rank);
229 p = malloc((size_t)size);
233 p = realloc(ptr, (size_t)size);
238 gmx_fatal(errno, __FILE__, __LINE__,
239 "Not enough memory. Failed to realloc %s bytes for %s, %s=%x\n"
240 "(called from file %s, line %d)",
241 gmx_large_int_str((gmx_large_int_t)size, cbuf),
242 name, name, ptr, file, line);
245 log_action(1, name, file, line, 1, size, p);
251 void save_free(const char *name, const char *file, int line, void *ptr)
254 log_action(0, name, file, line, 0, 0, ptr);
262 size_t maxavail(void)
265 size_t low, high, size;
269 while ((high-low) > 4)
272 if ((ptr = (char *)malloc((size_t)size)) == NULL)
285 size_t memavail(void)
293 if ((ptr = (char *)malloc((size_t)size)) != NULL)
302 /* If we don't have useful routines for allocating aligned memory,
303 * then we have to use the old-style GROMACS approach bitwise-ANDing
304 * pointers to ensure alignment. We store the pointer to the originally
305 * allocated region in the space before the returned pointer */
307 /* we create a positive define for the absence of an system-provided memalign */
308 #if (!defined HAVE_POSIX_MEMALIGN && !defined HAVE_MEMALIGN && \
309 !defined HAVE__ALIGNED_MALLOC)
310 #define GMX_OWN_MEMALIGN
314 /* Pointers allocated with this routine should only be freed
315 * with save_free_aligned, however this will only matter
316 * on systems that lack posix_memalign() and memalign() when
317 * freeing memory that needed to be adjusted to achieve
318 * the necessary alignment. */
319 void *save_malloc_aligned(const char *name, const char *file, int line,
320 unsigned nelem, size_t elsize, size_t alignment)
322 void **aligned = NULL;
323 void *malloced = NULL;
324 gmx_bool allocate_fail;
328 gmx_fatal(errno, __FILE__, __LINE__,
329 "Cannot allocate aligned memory with alignment of zero!\n(called from file %s, line %d)", file, line);
333 if (nelem == 0 || elsize == 0)
339 #ifdef PRINT_ALLOC_KB
340 if (nelem*elsize >= PRINT_ALLOC_KB*1024)
342 printf("Allocating %.1f MB for %s\n",
343 nelem*elsize/(PRINT_ALLOC_KB*1024.0), name);
347 allocate_fail = FALSE; /* stop compiler warnings */
348 #ifdef HAVE_POSIX_MEMALIGN
349 allocate_fail = (0 != posix_memalign(&malloced, alignment, nelem*elsize));
350 #elif defined HAVE_MEMALIGN
351 allocate_fail = ((malloced = memalign(alignment, nelem*elsize)) == NULL);
352 #elif defined HAVE__ALIGNED_MALLOC
353 allocate_fail = ((malloced = _aligned_malloc(nelem*elsize, alignment))
356 allocate_fail = ((malloced = malloc(nelem*elsize+alignment+
357 sizeof(void*))) == NULL);
361 gmx_fatal(errno, __FILE__, __LINE__,
362 "Not enough memory. Failed to allocate %u aligned elements of size %u for %s\n(called from file %s, line %d)", nelem, elsize, name, file, line);
364 /* we start with the original pointer */
365 aligned = (void**)malloced;
367 #ifdef GMX_OWN_MEMALIGN
368 /* Make the aligned pointer, and save the underlying pointer that
369 * we're allowed to free(). */
371 /* we first make space to store that underlying pointer: */
372 aligned = aligned + 1;
373 /* then we apply a bit mask */
374 aligned = (void *) (((size_t) aligned + alignment - 1) &
375 (~((size_t) (alignment-1))));
376 /* and we store the original pointer in the area just before the
377 pointer we're going to return */
378 aligned[-1] = malloced;
381 return (void*)aligned;
384 void *save_calloc_aligned(const char *name, const char *file, int line,
385 unsigned nelem, size_t elsize, size_t alignment)
387 void *aligned = save_malloc_aligned(name, file, line, nelem, elsize, alignment);
390 memset(aligned, 0, (size_t)(nelem * elsize));
395 /* This routine can NOT be called with any pointer */
396 void save_free_aligned(const char *name, const char *file, int line, void *ptr)
403 #ifdef GMX_OWN_MEMALIGN
404 /* we get the pointer from just before the memaligned pointer */
405 free = ((void**)ptr)[-1];
408 #ifndef HAVE__ALIGNED_MALLOC
409 /* (Now) we're allowed to use a normal free() on this pointer. */
410 save_free(name, file, line, free);