rf_debugMem.c revision 1.1 1 1.1 oster /* $NetBSD: rf_debugMem.c,v 1.1 1998/11/13 04:20:28 oster Exp $ */
2 1.1 oster /*
3 1.1 oster * Copyright (c) 1995 Carnegie-Mellon University.
4 1.1 oster * All rights reserved.
5 1.1 oster *
6 1.1 oster * Author: Daniel Stodolsky, Mark Holland, Jim Zelenka
7 1.1 oster *
8 1.1 oster * Permission to use, copy, modify and distribute this software and
9 1.1 oster * its documentation is hereby granted, provided that both the copyright
10 1.1 oster * notice and this permission notice appear in all copies of the
11 1.1 oster * software, derivative works or modified versions, and any portions
12 1.1 oster * thereof, and that both notices appear in supporting documentation.
13 1.1 oster *
14 1.1 oster * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 1.1 oster * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16 1.1 oster * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 1.1 oster *
18 1.1 oster * Carnegie Mellon requests users of this software to return to
19 1.1 oster *
20 1.1 oster * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 1.1 oster * School of Computer Science
22 1.1 oster * Carnegie Mellon University
23 1.1 oster * Pittsburgh PA 15213-3890
24 1.1 oster *
25 1.1 oster * any improvements or extensions that they make and grant Carnegie the
26 1.1 oster * rights to redistribute these changes.
27 1.1 oster */
28 1.1 oster
29 1.1 oster /* debugMem.c: memory usage debugging stuff.
30 1.1 oster * Malloc, Calloc, and Free are #defined everywhere
31 1.1 oster * to do_malloc, do_calloc, and do_free.
32 1.1 oster *
33 1.1 oster * if RF_UTILITY is nonzero, it means were compiling one of the
34 1.1 oster * raidframe utility programs, such as rfctrl or smd. In this
35 1.1 oster * case, we eliminate all references to the threads package
36 1.1 oster * and to the allocation list stuff.
37 1.1 oster */
38 1.1 oster
39 1.1 oster /* :
40 1.1 oster * Log: rf_debugMem.c,v
41 1.1 oster * Revision 1.38 1996/08/20 14:45:43 jimz
42 1.1 oster * add debugging to track memory allocated (amount only, w/out
43 1.1 oster * excessive sanity checking)
44 1.1 oster *
45 1.1 oster * Revision 1.37 1996/07/27 23:36:08 jimz
46 1.1 oster * Solaris port of simulator
47 1.1 oster *
48 1.1 oster * Revision 1.36 1996/07/18 22:57:14 jimz
49 1.1 oster * port simulator to AIX
50 1.1 oster *
51 1.1 oster * Revision 1.35 1996/06/13 08:55:38 jimz
52 1.1 oster * make error messages refer to file, line of original
53 1.1 oster * allocation
54 1.1 oster *
55 1.1 oster * Revision 1.34 1996/06/10 11:55:47 jimz
56 1.1 oster * Straightened out some per-array/not-per-array distinctions, fixed
57 1.1 oster * a couple bugs related to confusion. Added shutdown lists. Removed
58 1.1 oster * layout shutdown function (now subsumed by shutdown lists).
59 1.1 oster *
60 1.1 oster * Revision 1.33 1996/06/09 02:36:46 jimz
61 1.1 oster * lots of little crufty cleanup- fixup whitespace
62 1.1 oster * issues, comment #ifdefs, improve typing in some
63 1.1 oster * places (esp size-related)
64 1.1 oster *
65 1.1 oster * Revision 1.32 1996/06/05 18:06:02 jimz
66 1.1 oster * Major code cleanup. The Great Renaming is now done.
67 1.1 oster * Better modularity. Better typing. Fixed a bunch of
68 1.1 oster * synchronization bugs. Made a lot of global stuff
69 1.1 oster * per-desc or per-array. Removed dead code.
70 1.1 oster *
71 1.1 oster * Revision 1.31 1996/05/30 23:22:16 jimz
72 1.1 oster * bugfixes of serialization, timing problems
73 1.1 oster * more cleanup
74 1.1 oster *
75 1.1 oster * Revision 1.30 1996/05/30 11:29:41 jimz
76 1.1 oster * Numerous bug fixes. Stripe lock release code disagreed with the taking code
77 1.1 oster * about when stripes should be locked (I made it consistent: no parity, no lock)
78 1.1 oster * There was a lot of extra serialization of I/Os which I've removed- a lot of
79 1.1 oster * it was to calculate values for the cache code, which is no longer with us.
80 1.1 oster * More types, function, macro cleanup. Added code to properly quiesce the array
81 1.1 oster * on shutdown. Made a lot of stuff array-specific which was (bogusly) general
82 1.1 oster * before. Fixed memory allocation, freeing bugs.
83 1.1 oster *
84 1.1 oster * Revision 1.29 1996/05/27 18:56:37 jimz
85 1.1 oster * more code cleanup
86 1.1 oster * better typing
87 1.1 oster * compiles in all 3 environments
88 1.1 oster *
89 1.1 oster * Revision 1.28 1996/05/23 21:46:35 jimz
90 1.1 oster * checkpoint in code cleanup (release prep)
91 1.1 oster * lots of types, function names have been fixed
92 1.1 oster *
93 1.1 oster * Revision 1.27 1996/05/23 00:33:23 jimz
94 1.1 oster * code cleanup: move all debug decls to rf_options.c, all extern
95 1.1 oster * debug decls to rf_options.h, all debug vars preceded by rf_
96 1.1 oster *
97 1.1 oster * Revision 1.26 1996/05/21 18:53:46 jimz
98 1.1 oster * return NULL for failed allocations, not panic
99 1.1 oster *
100 1.1 oster * Revision 1.25 1996/05/20 16:14:19 jimz
101 1.1 oster * switch to rf_{mutex,cond}_{init,destroy}
102 1.1 oster *
103 1.1 oster * Revision 1.24 1996/05/18 19:51:34 jimz
104 1.1 oster * major code cleanup- fix syntax, make some types consistent,
105 1.1 oster * add prototypes, clean out dead code, et cetera
106 1.1 oster *
107 1.1 oster * Revision 1.23 1996/05/17 12:42:35 jimz
108 1.1 oster * wrap get_threadid stuff in #ifndef UTILITY for utils which use
109 1.1 oster * redzone allocation stuff
110 1.1 oster *
111 1.1 oster * Revision 1.22 1996/05/16 23:06:09 jimz
112 1.1 oster * don't warn about NULL alists
113 1.1 oster *
114 1.1 oster * Revision 1.21 1996/05/16 22:25:02 jimz
115 1.1 oster * show allocations for [MC]allocAndAdd
116 1.1 oster *
117 1.1 oster * Revision 1.20 1996/05/15 18:30:22 jimz
118 1.1 oster * print memory allocation as well as frees if memDebug > 1
119 1.1 oster *
120 1.1 oster * Revision 1.19 1996/05/07 17:41:17 jimz
121 1.1 oster * add "level 2" for memDebug, which will print freed address ranges
122 1.1 oster *
123 1.1 oster * Revision 1.18 1996/05/02 20:41:53 jimz
124 1.1 oster * really fix malloc problem out-of-kernel in memory_hash_insert()
125 1.1 oster *
126 1.1 oster * Revision 1.17 1996/05/02 20:04:29 jimz
127 1.1 oster * fixed malloc deadlock previous change introduced
128 1.1 oster *
129 1.1 oster * Revision 1.16 1996/05/01 16:27:26 jimz
130 1.1 oster * get rid of ALLOCMH
131 1.1 oster * stop using ccmn_ memory management
132 1.1 oster *
133 1.1 oster * Revision 1.15 1995/12/12 18:10:06 jimz
134 1.1 oster * MIN -> RF_MIN, MAX -> RF_MAX, ASSERT -> RF_ASSERT
135 1.1 oster * fix 80-column brain damage in comments
136 1.1 oster *
137 1.1 oster * Revision 1.14 1995/12/01 15:56:17 root
138 1.1 oster * added copyright info
139 1.1 oster *
140 1.1 oster */
141 1.1 oster
142 1.1 oster #include "rf_types.h"
143 1.1 oster #include "rf_sys.h"
144 1.1 oster
145 1.1 oster #if RF_UTILITY == 0
146 1.1 oster #include "rf_threadstuff.h"
147 1.1 oster #include "rf_threadid.h"
148 1.1 oster #include "rf_options.h"
149 1.1 oster #else /* RF_UTILITY == 0 */
150 1.1 oster #include "rf_utility.h"
151 1.1 oster #endif /* RF_UTILITY == 0 */
152 1.1 oster
153 1.1 oster #ifndef KERNEL
154 1.1 oster #include <stdio.h>
155 1.1 oster #include <assert.h>
156 1.1 oster #endif /* !KERNEL */
157 1.1 oster #include "rf_debugMem.h"
158 1.1 oster #include "rf_general.h"
159 1.1 oster
160 1.1 oster static long tot_mem_in_use = 0, max_mem = 0;
161 1.1 oster
162 1.1 oster /* Hash table of information about memory allocations */
163 1.1 oster #define RF_MH_TABLESIZE 1000
164 1.1 oster
165 1.1 oster struct mh_struct {
166 1.1 oster void *address;
167 1.1 oster int size;
168 1.1 oster int line;
169 1.1 oster char *filen;
170 1.1 oster char allocated;
171 1.1 oster struct mh_struct *next;
172 1.1 oster };
173 1.1 oster static struct mh_struct *mh_table[RF_MH_TABLESIZE];
174 1.1 oster RF_DECLARE_MUTEX(rf_debug_mem_mutex)
175 1.1 oster static int mh_table_initialized=0;
176 1.1 oster
177 1.1 oster static void memory_hash_insert(void *addr, int size, int line, char *filen);
178 1.1 oster static int memory_hash_remove(void *addr, int sz);
179 1.1 oster
180 1.1 oster #ifndef KERNEL /* no redzones or "real_" routines in the kernel */
181 1.1 oster
182 1.1 oster static void rf_redzone_free_failed(void *ptr, int size, int line, char *file);
183 1.1 oster
184 1.1 oster void *rf_real_redzone_malloc(_size_)
185 1.1 oster int _size_;
186 1.1 oster {
187 1.1 oster char *p;
188 1.1 oster
189 1.1 oster rf_validate_mh_table();
190 1.1 oster p = malloc((_size_)+16);
191 1.1 oster if (p == NULL)
192 1.1 oster return(p);
193 1.1 oster RF_ASSERT (p);
194 1.1 oster *((long *) p) = (_size_) ;
195 1.1 oster ((char *) p)[(_size_)+8] = '!';
196 1.1 oster ((char *) p)[(_size_)+15] = '!';
197 1.1 oster p += 8;
198 1.1 oster return(p);
199 1.1 oster }
200 1.1 oster
201 1.1 oster void *rf_real_redzone_calloc(_n_,_size_)
202 1.1 oster int _n_,_size_;
203 1.1 oster {
204 1.1 oster char *p;
205 1.1 oster int _sz_;
206 1.1 oster
207 1.1 oster rf_validate_mh_table();
208 1.1 oster _sz_ = (_n_) * (_size_);
209 1.1 oster p = malloc((_sz_)+16);
210 1.1 oster if (p == NULL)
211 1.1 oster return(p);
212 1.1 oster bzero(p,(_sz_)+16);
213 1.1 oster *((long *) p) = (_sz_) ;
214 1.1 oster ((char *) p)[(_sz_)+8] = '!';
215 1.1 oster ((char *) p)[(_sz_)+15] = '!';
216 1.1 oster p += 8;
217 1.1 oster return(p);
218 1.1 oster }
219 1.1 oster
220 1.1 oster void rf_real_redzone_free(p, line, filen)
221 1.1 oster char *p;
222 1.1 oster int line;
223 1.1 oster char *filen;
224 1.1 oster {
225 1.1 oster unsigned long _size_;
226 1.1 oster
227 1.1 oster rf_validate_mh_table();
228 1.1 oster p -= 8;
229 1.1 oster _size_ = *((long *) p);
230 1.1 oster if ((((char *) p)[(_size_)+8] != '!') || (((char *) p)[(_size_)+15] != '!'))
231 1.1 oster rf_redzone_free_failed(p,(_size_),line,filen);
232 1.1 oster free(p);
233 1.1 oster }
234 1.1 oster
235 1.1 oster unsigned long rf_mem_alloc = 0;
236 1.1 oster
237 1.1 oster char *rf_real_Malloc(size, line, file)
238 1.1 oster int size;
239 1.1 oster int line;
240 1.1 oster char *file;
241 1.1 oster {
242 1.1 oster void *pp;
243 1.1 oster char *p;
244 1.1 oster int tid;
245 1.1 oster
246 1.1 oster RF_LOCK_MUTEX(rf_debug_mem_mutex);
247 1.1 oster rf_redzone_malloc(pp, size);
248 1.1 oster p = pp;
249 1.1 oster if (p == NULL) {
250 1.1 oster RF_ERRORMSG3("Unable to malloc %d bytes at line %d file %s\n", size,
251 1.1 oster line, file);
252 1.1 oster }
253 1.1 oster if (rf_memAmtDebug) {
254 1.1 oster rf_mem_alloc += size;
255 1.1 oster printf("%lu size %d %s:%d\n", rf_mem_alloc, size, file, line);
256 1.1 oster }
257 1.1 oster #if RF_UTILITY == 0
258 1.1 oster if (rf_memDebug > 1) {
259 1.1 oster rf_get_threadid(tid);
260 1.1 oster printf("[%d] malloc 0x%lx - 0x%lx (%d) %s %d\n", tid, p, p+size, size,
261 1.1 oster file, line);
262 1.1 oster }
263 1.1 oster #endif /* RF_UTILITY == 0 */
264 1.1 oster if (rf_memDebug)
265 1.1 oster rf_record_malloc(p, size, line, file);
266 1.1 oster RF_UNLOCK_MUTEX(rf_debug_mem_mutex);
267 1.1 oster return(p);
268 1.1 oster }
269 1.1 oster
270 1.1 oster #if RF_UTILITY == 0
271 1.1 oster char *rf_real_MallocAndAdd(size, alist, line, file)
272 1.1 oster int size;
273 1.1 oster RF_AllocListElem_t *alist;
274 1.1 oster int line;
275 1.1 oster char *file;
276 1.1 oster {
277 1.1 oster void *pp;
278 1.1 oster char *p;
279 1.1 oster int tid;
280 1.1 oster
281 1.1 oster RF_LOCK_MUTEX(rf_debug_mem_mutex);
282 1.1 oster rf_redzone_malloc(pp, size);
283 1.1 oster p = pp;
284 1.1 oster if (p == NULL) {
285 1.1 oster RF_ERRORMSG3("Unable to malloc %d bytes at line %d file %s\n", size,
286 1.1 oster line, file);
287 1.1 oster }
288 1.1 oster if (rf_memAmtDebug) {
289 1.1 oster rf_mem_alloc += size;
290 1.1 oster printf("%lu size %d %s:%d\n", rf_mem_alloc, size, file, line);
291 1.1 oster }
292 1.1 oster if (rf_memDebug > 1) {
293 1.1 oster rf_get_threadid(tid);
294 1.1 oster printf("[%d] malloc+add 0x%lx - 0x%lx (%d) %s %d\n", tid, p, p+size,
295 1.1 oster size, file, line);
296 1.1 oster }
297 1.1 oster if (alist) {
298 1.1 oster rf_real_AddToAllocList(alist, pp, size, 0);
299 1.1 oster }
300 1.1 oster if (rf_memDebug)
301 1.1 oster rf_record_malloc(p, size, line, file);
302 1.1 oster RF_UNLOCK_MUTEX(rf_debug_mem_mutex);
303 1.1 oster return(p);
304 1.1 oster }
305 1.1 oster #endif /* RF_UTILITY == 0 */
306 1.1 oster
307 1.1 oster char *rf_real_Calloc(nel, elsz, line, file)
308 1.1 oster int nel;
309 1.1 oster int elsz;
310 1.1 oster int line;
311 1.1 oster char *file;
312 1.1 oster {
313 1.1 oster int tid, size;
314 1.1 oster void *pp;
315 1.1 oster char *p;
316 1.1 oster
317 1.1 oster size = nel * elsz;
318 1.1 oster RF_LOCK_MUTEX(rf_debug_mem_mutex);
319 1.1 oster rf_redzone_calloc(pp, nel, elsz);
320 1.1 oster p = pp;
321 1.1 oster if (p == NULL) {
322 1.1 oster RF_ERRORMSG4("Unable to calloc %d objects of size %d at line %d file %s\n",
323 1.1 oster nel, elsz, line, file);
324 1.1 oster return(NULL);
325 1.1 oster }
326 1.1 oster if (rf_memAmtDebug) {
327 1.1 oster rf_mem_alloc += size;
328 1.1 oster printf("%lu size %d %s:%d\n", rf_mem_alloc, size, file, line);
329 1.1 oster }
330 1.1 oster #if RF_UTILITY == 0
331 1.1 oster if (rf_memDebug > 1) {
332 1.1 oster rf_get_threadid(tid);
333 1.1 oster printf("[%d] calloc 0x%lx - 0x%lx (%d,%d) %s %d\n", tid, p, p+size, nel,
334 1.1 oster elsz, file, line);
335 1.1 oster }
336 1.1 oster #endif /* RF_UTILITY == 0 */
337 1.1 oster if (rf_memDebug) {
338 1.1 oster rf_record_malloc(p, size, line, file);
339 1.1 oster }
340 1.1 oster RF_UNLOCK_MUTEX(rf_debug_mem_mutex);
341 1.1 oster return(p);
342 1.1 oster }
343 1.1 oster
344 1.1 oster #if RF_UTILITY == 0
345 1.1 oster char *rf_real_CallocAndAdd(nel, elsz, alist, line, file)
346 1.1 oster int nel;
347 1.1 oster int elsz;
348 1.1 oster RF_AllocListElem_t *alist;
349 1.1 oster int line;
350 1.1 oster char *file;
351 1.1 oster {
352 1.1 oster int tid, size;
353 1.1 oster void *pp;
354 1.1 oster char *p;
355 1.1 oster
356 1.1 oster size = nel * elsz;
357 1.1 oster RF_LOCK_MUTEX(rf_debug_mem_mutex);
358 1.1 oster rf_redzone_calloc(pp, nel, elsz);
359 1.1 oster p = pp;
360 1.1 oster if (p == NULL) {
361 1.1 oster RF_ERRORMSG4("Unable to calloc %d objs of size %d at line %d file %s\n",
362 1.1 oster nel, elsz, line, file);
363 1.1 oster return(NULL);
364 1.1 oster }
365 1.1 oster if (rf_memAmtDebug) {
366 1.1 oster rf_mem_alloc += size;
367 1.1 oster printf("%lu size %d %s:%d\n", rf_mem_alloc, size, file, line);
368 1.1 oster }
369 1.1 oster if (rf_memDebug > 1) {
370 1.1 oster rf_get_threadid(tid);
371 1.1 oster printf("[%d] calloc+add 0x%lx - 0x%lx (%d,%d) %s %d\n", tid, p,
372 1.1 oster p+size, nel, elsz, file, line);
373 1.1 oster }
374 1.1 oster if (alist) {
375 1.1 oster rf_real_AddToAllocList(alist, pp, size, 0);
376 1.1 oster }
377 1.1 oster if (rf_memDebug)
378 1.1 oster rf_record_malloc(p, size, line, file);
379 1.1 oster RF_UNLOCK_MUTEX(rf_debug_mem_mutex);
380 1.1 oster return(p);
381 1.1 oster }
382 1.1 oster #endif /* RF_UTILITY == 0 */
383 1.1 oster
384 1.1 oster void rf_real_Free(p, sz, line, file)
385 1.1 oster void *p;
386 1.1 oster int sz;
387 1.1 oster int line;
388 1.1 oster char *file;
389 1.1 oster {
390 1.1 oster int tid;
391 1.1 oster
392 1.1 oster #if RF_UTILITY == 0
393 1.1 oster if (rf_memDebug > 1) {
394 1.1 oster rf_get_threadid(tid);
395 1.1 oster printf("[%d] free 0x%lx - 0x%lx (%d) %s %d\n", tid, p, ((char *)p)+sz, sz,
396 1.1 oster file, line);
397 1.1 oster }
398 1.1 oster #endif /* RF_UTILITY == 0 */
399 1.1 oster RF_LOCK_MUTEX(rf_debug_mem_mutex);
400 1.1 oster if (rf_memAmtDebug) {
401 1.1 oster rf_mem_alloc -= sz;
402 1.1 oster printf("%lu - size %d %s:%d\n", rf_mem_alloc, sz, file, line);
403 1.1 oster }
404 1.1 oster if (rf_memDebug) {
405 1.1 oster rf_unrecord_malloc(p,sz);
406 1.1 oster }
407 1.1 oster rf_redzone_free(p);
408 1.1 oster RF_UNLOCK_MUTEX(rf_debug_mem_mutex);
409 1.1 oster }
410 1.1 oster
411 1.1 oster void rf_validate_mh_table()
412 1.1 oster {
413 1.1 oster int i, size;
414 1.1 oster struct mh_struct *p;
415 1.1 oster char *cp;
416 1.1 oster
417 1.1 oster return;
418 1.1 oster for (i=0; i<RF_MH_TABLESIZE; i++) {
419 1.1 oster for (p=mh_table[i]; p; p=p->next) if (p->allocated) {
420 1.1 oster cp = ((char *) p->address) - 8;
421 1.1 oster size = *((long *) cp);
422 1.1 oster if ((((char *) cp)[(size)+8] != '!') || (((char *) cp)[(size)+15] != '!')) {
423 1.1 oster rf_redzone_free_failed(cp,(size),__LINE__,__FILE__);
424 1.1 oster }
425 1.1 oster }
426 1.1 oster }
427 1.1 oster }
428 1.1 oster
429 1.1 oster static void rf_redzone_free_failed(ptr,size,line,file)
430 1.1 oster void *ptr;
431 1.1 oster int size;
432 1.1 oster int line;
433 1.1 oster char *file;
434 1.1 oster {
435 1.1 oster RF_ERRORMSG4("Free of 0x%lx (recorded size %d) at %d of %s detected redzone overrun\n",ptr,size,line,file);
436 1.1 oster RF_ASSERT(0);
437 1.1 oster }
438 1.1 oster
439 1.1 oster #endif /* !KERNEL */
440 1.1 oster
441 1.1 oster void rf_record_malloc(p, size, line, filen)
442 1.1 oster void *p;
443 1.1 oster int size, line;
444 1.1 oster char *filen;
445 1.1 oster {
446 1.1 oster RF_ASSERT(size != 0);
447 1.1 oster
448 1.1 oster /*RF_LOCK_MUTEX(rf_debug_mem_mutex);*/
449 1.1 oster memory_hash_insert(p, size, line, filen);
450 1.1 oster tot_mem_in_use += size;
451 1.1 oster /*RF_UNLOCK_MUTEX(rf_debug_mem_mutex);*/
452 1.1 oster if ( (long) p == rf_memDebugAddress) {
453 1.1 oster printf("Allocate: debug address allocated from line %d file %s\n",line,filen);
454 1.1 oster }
455 1.1 oster }
456 1.1 oster
457 1.1 oster void rf_unrecord_malloc(p, sz)
458 1.1 oster void *p;
459 1.1 oster int sz;
460 1.1 oster {
461 1.1 oster int size;
462 1.1 oster
463 1.1 oster /*RF_LOCK_MUTEX(rf_debug_mem_mutex);*/
464 1.1 oster size = memory_hash_remove(p, sz);
465 1.1 oster tot_mem_in_use -= size;
466 1.1 oster /*RF_UNLOCK_MUTEX(rf_debug_mem_mutex);*/
467 1.1 oster if ( (long) p == rf_memDebugAddress) {
468 1.1 oster printf("Free: Found debug address\n"); /* this is really only a flag line for gdb */
469 1.1 oster }
470 1.1 oster }
471 1.1 oster
472 1.1 oster void rf_print_unfreed()
473 1.1 oster {
474 1.1 oster int i, foundone=0;
475 1.1 oster struct mh_struct *p;
476 1.1 oster
477 1.1 oster for (i=0; i<RF_MH_TABLESIZE; i++) {
478 1.1 oster for (p=mh_table[i]; p; p=p->next) if (p->allocated) {
479 1.1 oster if (!foundone) printf("\n\nThere are unfreed memory locations at program shutdown:\n");
480 1.1 oster foundone = 1;
481 1.1 oster printf("Addr 0x%lx Size %d line %d file %s\n",
482 1.1 oster (long)p->address,p->size,p->line,p->filen);
483 1.1 oster }
484 1.1 oster }
485 1.1 oster if (tot_mem_in_use) {
486 1.1 oster printf("%ld total bytes in use\n", tot_mem_in_use);
487 1.1 oster }
488 1.1 oster }
489 1.1 oster
490 1.1 oster int rf_ConfigureDebugMem(listp)
491 1.1 oster RF_ShutdownList_t **listp;
492 1.1 oster {
493 1.1 oster int i, rc;
494 1.1 oster
495 1.1 oster rc = rf_create_managed_mutex(listp, &rf_debug_mem_mutex);
496 1.1 oster if (rc) {
497 1.1 oster RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n", __FILE__,
498 1.1 oster __LINE__, rc);
499 1.1 oster return(rc);
500 1.1 oster }
501 1.1 oster if (rf_memDebug) {
502 1.1 oster for (i=0; i<RF_MH_TABLESIZE; i++)
503 1.1 oster mh_table[i] = NULL;
504 1.1 oster mh_table_initialized=1;
505 1.1 oster }
506 1.1 oster return(0);
507 1.1 oster }
508 1.1 oster
509 1.1 oster #define HASHADDR(_a_) ( (((unsigned long) _a_)>>3) % RF_MH_TABLESIZE )
510 1.1 oster
511 1.1 oster static void memory_hash_insert(addr, size, line, filen)
512 1.1 oster void *addr;
513 1.1 oster int size, line;
514 1.1 oster char *filen;
515 1.1 oster {
516 1.1 oster unsigned long bucket = HASHADDR(addr);
517 1.1 oster struct mh_struct *p;
518 1.1 oster
519 1.1 oster RF_ASSERT(mh_table_initialized);
520 1.1 oster
521 1.1 oster /* search for this address in the hash table */
522 1.1 oster for (p=mh_table[bucket]; p && (p->address != addr); p=p->next);
523 1.1 oster if (!p) {
524 1.1 oster #ifdef KERNEL
525 1.1 oster RF_Malloc(p,sizeof(struct mh_struct),(struct mh_struct *));
526 1.1 oster #else /* KERNEL */
527 1.1 oster p = (struct mh_struct *)malloc(sizeof(struct mh_struct));
528 1.1 oster #endif /* KERNEL */
529 1.1 oster RF_ASSERT(p);
530 1.1 oster p->next = mh_table[bucket];
531 1.1 oster mh_table[bucket] = p;
532 1.1 oster p->address = addr;
533 1.1 oster p->allocated = 0;
534 1.1 oster }
535 1.1 oster if (p->allocated) {
536 1.1 oster printf("ERROR: reallocated address 0x%lx from line %d, file %s without intervening free\n",(long) addr, line, filen);
537 1.1 oster printf(" last allocated from line %d file %s\n",p->line, p->filen);
538 1.1 oster RF_ASSERT(0);
539 1.1 oster }
540 1.1 oster p->size = size; p->line = line; p->filen = filen;
541 1.1 oster p->allocated = 1;
542 1.1 oster }
543 1.1 oster
544 1.1 oster static int memory_hash_remove(addr, sz)
545 1.1 oster void *addr;
546 1.1 oster int sz;
547 1.1 oster {
548 1.1 oster unsigned long bucket = HASHADDR(addr);
549 1.1 oster struct mh_struct *p;
550 1.1 oster
551 1.1 oster RF_ASSERT(mh_table_initialized);
552 1.1 oster for (p=mh_table[bucket]; p && (p->address != addr); p=p->next);
553 1.1 oster if (!p) {
554 1.1 oster printf("ERROR: freeing never-allocated address 0x%lx\n",(long) addr);
555 1.1 oster RF_PANIC();
556 1.1 oster }
557 1.1 oster if (!p->allocated) {
558 1.1 oster printf("ERROR: freeing unallocated address 0x%lx. Last allocation line %d file %s\n",(long) addr, p->line, p->filen);
559 1.1 oster RF_PANIC();
560 1.1 oster }
561 1.1 oster if (sz > 0 && p->size != sz) { /* you can suppress this error by using a negative value as the size to free */
562 1.1 oster printf("ERROR: incorrect size at free for address 0x%lx: is %d should be %d. Alloc at line %d of file %s\n",(unsigned long) addr, sz, p->size,p->line, p->filen);
563 1.1 oster RF_PANIC();
564 1.1 oster }
565 1.1 oster p->allocated = 0;
566 1.1 oster return(p->size);
567 1.1 oster }
568 1.1 oster
569 1.1 oster void rf_ReportMaxMem()
570 1.1 oster {
571 1.1 oster printf("Max memory used: %d bytes\n",(int)max_mem);
572 1.1 oster #ifndef KERNEL
573 1.1 oster fflush(stdout);
574 1.1 oster fprintf(stderr,"Max memory used: %d bytes\n",max_mem);
575 1.1 oster fflush(stderr);
576 1.1 oster #endif /* !KERNEL */
577 1.1 oster }
578