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
25 #ifdef FFTW_USING_CILK
27 #include <cilk-compat.h>
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 /**********************************************************
44 **********************************************************/
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
61 #define TWOINTS (2 * sizeof(int))
63 #define VERBOSE_ALLOCATION 0
65 #if VERBOSE_ALLOCATION
66 #define WHEN_VERBOSE(a) a
68 #define WHEN_VERBOSE(a)
71 void *fftw_malloc(size_t n
)
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
);
83 fftw_die("fftw_malloc: out of memory\n");
85 /* store the size in a known position */
87 ((int *) p
)[1] = MAGIC
;
88 for (i
= 0; i
< PAD_FACTOR
* n
; ++i
)
89 p
[i
+ TWOINTS
] = (char) (i
^ 0xDEADBEEF);
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
)
107 q
= ((char *) p
) - TWOINTS
;
109 fftw_die("fftw_free: tried to free NULL+TWOINTS pointer!\n");
112 int n
= ((int *) q
)[0];
113 int magic
= ((int *) q
)[1];
117 printf("FFTW_FREE %d\n", n
);
121 *((int *) q
) = 0; /* set to zero to detect duplicate free's */
124 fftw_die("Wrong magic in fftw_free()!\n");
125 ((int *) q
)[1] = ~MAGIC
;
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)) {
139 fprintf(stderr
, "Byte %d past end of array has changed!\n",
141 fftw_die("Array bounds overwritten!\n");
143 for (i
= 0; i
< PAD_FACTOR
* n
; ++i
)
144 q
[i
+ TWOINTS
] = (char) (i
^ 0xBEEFDEAD);
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");
160 /**********************************************************
162 **********************************************************/
163 /* production version, no hacks */
165 void *fftw_malloc(size_t n
)
169 if (fftw_malloc_hook
)
170 return fftw_malloc_hook(n
);
178 fftw_die("fftw_malloc: out of memory\n");
183 void fftw_free(void *p
)
186 if (fftw_free_hook
) {
196 /* die when fatal errors occur */
197 void fftw_die(const char *s
)
203 fprintf(stderr
, "fftw: %s", s
);
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
;
213 if (fftw_malloc_cnt
|| fftw_malloc_total
||
214 fftw_node_cnt
|| fftw_plan_cnt
|| fftw_twiddle_size
) {
219 " node=%d plan=%d twiddle=%d\n"
220 "fftw_malloc_total = %d\n",
222 fftw_node_cnt
, fftw_plan_cnt
, fftw_twiddle_size
,
227 if (fftw_node_cnt
|| fftw_plan_cnt
|| fftw_twiddle_size
) {
231 " node=%d plan=%d twiddle=%d\n",
232 fftw_node_cnt
, fftw_plan_cnt
, fftw_twiddle_size
);
238 void fftw_print_max_memory_usage(void)
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);