]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/malloc/stats.c
Bash-4.3 distribution sources and documentation
[thirdparty/bash.git] / lib / malloc / stats.c
CommitLineData
f73dda09
JA
1/* stats.c - malloc statistics */
2
b80f6443 3/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
f73dda09 4
3185942a 5 This file is part of GNU Bash, the Bourne-Again SHell.
f73dda09 6
3185942a
JA
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
f73dda09 11
3185942a
JA
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
f73dda09
JA
20
21#ifdef HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#include "imalloc.h"
26
27#ifdef MALLOC_STATS
28
29#include <stdio.h>
7117c2d2
JA
30#ifdef HAVE_UNISTD_H
31# include <unistd.h>
32#endif
0628567a 33#include <string.h>
7117c2d2 34
f73dda09
JA
35#include "mstats.h"
36
7117c2d2
JA
37extern int malloc_free_blocks __P((int));
38
39extern struct _malstats _mstats;
f73dda09 40
b80f6443
JA
41extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
42
f73dda09
JA
43struct bucket_stats
44malloc_bucket_stats (size)
45 int size;
46{
47 struct bucket_stats v;
48
49 v.nfree = 0;
50
51 if (size < 0 || size >= NBUCKETS)
52 {
53 v.blocksize = 0;
7117c2d2 54 v.nused = v.nmal = v.nmorecore = v.nlesscore = v.nsplit = 0;
f73dda09
JA
55 return v;
56 }
57
58 v.blocksize = 1 << (size + 3);
59 v.nused = _mstats.nmalloc[size];
60 v.nmal = _mstats.tmalloc[size];
61 v.nmorecore = _mstats.nmorecore[size];
7117c2d2 62 v.nlesscore = _mstats.nlesscore[size];
f73dda09 63 v.nsplit = _mstats.nsplit[size];
7117c2d2 64 v.ncoalesce = _mstats.ncoalesce[size];
f73dda09
JA
65
66 v.nfree = malloc_free_blocks (size); /* call back to malloc.c */
67
68 return v;
69}
70
71/* Return a copy of _MSTATS, with two additional fields filled in:
72 BYTESFREE is the total number of bytes on free lists. BYTESUSED
73 is the total number of bytes in use. These two fields are fairly
74 expensive to compute, so we do it only when asked to. */
75struct _malstats
76malloc_stats ()
77{
78 struct _malstats result;
79 struct bucket_stats v;
80 register int i;
81
82 result = _mstats;
83 result.bytesused = result.bytesfree = 0;
84 for (i = 0; i < NBUCKETS; i++)
85 {
86 v = malloc_bucket_stats (i);
87 result.bytesfree += v.nfree * v.blocksize;
88 result.bytesused += v.nused * v.blocksize;
89 }
90 return (result);
91}
92
93static void
94_print_malloc_stats (s, fp)
95 char *s;
96 FILE *fp;
97{
98 register int i;
99 unsigned long totused, totfree;
100 struct bucket_stats v;
101
7117c2d2 102 fprintf (fp, "Memory allocation statistics: %s\n size\tfree\tin use\ttotal\tmorecore lesscore split\tcoalesce\n", s ? s : "");
f73dda09
JA
103 for (i = totused = totfree = 0; i < NBUCKETS; i++)
104 {
105 v = malloc_bucket_stats (i);
7117c2d2
JA
106 if (v.nmal > 0)
107 fprintf (fp, "%8lu\t%4d\t%6d\t%5d\t%8d\t%d %5d %8d\n", (unsigned long)v.blocksize, v.nfree, v.nused, v.nmal, v.nmorecore, v.nlesscore, v.nsplit, v.ncoalesce);
f73dda09
JA
108 totfree += v.nfree * v.blocksize;
109 totused += v.nused * v.blocksize;
110 }
111 fprintf (fp, "\nTotal bytes in use: %lu, total bytes free: %lu\n",
112 totused, totfree);
7117c2d2 113 fprintf (fp, "\nTotal bytes requested by application: %lu\n", _mstats.bytesreq);
f73dda09
JA
114 fprintf (fp, "Total mallocs: %d, total frees: %d, total reallocs: %d (%d copies)\n",
115 _mstats.nmal, _mstats.nfre, _mstats.nrealloc, _mstats.nrcopy);
116 fprintf (fp, "Total sbrks: %d, total bytes via sbrk: %d\n",
117 _mstats.nsbrk, _mstats.tsbrk);
118 fprintf (fp, "Total blocks split: %d, total block coalesces: %d\n",
119 _mstats.tbsplit, _mstats.tbcoalesce);
120}
121
122void
123print_malloc_stats (s)
124 char *s;
125{
126 _print_malloc_stats (s, stderr);
127}
128
129void
130fprint_malloc_stats (s, fp)
131 char *s;
132 FILE *fp;
133{
134 _print_malloc_stats (s, fp);
135}
136
b80f6443 137#define TRACEROOT "/var/tmp/maltrace/stats."
f73dda09
JA
138
139void
7117c2d2
JA
140trace_malloc_stats (s, fn)
141 char *s, *fn;
f73dda09 142{
b80f6443 143 FILE *fp;
7117c2d2 144 char defname[sizeof (TRACEROOT) + 64];
b80f6443
JA
145 static char mallbuf[1024];
146
147 fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname));
148 if (fp)
149 {
150 setvbuf (fp, mallbuf, _IOFBF, sizeof (mallbuf));
151 _print_malloc_stats (s, fp);
152 fflush(fp);
153 fclose(fp);
154 }
155}
156
157#endif /* MALLOC_STATS */
158
159#if defined (MALLOC_STATS) || defined (MALLOC_TRACE)
160FILE *
161_imalloc_fopen (s, fn, def, defbuf, defsiz)
162 char *s;
163 char *fn;
164 char *def;
165 char *defbuf;
166 size_t defsiz;
167{
7117c2d2
JA
168 char fname[1024];
169 long l;
f73dda09
JA
170 FILE *fp;
171
7117c2d2
JA
172 l = (long)getpid ();
173 if (fn == 0)
174 {
b80f6443
JA
175 sprintf (defbuf, "%s%ld", def, l);
176 fp = fopen(defbuf, "w");
7117c2d2
JA
177 }
178 else
179 {
180 char *p, *q, *r;
181 char pidbuf[32];
182 int sp;
183
184 sprintf (pidbuf, "%ld", l);
185 if ((strlen (pidbuf) + strlen (fn) + 2) >= sizeof (fname))
3185942a 186 return ((FILE *)0);
7117c2d2
JA
187 for (sp = 0, p = fname, q = fn; *q; )
188 {
189 if (sp == 0 && *q == '%' && q[1] == 'p')
190 {
191 sp = 1;
192 for (r = pidbuf; *r; )
193 *p++ = *r++;
194 q += 2;
195 }
196 else
197 *p++ = *q++;
198 }
199 *p = '\0';
200 fp = fopen (fname, "w");
201 }
f73dda09 202
b80f6443
JA
203 return fp;
204}
205#endif /* MALLOC_STATS || MALLOC_TRACE */