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 * Gromacs Runs On Most of All Computer Systems
42 * Memory allocation routines in gromacs:
44 * If an allocation fails, the program is halted by means of the
45 * fatal_error routine, which outputs source file and line number
46 * and the name of the variable involved.
48 * Macro's which can be used:
51 * Allocates memory for nelem elements and returns this in ptr.
52 * The allocated memory is initialized to zeros.
55 * Reallocates memory for nelem elements and returns this in ptr.
58 * Allocates memory for size bytes and returns this in ptr.
60 * scalloc(ptr,nelem,elsize)
61 * Allocates memory for nelem elements of size elsize and returns
65 * Reallocates memory for size bytes and returns this in ptr.
68 * Frees memory referenced by ptr.
70 * snew_aligned(ptr,nelem,alignment)
71 * Allocates memory for nelem elements and returns this in ptr.
72 * The allocated memory is initialized to zeroes.
73 * alignment=n will constrain ptr to be n-byte aligned.
74 * This pointer should only be freed with sfree_aligned, since
75 * it may not be the value returned by the underlying malloc.
78 * Frees aligned memory referenced by ptr.
80 ****************************************************************************
82 * Functions which are used by the macro's:
84 * extern void *save_malloc(char *name,char *file,int line,int size);
85 * Like alloc, returns a pointer to the allocated space, uses name, file
86 * and line to generate an error message when allocation failed.
88 * extern void *save_calloc(char *name,char *file,int line,
89 * size_t nelem,size_t elsize);
90 * Like calloc, returns a pointer to the allocated space, uses name, file
91 * and line to generate an error message when allocation failed.
93 * extern void *save_realloc(char *name,char *file,int line,
94 * void *ptr,size_t size);
95 * Like realloc, returns a pointer to the allocated space, uses name, file
96 * and line to generate an error message when allocation failed.
97 * If ptr equals NULL, malloc is called in stead of realloc, in this way
98 * it is possible to combine first and later allocations.
100 * extern void save_free(char *name,char *file,int line, void *ptr);
101 * Like free, uses name, file and line to generate an error message when
104 * extern size_t maxavail();
105 * Returns the maximum available allocation unit, by applying a binary
106 * search on the largest block of memory available. After allocation
107 * it invokes free to restore the original state. So it is important
108 * that free can undo the effect of a malloc.
110 * extern size_t memavail();
111 * Returns the total of available allocation unit, by applying maxavail
112 * until no space is left, it then frees all allocated space and returns
113 * the sum of the previously allocated space. As mentioned with maxavail,
114 * it is important that free can undo the effect of a malloc.
116 * extern void *save_malloc_aligned(char *name,char *file,int line,size_t size,size_t alignment);
117 * Like alloc, returns a pointer to the allocated space, uses name, file
118 * and line to generate an error message when allocation failed.
119 * The returned pointer will be n-byte aligned, where n=alignment.
120 * The pointer should only be freed with a call to save_free.
122 * extern void save_free_aligned(char *name,char *file,int line, void *ptr);
123 * Like free, uses name, file and line to generate an error message when
124 * the free failed. This function is intended to be called for
125 * pointers allocated with save_malloc_aligned, and may not work
126 * on normal pointers.
133 void *save_malloc(const char *name
,const char *file
,int line
,size_t size
);
134 void *save_calloc(const char *name
,const char *file
,int line
,
135 size_t nelem
,size_t elsize
);
136 void *save_realloc(const char *name
,const char *file
,int line
,
137 void *ptr
,size_t nelem
,size_t elsize
);
138 void save_free(const char *name
,const char *file
,int line
, void *ptr
);
139 size_t maxavail(void);
140 size_t memavail(void);
142 /* Aligned-memory counterparts */
144 void *save_calloc_aligned(const char *name
,const char *file
,int line
,
145 unsigned nelem
,size_t elsize
,size_t alignment
);
146 void save_free_aligned(const char *name
,const char *file
,int line
, void *ptr
);
151 /* Use of sizeof(T) in _snew() and _srenew() can cause obscure bugs if
152 * several files define distinct data structures with identical names and
153 * allocate memory for them using the macros below.
154 * For this reason, the size of an element is passed as a parameter.
156 * The C versions work fine in such cases, but when compiled with a C++
157 * compiler (and if the compiler does not inline the calls), the linker cannot
158 * tell that data structures with identical names are actually different and
159 * links calls to these template functions incorrectly, which can result in
160 * allocation of an incorrect amount of memory if the element size is computed
161 * within the function. Even with the size passed as a parameter, incorrect
162 * linkage will occur, but as the type is now only present in the cast, it
163 * should not cause problems.
165 template <typename T
>
166 void _snew(const char *name
, const char *file
, int line
,
167 T
*&ptr
, size_t nelem
, size_t elsize
)
169 ptr
= (T
*)save_calloc(name
, file
, line
, nelem
, elsize
);
171 template <typename T
>
172 void _srenew(const char *name
, const char *file
, int line
,
173 T
*&ptr
, size_t nelem
, size_t elsize
)
175 ptr
= (T
*)save_realloc(name
, file
, line
, ptr
, nelem
, elsize
);
177 template <typename T
>
178 void _smalloc(const char *name
, const char *file
, int line
, T
*&ptr
, size_t size
)
180 ptr
= (T
*)save_malloc(name
, file
, line
, size
);
182 template <typename T
>
183 void _srealloc(const char *name
, const char *file
, int line
, T
*&ptr
, size_t size
)
185 ptr
= (T
*)save_realloc(name
, file
, line
, ptr
, size
, sizeof(char));
187 template <typename T
>
188 void _snew_aligned(const char *name
, const char *file
, int line
,
189 T
*&ptr
, size_t nelem
, size_t elsize
,size_t alignment
)
191 ptr
= (T
*)save_calloc_aligned(name
, file
, line
, nelem
, elsize
, alignment
);
194 #define snew(ptr,nelem) _snew(#ptr,__FILE__,__LINE__,(ptr),(nelem),sizeof(*(ptr)))
195 #define srenew(ptr,nelem) _srenew(#ptr,__FILE__,__LINE__,(ptr),(nelem),sizeof(*(ptr)))
196 #define smalloc(ptr, size) _smalloc(#ptr,__FILE__,__LINE__,(ptr),(size))
197 #define srealloc(ptr, size) _srealloc(#ptr,__FILE__,__LINE__,(ptr),(size))
198 #define snew_aligned(ptr,nelem,alignment) _snew_aligned(#ptr,__FILE__,__LINE__,(ptr),(nelem),sizeof(*(ptr)),alignment)
202 /* These macros work in C, not in C++ */
203 #define snew(ptr,nelem) (ptr)=save_calloc(#ptr,__FILE__,__LINE__,\
204 (nelem),sizeof(*(ptr)))
205 #define srenew(ptr,nelem) (ptr)=save_realloc(#ptr,__FILE__,__LINE__,\
206 (ptr),(nelem),sizeof(*(ptr)))
207 #define smalloc(ptr,size) (ptr)=save_malloc(#ptr,__FILE__,__LINE__,size)
208 #define scalloc(ptr,nelem,elsize)\
209 (ptr)=save_calloc(#ptr,__FILE__,__LINE__,nelem,elsize)
210 #define srealloc(ptr,size) (ptr)=save_realloc(#ptr,__FILE__,__LINE__,\
212 #define snew_aligned(ptr,nelem,alignment) (ptr)=save_calloc_aligned(#ptr,__FILE__,__LINE__,(nelem),sizeof(*(ptr)),alignment)
215 #define sfree(ptr) save_free(#ptr,__FILE__,__LINE__,(ptr))
217 /* call this ONLY with a pointer obtained through snew_aligned or
219 #define sfree_aligned(ptr) save_free_aligned(#ptr,__FILE__,__LINE__,(ptr))
221 #endif /* _smalloc_h */