1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | #include "gromacs/utility/smalloc.h" |
38 | |
39 | #ifdef HAVE_CONFIG_H1 |
40 | #include <config.h> |
41 | #endif |
42 | |
43 | #include <errno(*__errno_location ()).h> |
44 | #include <stdio.h> |
45 | #include <stdlib.h> |
46 | #include <string.h> |
47 | |
48 | #ifdef WITH_DMALLOC |
49 | #include <dmalloc.h> |
50 | #endif |
51 | |
52 | #include "gromacs/utility/fatalerror.h" |
53 | #ifdef PRINT_ALLOC_KB |
54 | #include "gromacs/utility/gmxmpi.h" |
55 | #endif |
56 | |
57 | #ifdef DEBUG |
58 | #include "thread_mpi/threads.h" |
59 | |
60 | static void log_action(int bMal, const char *what, const char *file, int line, |
61 | int nelem, int size, void *ptr) |
62 | { |
63 | static int btot = 0; |
64 | char *NN = "NULL"; |
65 | int bytes; |
66 | |
67 | bytes = size*nelem; |
68 | if (!bMal) |
69 | { |
70 | bytes = -bytes; |
71 | } |
72 | |
73 | tMPI_Thread_mutex_lock(&gmx_logfile_mtx); |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | btot += bytes; |
80 | |
81 | bytes /= 1024; |
82 | if (debug && (bytes != 0)) |
83 | { |
84 | fprintf(debug, "%s:%d kB (%7d kB) [%s, line %d, nelem %d, size %d]\n", |
85 | what ? what : NN, bytes, btot/1024, |
86 | file ? file : NN, line, nelem, size); |
87 | } |
88 | |
89 | if (bytes >= 1024 || bytes <= -1024) |
90 | { |
91 | char *fname = NULL((void*)0); |
92 | if (file) |
93 | { |
94 | fname = strrchr(file, DIR_SEPARATOR); |
95 | if (fname) |
96 | { |
97 | fname++; |
98 | } |
99 | else |
100 | { |
101 | fname = file; |
102 | } |
103 | } |
104 | printf("%s: %.1f MB [%s, line %d, nelem %d, size %d]\n", |
105 | what ? what : NN, bytes/1024.0, |
106 | file ? fname : NN, line, nelem, size); |
107 | } |
108 | tMPI_Thread_mutex_unlock(&gmx_logfile_mtx); |
109 | } |
110 | #endif |
111 | |
112 | void *save_malloc(const char *name, const char *file, int line, size_t size) |
113 | { |
114 | void *p; |
115 | |
116 | p = NULL((void*)0); |
117 | if (size == 0) |
118 | { |
119 | p = NULL((void*)0); |
120 | } |
121 | else |
122 | { |
123 | if ((p = malloc(size)) == NULL((void*)0)) |
124 | { |
125 | gmx_fatal(errno(*__errno_location ()), __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/utility/smalloc.c", __LINE__125, |
126 | "Not enough memory. Failed to malloc %"GMX_PRId64"l" "d" " bytes for %s\n" |
127 | "(called from file %s, line %d)", |
128 | (gmx_int64_t)size, name, file, line); |
129 | } |
130 | (void) memset(p, 0, size); |
131 | } |
132 | #ifdef DEBUG |
133 | log_action(1, name, file, line, 1, size, p); |
134 | #endif |
135 | return p; |
136 | } |
137 | |
138 | void *save_calloc(const char *name, const char *file, int line, |
139 | size_t nelem, size_t elsize) |
140 | { |
141 | void *p; |
142 | |
143 | p = NULL((void*)0); |
144 | if ((nelem == 0) || (elsize == 0)) |
145 | { |
146 | p = NULL((void*)0); |
147 | } |
148 | else |
149 | { |
150 | #ifdef PRINT_ALLOC_KB |
151 | int rank = 0; |
152 | if (nelem*elsize >= PRINT_ALLOC_KB*1024) |
153 | { |
154 | #ifdef GMX_MPI |
155 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
156 | #endif |
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); |
159 | } |
160 | #endif |
161 | #ifdef GMX_BROKEN_CALLOC |
162 | |
163 | |
164 | if ((p = malloc((size_t)nelem*(size_t)elsize)) == NULL((void*)0)) |
165 | { |
166 | gmx_fatal(errno(*__errno_location ()), __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/utility/smalloc.c", __LINE__166, |
167 | "Not enough memory. Failed to calloc %"GMX_PRId64"l" "d" |
168 | " elements of size %"GMX_PRId64"l" "d" |
169 | " for %s\n(called from file %s, line %d)", |
170 | (gmx_int64_t)nelem, (gmx_int64_t)elsize, |
171 | name, file, line); |
172 | } |
173 | memset(p, 0, (size_t) (nelem * elsize)); |
174 | #else |
175 | if ((p = calloc((size_t)nelem, (size_t)elsize)) == NULL((void*)0)) |
176 | { |
177 | gmx_fatal(errno(*__errno_location ()), __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/utility/smalloc.c", __LINE__177, |
178 | "Not enough memory. Failed to calloc %"GMX_PRId64"l" "d" |
179 | " elements of size %"GMX_PRId64"l" "d" |
180 | " for %s\n(called from file %s, line %d)", |
181 | (gmx_int64_t)nelem, (gmx_int64_t)elsize, name, file, line); |
182 | } |
183 | #endif |
184 | } |
185 | #ifdef DEBUG |
186 | log_action(1, name, file, line, nelem, elsize, p); |
187 | #endif |
188 | return p; |
189 | } |
190 | |
191 | void *save_realloc(const char *name, const char *file, int line, void *ptr, |
192 | size_t nelem, size_t elsize) |
193 | { |
194 | void *p; |
195 | size_t size = nelem*elsize; |
196 | |
197 | p = NULL((void*)0); |
198 | if (size == 0) |
199 | { |
200 | save_free(name, file, line, ptr); |
201 | } |
202 | else |
203 | { |
204 | #ifdef PRINT_ALLOC_KB |
205 | int rank = 0; |
206 | if (size >= PRINT_ALLOC_KB*1024) |
207 | { |
208 | #ifdef GMX_MPI |
209 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
210 | #endif |
211 | printf("Reallocating %.1f MB for %s (called from file %s, line %d on %d)\n", |
212 | size/1048576.0, name, file, line, rank); |
213 | } |
214 | #endif |
215 | if (ptr == NULL((void*)0)) |
216 | { |
217 | p = malloc((size_t)size); |
218 | } |
219 | else |
220 | { |
221 | p = realloc(ptr, (size_t)size); |
222 | } |
223 | if (p == NULL((void*)0)) |
224 | { |
225 | gmx_fatal(errno(*__errno_location ()), __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/utility/smalloc.c", __LINE__225, |
226 | "Not enough memory. Failed to realloc %"GMX_PRId64"l" "d" " bytes for %s, %s=%x\n" |
227 | "(called from file %s, line %d)", |
228 | (gmx_int64_t)size, name, name, ptr, file, line); |
229 | } |
230 | #ifdef DEBUG |
231 | log_action(1, name, file, line, 1, size, p); |
232 | #endif |
233 | } |
234 | return p; |
235 | } |
236 | |
237 | void save_free(const char gmx_unused__attribute__ ((unused)) *name, const char gmx_unused__attribute__ ((unused)) *file, int gmx_unused__attribute__ ((unused)) line, void *ptr) |
238 | { |
239 | #ifdef DEBUG |
240 | log_action(0, name, file, line, 0, 0, ptr); |
241 | #endif |
242 | if (ptr != NULL((void*)0)) |
243 | { |
244 | free(ptr); |
245 | } |
246 | } |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | |
254 | #if (!defined HAVE_POSIX_MEMALIGN && !defined HAVE_MEMALIGN && \ |
255 | !defined HAVE__ALIGNED_MALLOC) |
256 | #define GMX_OWN_MEMALIGN |
257 | #endif |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | void *save_malloc_aligned(const char *name, const char *file, int line, |
266 | size_t nelem, size_t elsize, size_t alignment) |
267 | { |
268 | void **aligned = NULL((void*)0); |
269 | void *malloced = NULL((void*)0); |
270 | gmx_bool allocate_fail; |
271 | |
272 | if (alignment == 0) |
273 | { |
274 | gmx_fatal(errno(*__errno_location ()), __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/utility/smalloc.c", __LINE__274, |
275 | "Cannot allocate aligned memory with alignment of zero!\n(called from file %s, line %d)", file, line); |
276 | } |
277 | |
278 | |
279 | if (nelem == 0 || elsize == 0) |
280 | { |
281 | aligned = NULL((void*)0); |
282 | } |
283 | else |
284 | { |
285 | #ifdef PRINT_ALLOC_KB |
286 | if (nelem*elsize >= PRINT_ALLOC_KB*1024) |
287 | { |
288 | printf("Allocating %.1f MB for %s\n", |
289 | nelem*elsize/(PRINT_ALLOC_KB*1024.0), name); |
290 | } |
291 | #endif |
292 | |
293 | allocate_fail = FALSE0; |
| Value stored to 'allocate_fail' is never read |
294 | #ifdef HAVE_POSIX_MEMALIGN |
295 | allocate_fail = (0 != posix_memalign(&malloced, alignment, nelem*elsize)); |
296 | #elif defined HAVE_MEMALIGN |
297 | allocate_fail = ((malloced = memalign(alignment, nelem*elsize)) == NULL((void*)0)); |
298 | #elif defined HAVE__ALIGNED_MALLOC |
299 | allocate_fail = ((malloced = _aligned_malloc(nelem*elsize, alignment)) |
300 | == NULL((void*)0)); |
301 | #else |
302 | allocate_fail = ((malloced = malloc(nelem*elsize+alignment+ |
303 | sizeof(void*))) == NULL((void*)0)); |
304 | #endif |
305 | if (allocate_fail) |
306 | { |
307 | gmx_fatal(errno(*__errno_location ()), __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/utility/smalloc.c", __LINE__307, |
308 | "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); |
309 | } |
310 | |
311 | aligned = (void**)malloced; |
312 | |
313 | #ifdef GMX_OWN_MEMALIGN |
314 | |
315 | |
316 | |
317 | |
318 | aligned = aligned + 1; |
319 | |
320 | aligned = (void *) (((size_t) aligned + alignment - 1) & |
321 | (~((size_t) (alignment-1)))); |
322 | |
323 | |
324 | aligned[-1] = malloced; |
325 | #endif |
326 | } |
327 | return (void*)aligned; |
328 | } |
329 | |
330 | void *save_calloc_aligned(const char *name, const char *file, int line, |
331 | size_t nelem, size_t elsize, size_t alignment) |
332 | { |
333 | void *aligned = save_malloc_aligned(name, file, line, nelem, elsize, alignment); |
334 | if (aligned != NULL((void*)0)) |
335 | { |
336 | memset(aligned, 0, (size_t)(nelem * elsize)); |
337 | } |
338 | return aligned; |
339 | } |
340 | |
341 | |
342 | void save_free_aligned(const char *name, const char *file, int line, void *ptr) |
343 | { |
344 | int i, j; |
345 | void *free = ptr; |
346 | |
347 | if (NULL((void*)0) != ptr) |
348 | { |
349 | #ifdef GMX_OWN_MEMALIGN |
350 | |
351 | free = ((void**)ptr)[-1]; |
352 | #endif |
353 | |
354 | #ifndef HAVE__ALIGNED_MALLOC |
355 | |
356 | save_free(name, file, line, free); |
357 | #else |
358 | _aligned_free(free); |
359 | #endif |
360 | } |
361 | } |