BSD 4_4_Lite2 development
[unix-history] / usr / src / contrib / mprof / leak.c
CommitLineData
b0bdc297
C
1/* leak.c 2.1 7/8/88 14:15:57 */
2/* Copyright (c) 1987, Benjamin G. Zorn */
3
4#include <stdio.h>
5#include "mprof.h"
6
7int mprof_smemC;
8mpcell lt_hmem[MP_HASH_SIZE];
9
10mpsstk mp_new_sstk();
11int lt_hash();
12void lt_puthash();
13mpsstk lt_lookup();
14void mp_print_leak();
15
16extern bool keeping_leaks;
17
18bool keeping_leaks = TRUE;
19
20mpsstk
21mp_new_sstk(nbytes, scallstack)
22int nbytes;
23unsigned scallstack[SHORT_CALLSTACK_SIZE];
24{
25 mpsstk newsstk = (mpsstk) malloc(MPSSTK_SIZE);
26 int i;
27
28 mprof_smemC++;
29 sstk_allocs(newsstk) = 1;
30 sstk_bytes_alloced(newsstk) = nbytes;
31 sstk_frees(newsstk) = 0;
32 sstk_bytes_freed(newsstk) = 0;
33 for (i = 0; i < SHORT_CALLSTACK_SIZE; i++) {
34 sstk_addrs(newsstk)[i] = scallstack[i];
35 }
36 return (newsstk);
37}
38
39
40int
41lt_hash(addrs)
42unsigned addrs[SHORT_CALLSTACK_SIZE];
43{
44 unsigned tmp = 0, i;
45 int hash;
46
47 for (i = 0; i < SHORT_CALLSTACK_SIZE; i++) {
48 tmp = tmp ^ addrs[i];
49 }
50 hash = (tmp >> 24 | (tmp & 0xff00)) ^
51 (((tmp & 0xff) << 8) | (tmp & 0xff0000) >> 16);
52 return (hash % MP_HASH_SIZE);
53}
54
55void
56lt_puthash(s)
57mpsstk s;
58{
59 int hash = lt_hash(sstk_addrs(s));
60
61 lt_hmem[hash] = mp_cons((int) s, lt_hmem[hash]);
62}
63
64mpsstk
65lt_lookup(addrs)
66unsigned addrs[SHORT_CALLSTACK_SIZE];
67{
68 int hash = lt_hash(addrs);
69 mpcell c = lt_hmem[hash];
70 mpsstk s;
71 int i;
72 unsigned *haddrs;
73
74 while (!mp_null(c)) {
75 s = (mpsstk) mp_car(c);
76 haddrs = sstk_addrs(s);
77 for (i = 0; i < SHORT_CALLSTACK_SIZE; i++) {
78 if (addrs[i] != haddrs[i]) {
79 break;
80 } else if (i == SHORT_CALLSTACK_SIZE - 1) {
81 return s;
82 }
83 }
84 c = (mpcell) mp_cdr(c);
85 }
86 return (mpsstk) MP_NIL;
87}
88
89mpsstk
90mp_add_leak_table(sstk, nbytes)
91unsigned sstk[SHORT_CALLSTACK_SIZE];
92int nbytes;
93{
94 mpsstk s;
95
96 if (!keeping_leaks) return NULL;
97
98 s = lt_lookup(sstk);
99 if (s != (mpsstk) MP_NIL) {
100 sstk_allocs(s)++;
101 sstk_bytes_alloced(s) += nbytes;
102 } else {
103 s = mp_new_sstk(nbytes, sstk);
104 lt_puthash(s);
105 }
106 return s;
107}
108
109void
110mp_remove_leak_table(leakdata, nbytes)
111mpsstk leakdata;
112int nbytes;
113{
114
115 if (!keeping_leaks) return;
116
117 if (leakdata != (mpsstk) MP_NIL) {
118 sstk_frees(leakdata)++;
119 sstk_bytes_freed(leakdata) += nbytes;
120 } else {
121 fprintf(stderr,
122 "mp_remove_leak_table -- free of unallocated object\n");
123 exit(1);
124 }
125}
126
127void
128mp_print_leak_table(file)
129int file;
130{
131 mpsstk s;
132 int i;
133 mpcell chain;
134 int abytes = 0, fbytes = 0;
135 char outbuf[256];
136
137/* sprintf(outbuf, "%10s %10s %10s %10s %-10s\n",
138 "allocs", "bytes", "frees", "bytes", "path");
139 write(file, outbuf, strlen(outbuf));
140*/
141
142 for (i = 0; i < MP_HASH_SIZE; i++) {
143 chain = lt_hmem[i];
144 while (!mp_null(chain)) {
145 s = (mpsstk) mp_car(chain);
146
147 if (((sstk_allocs(s) != sstk_frees(s)) ||
148 (sstk_bytes_alloced(s) != sstk_bytes_freed(s)))) {
149 mp_print_leak(file, s);
150 }
151 abytes += sstk_bytes_alloced(s);
152 fbytes += sstk_bytes_freed(s);
153
154 chain = (mpcell) mp_cdr(chain);
155 }
156 }
157
158/*
159 printf(" a: %d f: %d\n", abytes, fbytes);
160*/
161 write(file, "-2 -1 -1 -1\n", 12);
162}
163
164void
165mp_print_leak(file, s)
166int file;
167mpsstk s;
168{
169 char outbuf[256];
170 int i;
171
172 sprintf(outbuf, "%d %d %d %d\n",
173 sstk_allocs(s), sstk_bytes_alloced(s),
174 sstk_frees(s), sstk_bytes_freed(s));
175 write(file, outbuf, strlen(outbuf));
176 /*
177 */
178
179 for (i = 0; i < SHORT_CALLSTACK_SIZE; i++) {
180 sprintf(outbuf, "%d\n", sstk_addrs(s)[i]);
181 write(file, outbuf, strlen(outbuf));
182 /*
183 */
184 }
185}
186
187
188void
189mpleak_init()
190{
191 int i;
192
193 for (i = 0; i < MP_HASH_SIZE; i++) {
194 lt_hmem[i] = (mpcell) MP_NIL;
195 }
196 mprof_smemC = 0;
197}