2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
42 /* This file is completely threadsafe - keep it that way! */
45 #include "thread_mpi/threads.h"
52 #include "gmx_fatal.h"
60 static void log_action(int bMal,const char *what,const char *file,int line,
61 int nelem,int size,void *ptr)
72 tMPI_Thread_mutex_lock(&gmx_logfile_mtx);
75 /* This total memory count is not correct, since with realloc
76 * it adds the whole size again, not just the increment.
78 /* This static variable is protected by the mutex too... */
82 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) {
91 fname = strrchr(file,DIR_SEPARATOR);
98 printf("%s: %.1f MB [%s, line %d, nelem %d, size %d]\n",
99 what ? what : NN,bytes/1024.0,
100 file ? fname : NN,line,nelem,size);
102 #ifdef GMX_THREAD_MPI
103 tMPI_Thread_mutex_unlock(&gmx_logfile_mtx);
108 static char *gmx_large_int_str(gmx_large_int_t i,char *buf)
110 sprintf(buf,gmx_large_int_pfmt,i);
115 void *save_malloc(const char *name,const char *file,int line,size_t size)
124 if ((p=malloc(size))==NULL) {
126 gmx_fatal(errno,__FILE__,__LINE__,
127 "Not enough memory. Failed to malloc %s bytes for %s\n"
128 "(called from file %s, line %d)",
129 gmx_large_int_str((gmx_large_int_t)size,cbuf),
132 (void) memset(p,0,size);
135 log_action(1,name,file,line,1,size,p);
140 void *save_calloc(const char *name,const char *file,int line,
141 size_t nelem,size_t elsize)
146 if ((nelem==0)||(elsize==0))
150 #ifdef PRINT_ALLOC_KB
152 if (nelem*elsize >= PRINT_ALLOC_KB*1024) {
155 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
157 printf("Allocating %.1f MB for %s (called from file %s, line %d on %d)\n",
158 nelem*elsize/1048576.0,name,file,line,rank);
161 #ifdef GMX_BROKEN_CALLOC
162 /* emulate calloc(3) with malloc/memset on machines with
163 a broken calloc, e.g. in -lgmalloc on cray xt3. */
164 if ((p=malloc((size_t)nelem*(size_t)elsize))==NULL)
165 gmx_fatal(errno,__FILE__,__LINE__,
166 "Not enough memory. Failed to calloc %"gmx_large_int_fmt
167 " elements of size %"gmx_large_int_fmt
168 " for %s\n(called from file %s, line %d)",
169 (gmx_large_int_t)nelem,(gmx_large_int_t)elsize,
171 memset(p, 0,(size_t) (nelem * elsize));
173 if ((p=calloc((size_t)nelem,(size_t)elsize))==NULL)
174 gmx_fatal(errno,__FILE__,__LINE__,
175 "Not enough memory. Failed to calloc %"gmx_large_int_fmt
176 " elements of size %"gmx_large_int_fmt
177 " for %s\n(called from file %s, line %d)",
178 (gmx_large_int_t)nelem,(gmx_large_int_t)elsize,name,file,line);
182 log_action(1,name,file,line,nelem,elsize,p);
187 void *save_realloc(const char *name,const char *file,int line,void *ptr,
188 size_t nelem,size_t elsize)
191 size_t size = nelem*elsize;
196 save_free(name, file, line, ptr);
200 #ifdef PRINT_ALLOC_KB
202 if (size >= PRINT_ALLOC_KB*1024) {
205 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
207 printf("Reallocating %.1f MB for %s (called from file %s, line %d on %d)\n",
208 size/1048576.0,name,file,line,rank);
212 p=malloc((size_t)size);
214 p=realloc(ptr,(size_t)size);
217 gmx_fatal(errno,__FILE__,__LINE__,
218 "Not enough memory. Failed to realloc %s bytes for %s, %s=%x\n"
219 "(called from file %s, line %d)",
220 gmx_large_int_str((gmx_large_int_t)size,cbuf),
221 name,name,ptr,file,line);
224 log_action(1,name,file,line,1,size,p);
230 void save_free(const char *name,const char *file,int line, void *ptr)
233 log_action(0,name,file,line,0,0,ptr);
239 size_t maxavail(void)
242 size_t low,high,size;
246 while ((high-low) > 4) {
248 if ((ptr=(char *)malloc((size_t)size))==NULL)
258 size_t memavail(void)
265 if ((ptr=(char *)malloc((size_t)size)) != NULL) {
273 /* If we don't have useful routines for allocating aligned memory,
274 * then we have to use the old-style GROMACS approach bitwise-ANDing
275 * pointers to ensure alignment. We store the pointer to the originally
276 * allocated region in the space before the returned pointer */
278 /* we create a positive define for the absence of an system-provided memalign */
279 #if (!defined HAVE_POSIX_MEMALIGN && !defined HAVE_MEMALIGN && \
280 !defined HAVE__ALIGNED_MALLOC)
281 #define GMX_OWN_MEMALIGN
285 /* Pointers allocated with this routine should only be freed
286 * with save_free_aligned, however this will only matter
287 * on systems that lack posix_memalign() and memalign() when
288 * freeing memory that needed to be adjusted to achieve
289 * the necessary alignment. */
290 void *save_malloc_aligned(const char *name,const char *file,int line,
291 unsigned nelem,size_t elsize,size_t alignment)
295 gmx_bool allocate_fail;
299 gmx_fatal(errno,__FILE__,__LINE__,
300 "Cannot allocate aligned memory with alignment of zero!\n(called from file %s, line %d)",file,line);
304 if (nelem ==0 || elsize == 0)
310 #ifdef PRINT_ALLOC_KB
311 if (nelem*elsize >= PRINT_ALLOC_KB*1024)
313 printf("Allocating %.1f MB for %s\n",
314 nelem*elsize/(PRINT_ALLOC_KB*1024.0),name);
318 allocate_fail = FALSE; /* stop compiler warnings */
319 #ifdef HAVE_POSIX_MEMALIGN
320 allocate_fail = (0!=posix_memalign(&malloced, alignment, nelem*elsize));
321 #elif defined HAVE_MEMALIGN
322 allocate_fail = ((malloced=memalign(alignment, nelem*elsize)) == NULL);
323 #elif defined HAVE__ALIGNED_MALLOC
324 allocate_fail = ((malloced=_aligned_malloc(nelem*elsize, alignment))
327 allocate_fail = ((malloced = malloc(nelem*elsize+alignment+
328 sizeof(void*)))==NULL);
332 gmx_fatal(errno,__FILE__,__LINE__,
333 "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);
335 /* we start with the original pointer */
336 aligned=(void**)malloced;
338 #ifdef GMX_OWN_MEMALIGN
339 /* Make the aligned pointer, and save the underlying pointer that
340 * we're allowed to free(). */
342 /* we first make space to store that underlying pointer: */
343 aligned = aligned + 1;
344 /* then we apply a bit mask */
345 aligned = (void *) (((size_t) aligned + alignment - 1) &
346 (~((size_t) (alignment-1))));
347 /* and we store the original pointer in the area just before the
348 pointer we're going to return */
349 aligned[-1] = malloced;
352 return (void*)aligned;
355 void *save_calloc_aligned(const char *name,const char *file,int line,
356 unsigned nelem,size_t elsize,size_t alignment)
358 void *aligned = save_malloc_aligned(name, file, line, nelem, elsize, alignment);
361 memset(aligned, 0, (size_t)(nelem * elsize));
366 /* This routine can NOT be called with any pointer */
367 void save_free_aligned(const char *name,const char *file,int line,void *ptr)
374 #ifdef GMX_OWN_MEMALIGN
375 /* we get the pointer from just before the memaligned pointer */
376 free= ((void**)ptr)[-1];
379 #ifndef HAVE__ALIGNED_MALLOC
380 /* (Now) we're allowed to use a normal free() on this pointer. */
381 save_free(name,file,line,free);