comparison src/fftw-3.3.3/kernel/alloc.c @ 10:37bf6b4a2645

Add FFTW3
author Chris Cannam
date Wed, 20 Mar 2013 15:35:50 +0000
parents
children
comparison
equal deleted inserted replaced
9:c0fb53affa76 10:37bf6b4a2645
1 /*
2 * Copyright (c) 2003, 2007-11 Matteo Frigo
3 * Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21 #include "ifftw.h"
22
23 /**********************************************************
24 * DEBUGGING CODE
25 **********************************************************/
26 #if defined(FFTW_DEBUG_MALLOC)
27
28 #include <stdio.h>
29
30 /*
31 debugging malloc/free.
32
33 1) Initialize every malloced and freed area to random values, just
34 to make sure we are not using uninitialized pointers.
35
36 2) check for blocks freed twice.
37
38 3) Check for writes past the ends of allocated blocks
39
40 4) destroy contents of freed blocks in order to detect incorrect reuse.
41
42 5) keep track of who allocates what and report memory leaks
43
44 This code is a quick and dirty hack. May be nonportable.
45 Use at your own risk.
46
47 */
48
49 #define MAGIC ((size_t)0xABadCafe)
50 #define PAD_FACTOR 2
51 #define SZ_HEADER (4 * sizeof(size_t))
52 #define HASHSZ 1031
53
54 static unsigned int hashaddr(void *p)
55 {
56 return ((unsigned long)p) % HASHSZ;
57 }
58
59 struct mstat {
60 int siz;
61 int maxsiz;
62 int cnt;
63 int maxcnt;
64 };
65
66 static struct mstat mstat[MALLOC_WHAT_LAST];
67
68 struct minfo {
69 const char *file;
70 int line;
71 size_t n;
72 void *p;
73 struct minfo *next;
74 };
75
76 static struct minfo *minfo[HASHSZ] = {0};
77
78 #if defined(HAVE_THREADS) || defined(HAVE_OPENMP)
79 int X(in_thread) = 0;
80 #endif
81
82 void *X(malloc_debug)(size_t n, enum malloc_tag what,
83 const char *file, int line)
84 {
85 char *p;
86 size_t i;
87 struct minfo *info;
88 struct mstat *stat = mstat + what;
89 struct mstat *estat = mstat + EVERYTHING;
90
91 if (n == 0)
92 n = 1;
93
94 if (!IN_THREAD) {
95 stat->siz += n;
96 if (stat->siz > stat->maxsiz)
97 stat->maxsiz = stat->siz;
98 estat->siz += n;
99 if (estat->siz > estat->maxsiz)
100 estat->maxsiz = estat->siz;
101 }
102
103 p = (char *) X(kernel_malloc)(PAD_FACTOR * n + SZ_HEADER);
104 A(p);
105
106 /* store the sz in a known position */
107 ((size_t *) p)[0] = n;
108 ((size_t *) p)[1] = MAGIC;
109 ((size_t *) p)[2] = what;
110
111 /* fill with junk */
112 for (i = 0; i < PAD_FACTOR * n; i++)
113 p[i + SZ_HEADER] = (char) (i ^ 0xEF);
114
115 if (!IN_THREAD) {
116 ++stat->cnt;
117 ++estat->cnt;
118
119 if (stat->cnt > stat->maxcnt)
120 stat->maxcnt = stat->cnt;
121 if (estat->cnt > estat->maxcnt)
122 estat->maxcnt = estat->cnt;
123 }
124
125 /* skip the info we stored previously */
126 p = p + SZ_HEADER;
127
128 if (!IN_THREAD) {
129 unsigned int h = hashaddr(p);
130 /* record allocation in allocation list */
131 info = (struct minfo *) malloc(sizeof(struct minfo));
132 info->n = n;
133 info->file = file;
134 info->line = line;
135 info->p = p;
136 info->next = minfo[h];
137 minfo[h] = info;
138 }
139
140 return (void *) p;
141 }
142
143 void X(ifree)(void *p)
144 {
145 char *q;
146
147 A(p);
148
149 q = ((char *) p) - SZ_HEADER;
150 A(q);
151
152 {
153 size_t n = ((size_t *) q)[0];
154 size_t magic = ((size_t *) q)[1];
155 int what = ((size_t *) q)[2];
156 size_t i;
157 struct mstat *stat = mstat + what;
158 struct mstat *estat = mstat + EVERYTHING;
159
160 /* set to zero to detect duplicate free's */
161 ((size_t *) q)[0] = 0;
162
163 A(magic == MAGIC);
164 ((size_t *) q)[1] = ~MAGIC;
165
166 if (!IN_THREAD) {
167 stat->siz -= n;
168 A(stat->siz >= 0);
169 estat->siz -= n;
170 A(estat->siz >= 0);
171 }
172
173 /* check for writing past end of array: */
174 for (i = n; i < PAD_FACTOR * n; ++i)
175 if (q[i + SZ_HEADER] != (char) (i ^ 0xEF)) {
176 A(0 /* array bounds overwritten */ );
177 }
178 for (i = 0; i < PAD_FACTOR * n; ++i)
179 q[i + SZ_HEADER] = (char) (i ^ 0xAD);
180
181 if (!IN_THREAD) {
182 --stat->cnt;
183 --estat->cnt;
184
185 A(stat->cnt >= 0);
186 A((stat->cnt == 0 && stat->siz == 0) ||
187 (stat->cnt > 0 && stat->siz > 0));
188 A(estat->cnt >= 0);
189 A((estat->cnt == 0 && estat->siz == 0) ||
190 (estat->cnt > 0 && estat->siz > 0));
191 }
192
193 X(kernel_free)(q);
194 }
195
196 if (!IN_THREAD) {
197 /* delete minfo entry */
198 unsigned int h = hashaddr(p);
199 struct minfo **i;
200
201 for (i = minfo + h; *i; i = &((*i)->next)) {
202 if ((*i)->p == p) {
203 struct minfo *i0 = (*i)->next;
204 free(*i);
205 *i = i0;
206 return;
207 }
208 }
209
210 A(0 /* no entry in minfo list */ );
211 }
212 }
213
214 void X(malloc_print_minfo)(int verbose)
215 {
216 struct minfo *info;
217 int what;
218 unsigned int h;
219 int leak = 0;
220
221 if (verbose > 2) {
222 static const char *names[MALLOC_WHAT_LAST] = {
223 "EVERYTHING",
224 "PLANS", "SOLVERS", "PROBLEMS", "BUFFERS",
225 "HASHT", "TENSORS", "PLANNERS", "SLVDSC", "TWIDDLES",
226 "STRIDES", "OTHER"
227 };
228
229 printf("%12s %8s %8s %10s %10s\n",
230 "what", "cnt", "maxcnt", "siz", "maxsiz");
231
232 for (what = 0; what < MALLOC_WHAT_LAST; ++what) {
233 struct mstat *stat = mstat + what;
234 printf("%12s %8d %8d %10d %10d\n",
235 names[what], stat->cnt, stat->maxcnt,
236 stat->siz, stat->maxsiz);
237 }
238 }
239
240 for (h = 0; h < HASHSZ; ++h)
241 if (minfo[h]) {
242 printf("\nUnfreed allocations:\n");
243 break;
244 }
245
246 for (h = 0; h < HASHSZ; ++h)
247 for (info = minfo[h]; info; info = info->next) {
248 leak = 1;
249 printf("%s:%d: %zd bytes at %p\n",
250 info->file, info->line, info->n, info->p);
251 }
252
253 if (leak)
254 abort();
255 }
256
257 #else
258 /**********************************************************
259 * NON DEBUGGING CODE
260 **********************************************************/
261 /* production version, no hacks */
262
263 void *X(malloc_plain)(size_t n)
264 {
265 void *p;
266 if (n == 0)
267 n = 1;
268 p = X(kernel_malloc)(n);
269 CK(p);
270
271 #ifdef MIN_ALIGNMENT
272 A((((uintptr_t)p) % MIN_ALIGNMENT) == 0);
273 #endif
274
275 return p;
276 }
277
278 void X(ifree)(void *p)
279 {
280 X(kernel_free)(p);
281 }
282
283 #endif
284
285 void X(ifree0)(void *p)
286 {
287 /* common pattern */
288 if (p) X(ifree)(p);
289 }