changed reading hint
[gromacs/adressmacs.git] / src / fftw / malloc.c
blob52b130379d25868d4b494e3b5948d1773207b987
1 /*
2 * Copyright (c) 1997-1999 Massachusetts Institute of Technology
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * malloc.c -- memory allocation related functions
24 /* $Id$ */
25 #ifdef FFTW_USING_CILK
26 #include <cilk.h>
27 #include <cilk-compat.h>
28 #endif
30 #include <fftw-int.h>
31 #include <stdio.h>
32 #include <stdlib.h>
34 #ifdef HAVE_MALLOC_H
35 #include <malloc.h>
36 #endif
38 fftw_malloc_type_function fftw_malloc_hook = 0;
39 fftw_free_type_function fftw_free_hook = 0;
40 fftw_die_type_function fftw_die_hook = 0;
42 /**********************************************************
43 * DEBUGGING CODE
44 **********************************************************/
45 #ifdef FFTW_DEBUG
46 static int fftw_malloc_cnt = 0;
49 * debugging malloc/free. Initialize every malloced and freed area to
50 * random values, just to make sure we are not using uninitialized
51 * pointers. Also check for writes past the ends of allocated blocks,
52 * and a couple of other things.
54 * This code is a quick and dirty hack -- use at your own risk.
57 static int fftw_malloc_total = 0, fftw_malloc_max = 0, fftw_malloc_cnt_max = 0;
59 #define MAGIC 0xABadCafe
60 #define PAD_FACTOR 2
61 #define TWOINTS (2 * sizeof(int))
63 #define VERBOSE_ALLOCATION 0
65 #if VERBOSE_ALLOCATION
66 #define WHEN_VERBOSE(a) a
67 #else
68 #define WHEN_VERBOSE(a)
69 #endif
71 void *fftw_malloc(size_t n)
73 char *p;
74 int i;
76 fftw_malloc_total += n;
78 if (fftw_malloc_total > fftw_malloc_max)
79 fftw_malloc_max = fftw_malloc_total;
81 p = (char *) malloc(PAD_FACTOR * n + TWOINTS);
82 if (!p)
83 fftw_die("fftw_malloc: out of memory\n");
85 /* store the size in a known position */
86 ((int *) p)[0] = n;
87 ((int *) p)[1] = MAGIC;
88 for (i = 0; i < PAD_FACTOR * n; ++i)
89 p[i + TWOINTS] = (char) (i ^ 0xDEADBEEF);
91 ++fftw_malloc_cnt;
93 if (fftw_malloc_cnt > fftw_malloc_cnt_max)
94 fftw_malloc_cnt_max = fftw_malloc_cnt;
96 /* skip the size we stored previously */
97 return (void *) (p + TWOINTS);
100 void fftw_free(void *p)
102 char *q;
104 if (!p)
105 return;
107 q = ((char *) p) - TWOINTS;
108 if (!q)
109 fftw_die("fftw_free: tried to free NULL+TWOINTS pointer!\n");
112 int n = ((int *) q)[0];
113 int magic = ((int *) q)[1];
114 int i;
116 WHEN_VERBOSE( {
117 printf("FFTW_FREE %d\n", n);
118 fflush(stdout);
121 *((int *) q) = 0; /* set to zero to detect duplicate free's */
123 if (magic != MAGIC)
124 fftw_die("Wrong magic in fftw_free()!\n");
125 ((int *) q)[1] = ~MAGIC;
127 if (n < 0)
128 fftw_die("Tried to free block with corrupt size descriptor!\n");
130 fftw_malloc_total -= n;
132 if (fftw_malloc_total < 0)
133 fftw_die("fftw_malloc_total went negative!\n");
135 /* check for writing past end of array: */
136 for (i = n; i < PAD_FACTOR * n; ++i)
137 if (q[i + TWOINTS] != (char) (i ^ 0xDEADBEEF)) {
138 fflush(stdout);
139 fprintf(stderr, "Byte %d past end of array has changed!\n",
140 i - n + 1);
141 fftw_die("Array bounds overwritten!\n");
143 for (i = 0; i < PAD_FACTOR * n; ++i)
144 q[i + TWOINTS] = (char) (i ^ 0xBEEFDEAD);
146 --fftw_malloc_cnt;
148 if (fftw_malloc_cnt < 0)
149 fftw_die("fftw_malloc_cnt went negative!\n");
151 if (fftw_malloc_cnt == 0 && fftw_malloc_total > 0 ||
152 fftw_malloc_cnt > 0 && fftw_malloc_total == 0)
153 fftw_die("fftw_malloc_cnt/total not zero at the same time!\n");
155 free(q);
159 #else
160 /**********************************************************
161 * NON DEBUGGING CODE
162 **********************************************************/
163 /* production version, no hacks */
165 void *fftw_malloc(size_t n)
167 void *p;
169 if (fftw_malloc_hook)
170 return fftw_malloc_hook(n);
172 if (n == 0)
173 n = 1;
175 p = malloc(n);
177 if (!p)
178 fftw_die("fftw_malloc: out of memory\n");
180 return p;
183 void fftw_free(void *p)
185 if (p) {
186 if (fftw_free_hook) {
187 fftw_free_hook(p);
188 return;
190 free(p);
194 #endif
196 /* die when fatal errors occur */
197 void fftw_die(const char *s)
199 if (fftw_die_hook)
200 fftw_die_hook(s);
202 fflush(stdout);
203 fprintf(stderr, "fftw: %s", s);
204 exit(EXIT_FAILURE);
207 /* check for memory leaks when debugging */
208 void fftw_check_memory_leaks(void)
210 extern int fftw_node_cnt, fftw_plan_cnt, fftw_twiddle_size;
212 #ifdef FFTW_DEBUG
213 if (fftw_malloc_cnt || fftw_malloc_total ||
214 fftw_node_cnt || fftw_plan_cnt || fftw_twiddle_size) {
215 fflush(stdout);
216 fprintf(stderr,
217 "MEMORY LEAK!!!\n"
218 "fftw_malloc = %d"
219 " node=%d plan=%d twiddle=%d\n"
220 "fftw_malloc_total = %d\n",
221 fftw_malloc_cnt,
222 fftw_node_cnt, fftw_plan_cnt, fftw_twiddle_size,
223 fftw_malloc_total);
224 exit(EXIT_FAILURE);
226 #else
227 if (fftw_node_cnt || fftw_plan_cnt || fftw_twiddle_size) {
228 fflush(stdout);
229 fprintf(stderr,
230 "MEMORY LEAK!!!\n"
231 " node=%d plan=%d twiddle=%d\n",
232 fftw_node_cnt, fftw_plan_cnt, fftw_twiddle_size);
233 exit(EXIT_FAILURE);
235 #endif
238 void fftw_print_max_memory_usage(void)
240 #ifdef FFTW_DEBUG
241 printf("\nMaximum number of blocks allocated = %d\n"
242 "Maximum number of bytes allocated = %0.3f kB\n",
243 fftw_malloc_cnt_max, fftw_malloc_max / 1024.0);
244 #endif