| Bsoft 1.9 Bernard's software package

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

malloc.c
Go to the documentation of this file.
1 /*
2 * Copyright (c) 1997-1999, 2003 Massachusetts Institute of Technology
3 *
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.
8 *
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.
13 *
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
17 *
18 */
19
20 /*
21 * malloc.c -- memory allocation related functions
22 */
23
24 /* $Id: malloc.c,v 1.40 2003/03/16 23:43:46 stevenj Exp $ */
25 #include "fftw-int.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #ifdef HAVE_MALLOC_H
30 #include <malloc.h>
31 #endif
32
33 fftw_malloc_type_function fftw_malloc_hook = 0;
34 fftw_free_type_function fftw_free_hook = 0;
35 fftw_die_type_function fftw_die_hook = 0;
36
37 /**********************************************************
38 * DEBUGGING CODE
39 **********************************************************/
40 #ifdef FFTW_DEBUG
41 static int fftw_malloc_cnt = 0;
42
43 /*
44 * debugging malloc/free. Initialize every malloced and freed area to
45 * random values, just to make sure we are not using uninitialized
46 * pointers. Also check for writes past the ends of allocated blocks,
47 * and a couple of other things.
48 *
49 * This code is a quick and dirty hack -- use at your own risk.
50 */
51
52 static int fftw_malloc_total = 0, fftw_malloc_max = 0, fftw_malloc_cnt_max = 0;
53
54 #define MAGIC 0xABadCafe
55 #define PAD_FACTOR 2
56 #define TWOINTS (2 * sizeof(int))
57
58 #define VERBOSE_ALLOCATION 0
59
60 #if VERBOSE_ALLOCATION
61 #define WHEN_VERBOSE(a) a
62 #else
63 #define WHEN_VERBOSE(a)
64 #endif
65
66 void *fftw_malloc(size_t n)
67 {
68 char *p;
69 int i;
70
71 fftw_malloc_total += n;
72
73 if (fftw_malloc_total > fftw_malloc_max)
74 fftw_malloc_max = fftw_malloc_total;
75
76 p = (char *) malloc(PAD_FACTOR * n + TWOINTS);
77 if (!p)
78 fftw_die("fftw_malloc: out of memory\n");
79
80 /* store the size in a known position */
81 ((int *) p)[0] = n;
82 ((int *) p)[1] = MAGIC;
83 for (i = 0; i < PAD_FACTOR * n; ++i)
84 p[i + TWOINTS] = (char) (i ^ 0xDEADBEEF);
85
86 ++fftw_malloc_cnt;
87
88 if (fftw_malloc_cnt > fftw_malloc_cnt_max)
89 fftw_malloc_cnt_max = fftw_malloc_cnt;
90
91 /* skip the size we stored previously */
92 return (void *) (p + TWOINTS);
93 }
94
95 void fftw_free(void *p)
96 {
97 char *q;
98
99 if (!p)
100 return;
101
102 q = ((char *) p) - TWOINTS;
103 if (!q)
104 fftw_die("fftw_free: tried to free NULL+TWOINTS pointer!\n");
105
106 {
107 int n = ((int *) q)[0];
108 int magic = ((int *) q)[1];
109 int i;
110
111 WHEN_VERBOSE( {
112 printf("FFTW_FREE %d\n", n);
113 fflush(stdout);
114 })
115
116 *((int *) q) = 0; /* set to zero to detect duplicate free's */
117
118 if (magic != MAGIC)
119 fftw_die("Wrong magic in fftw_free()!\n");
120 ((int *) q)[1] = ~MAGIC;
121
122 if (n < 0)
123 fftw_die("Tried to free block with corrupt size descriptor!\n");
124
125 fftw_malloc_total -= n;
126
127 if (fftw_malloc_total < 0)
128 fftw_die("fftw_malloc_total went negative!\n");
129
130 /* check for writing past end of array: */
131 for (i = n; i < PAD_FACTOR * n; ++i)
132 if (q[i + TWOINTS] != (char) (i ^ 0xDEADBEEF)) {
133 fflush(stdout);
134 fprintf(stderr, "Byte %d past end of array has changed!\n",
135 i - n + 1);
136 fftw_die("Array bounds overwritten!\n");
137 }
138 for (i = 0; i < PAD_FACTOR * n; ++i)
139 q[i + TWOINTS] = (char) (i ^ 0xBEEFDEAD);
140
141 --fftw_malloc_cnt;
142
143 if (fftw_malloc_cnt < 0)
144 fftw_die("fftw_malloc_cnt went negative!\n");
145
146 if (fftw_malloc_cnt == 0 && fftw_malloc_total > 0 ||
147 fftw_malloc_cnt > 0 && fftw_malloc_total == 0)
148 fftw_die("fftw_malloc_cnt/total not zero at the same time!\n");
149
150 free(q);
151 }
152 }
153
154 #else
155 /**********************************************************
156 * NON DEBUGGING CODE
157 **********************************************************/
158 /* production version, no hacks */
159
160 void *fftw_malloc(size_t n)
161 {
162 void *p;
163
164 if (fftw_malloc_hook)
165 return fftw_malloc_hook(n);
166
167 if (n == 0)
168 n = 1;
169
170 p = malloc(n);
171
172 if (!p)
173 fftw_die("fftw_malloc: out of memory\n");
174
175 return p;
176 }
177
178 void fftw_free(void *p)
179 {
180 if (p) {
181 if (fftw_free_hook) {
182 fftw_free_hook(p);
183 return;
184 }
185 free(p);
186 }
187 }
188
189 #endif
190
191 /* die when fatal errors occur */
192 void fftw_die(const char *s)
193 {
194 if (fftw_die_hook)
195 fftw_die_hook(s);
196
197 fflush(stdout);
198 fprintf(stderr, "fftw: %s", s);
199 exit(EXIT_FAILURE);
200 }
201
202 /* check for memory leaks when debugging */
203 void fftw_check_memory_leaks(void)
204 {
205 extern int fftw_node_cnt, fftw_plan_cnt, fftw_twiddle_size;
206
207 #ifdef FFTW_DEBUG
208 if (fftw_malloc_cnt || fftw_malloc_total ||
209 fftw_node_cnt || fftw_plan_cnt || fftw_twiddle_size) {
210 fflush(stdout);
211 fprintf(stderr,
212 "MEMORY LEAK!!!\n"
213 "fftw_malloc = %d"
214 " node=%d plan=%d twiddle=%d\n"
215 "fftw_malloc_total = %d\n",
216 fftw_malloc_cnt,
217 fftw_node_cnt, fftw_plan_cnt, fftw_twiddle_size,
218 fftw_malloc_total);
219 exit(EXIT_FAILURE);
220 }
221 #else
222 if (fftw_node_cnt || fftw_plan_cnt || fftw_twiddle_size) {
223 fflush(stdout);
224 fprintf(stderr,
225 "MEMORY LEAK!!!\n"
226 " node=%d plan=%d twiddle=%d\n",
227 fftw_node_cnt, fftw_plan_cnt, fftw_twiddle_size);
228 exit(EXIT_FAILURE);
229 }
230 #endif
231 }
232
233 void fftw_print_max_memory_usage(void)
234 {
235 #ifdef FFTW_DEBUG
236 printf("\nMaximum number of blocks allocated = %d\n"
237 "Maximum number of bytes allocated = %0.3f kB\n",
238 fftw_malloc_cnt_max, fftw_malloc_max / 1024.0);
239 #endif
240 }
fftw_plan_cnt
int fftw_plan_cnt
Definition: putils.c:31
fftw-int.h
fftw_die_hook
fftw_die_type_function fftw_die_hook
Definition: malloc.c:35
fftw_die
void fftw_die(const char *s)
Definition: malloc.c:192
fftw_malloc
void * fftw_malloc(size_t n)
Definition: malloc.c:160
fftw_free_hook
fftw_free_type_function fftw_free_hook
Definition: malloc.c:34
fftw_malloc_type_function
void *(* fftw_malloc_type_function)(size_t n)
Definition: fftw.h:322
fftw_die_type_function
void(* fftw_die_type_function)(const char *errString)
Definition: fftw.h:324
fftw_twiddle_size
int fftw_twiddle_size
Definition: twiddle.c:140
fftw_check_memory_leaks
void fftw_check_memory_leaks(void)
Definition: malloc.c:203
fftw_free_type_function
void(* fftw_free_type_function)(void *p)
Definition: fftw.h:323
EXIT_FAILURE
#define EXIT_FAILURE
Definition: jerror.c:32
fftw_malloc_hook
fftw_malloc_type_function fftw_malloc_hook
Definition: malloc.c:33
fftw_node_cnt
int fftw_node_cnt
Definition: putils.c:30
fftw_free
void fftw_free(void *p)
Definition: malloc.c:178
fftw_print_max_memory_usage
void fftw_print_max_memory_usage(void)
Definition: malloc.c:233