5 #define MTHASH(v) ((((long) v) >> 8) & 0xffff)
6 #define MEMTSTSZ (1 << 18)
7 #define MTHASHSZ (1 << 16)
17 static struct memtst
*memtst
; /* memtst records */
18 static int memtst_n
; /* number of items in memtst[] */
19 static int memtst_sz
= MEMTSTSZ
;
20 static int *memtst_tail
; /* hash table list tails */
21 static int *memtst_prev
; /* hash table list previous items */
22 static int memtst_mcnt
, memtst_fcnt
; /* malloc() and free() count */
23 static long memtst_mmax
; /* maximum memory used */
24 static long memtst_mcur
; /* allocated memory */
25 static long memtst_mtot
; /* total memory allocated */
27 static int memtst_full(void)
29 return memtst_n
== memtst_sz
;
32 static char *memtst_show(long *bt
)
35 snprintf(s
, sizeof(s
), "%8p %8p %8p %8p %8p",
36 bt
[0], bt
[1], bt
[2], bt
[3], bt
[4]);
40 static void memtst_summary(void)
43 fprintf(stderr
, "memtst %d %d %ld", memtst_mcnt
, memtst_fcnt
, memtst_mtot
);
45 fprintf(stderr
, "\nmemtst: increase MEMTSTSZ\n");
48 fprintf(stderr
, " %ld\n", memtst_mmax
);
49 for (i
= 0; i
< memtst_n
; i
++) {
50 struct memtst
*mt
= &memtst
[i
];
52 fprintf(stderr
, "memtstleak %8p %8ld %s\n",
53 mt
->mem
, mt
->n
, memtst_show(mt
->bt
));
57 static void memtst_init(void)
59 memtst
= malloc(memtst_sz
* sizeof(memtst
[0]));
60 memtst_prev
= malloc(memtst_sz
* sizeof(memtst_prev
[0]));
61 memtst_tail
= malloc(MTHASHSZ
* sizeof(memtst_tail
[0]));
62 memset(memtst_tail
, 0xff, MTHASHSZ
* sizeof(memtst_tail
[0]));
63 atexit(memtst_summary
);
66 static void memtst_put(void *mem
, int n
, long *bt
)
73 mt
= &memtst
[memtst_n
];
76 memcpy(mt
->bt
, bt
, sizeof(mt
->bt
));
77 memtst_prev
[memtst_n
] = memtst_tail
[MTHASH(mem
)];
78 memtst_tail
[MTHASH(mem
)] = memtst_n
;
82 static struct memtst
*memtst_get(void *mem
)
87 idx
= memtst_tail
[MTHASH(mem
)];
89 struct memtst
*mt
= &memtst
[idx
];
90 if (!mt
->freed
&& mt
->mem
== mem
)
92 idx
= memtst_prev
[idx
];
97 long memtst_back(int n
);
99 static void memtst_bt(long *bt
)
101 bt
[0] = memtst_back(1);
102 bt
[1] = memtst_back(2);
103 bt
[2] = memtst_back(3);
104 bt
[3] = memtst_back(4);
105 bt
[4] = memtst_back(5);
108 void *memtst_malloc(long n
)
114 fprintf(stderr
, "memtstfail %8ld %s\n", n
, memtst_show(bt
));
116 memtst_put(v
, n
, bt
);
122 if (memtst_mcur
> memtst_mmax
)
123 memtst_mmax
= memtst_mcur
;
127 void memtst_free(void *v
)
134 if (!mt
&& !memtst_full()) {
137 fprintf(stderr
, "memtstfree %8p %s\n", v
, memtst_show(bt
));
141 memtst_mcur
-= mt
->n
;