1 /* stats.c - malloc statistics */
3 /* Copyright (C) 2001-2020 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne-Again SHell.
7 Bush 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.
12 Bush 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.
17 You should have received a copy of the GNU General Public License
18 along with Bush. If not, see <http://www.gnu.org/licenses/>.
37 extern int malloc_free_blocks
PARAMS((int));
39 extern int malloc_mmap_threshold
;
41 extern struct _malstats _mstats
;
43 extern FILE *_imalloc_fopen
PARAMS((char *, char *, char *, char *, size_t));
46 malloc_bucket_stats (size
)
49 struct bucket_stats v
;
53 if (size
< 0 || size
>= NBUCKETS
)
56 v
.nused
= v
.nmal
= v
.nmorecore
= v
.nlesscore
= v
.nsplit
= 0;
60 v
.blocksize
= 1 << (size
+ 3);
61 v
.nused
= _mstats
.nmalloc
[size
];
62 v
.nmal
= _mstats
.tmalloc
[size
];
63 v
.nmorecore
= _mstats
.nmorecore
[size
];
64 v
.nlesscore
= _mstats
.nlesscore
[size
];
65 v
.nsplit
= _mstats
.nsplit
[size
];
66 v
.ncoalesce
= _mstats
.ncoalesce
[size
];
68 v
.nfree
= malloc_free_blocks (size
); /* call back to malloc.c */
73 /* Return a copy of _MSTATS, with two additional fields filled in:
74 BYTESFREE is the total number of bytes on free lists. BYTESUSED
75 is the total number of bytes in use. These two fields are fairly
76 expensive to compute, so we do it only when asked to. */
80 struct _malstats result
;
81 struct bucket_stats v
;
85 result
.bytesused
= result
.bytesfree
= 0;
86 for (i
= 0; i
< NBUCKETS
; i
++)
88 v
= malloc_bucket_stats (i
);
89 result
.bytesfree
+= v
.nfree
* v
.blocksize
;
90 result
.bytesused
+= v
.nused
* v
.blocksize
;
96 _print_malloc_stats (s
, fp
)
101 unsigned long totused
, totfree
;
102 struct bucket_stats v
;
104 fprintf (fp
, "Memory allocation statistics: %s\n size\tfree\tin use\ttotal\tmorecore lesscore split\tcoalesce\n", s
? s
: "");
105 for (i
= totused
= totfree
= 0; i
< NBUCKETS
; i
++)
107 v
= malloc_bucket_stats (i
);
108 /* Show where the mmap threshold is; sizes greater than this use mmap to
109 allocate and munmap to free (munmap shows up as lesscore). */
110 if (i
== malloc_mmap_threshold
+1)
111 fprintf (fp
, "--------\n");
113 fprintf (fp
, "%8lu\t%4d\t%6d\t%5d%8d\t%8d %5d %8d\n", (unsigned long)v
.blocksize
, v
.nfree
, v
.nused
, v
.nmal
, v
.nmorecore
, v
.nlesscore
, v
.nsplit
, v
.ncoalesce
);
114 totfree
+= v
.nfree
* v
.blocksize
;
115 totused
+= v
.nused
* v
.blocksize
;
117 fprintf (fp
, "\nTotal bytes in use: %lu, total bytes free: %lu\n",
119 fprintf (fp
, "\nTotal bytes requested by application: %lu\n", (unsigned long)_mstats
.bytesreq
);
120 fprintf (fp
, "Total mallocs: %d, total frees: %d, total reallocs: %d (%d copies)\n",
121 _mstats
.nmal
, _mstats
.nfre
, _mstats
.nrealloc
, _mstats
.nrcopy
);
122 fprintf (fp
, "Total sbrks: %d, total bytes via sbrk: %d\n",
123 _mstats
.nsbrk
, _mstats
.tsbrk
);
124 fprintf (fp
, "Total mmaps: %d, total bytes via mmap: %d\n",
125 _mstats
.nmmap
, _mstats
.tmmap
);
126 fprintf (fp
, "Total blocks split: %d, total block coalesces: %d\n",
127 _mstats
.tbsplit
, _mstats
.tbcoalesce
);
131 print_malloc_stats (s
)
134 _print_malloc_stats (s
, stderr
);
138 fprint_malloc_stats (s
, fp
)
142 _print_malloc_stats (s
, fp
);
145 #define TRACEROOT "/var/tmp/maltrace/stats."
148 trace_malloc_stats (s
, fn
)
152 char defname
[sizeof (TRACEROOT
) + 64];
153 static char mallbuf
[1024];
155 fp
= _imalloc_fopen (s
, fn
, TRACEROOT
, defname
, sizeof (defname
));
158 setvbuf (fp
, mallbuf
, _IOFBF
, sizeof (mallbuf
));
159 _print_malloc_stats (s
, fp
);
165 #endif /* MALLOC_STATS */
167 #if defined (MALLOC_STATS) || defined (MALLOC_TRACE)
169 _imalloc_fopen (s
, fn
, def
, defbuf
, defsiz
)
183 sprintf (defbuf
, "%s%ld", def
, l
);
184 fp
= fopen(defbuf
, "w");
192 sprintf (pidbuf
, "%ld", l
);
193 if ((strlen (pidbuf
) + strlen (fn
) + 2) >= sizeof (fname
))
195 for (sp
= 0, p
= fname
, q
= fn
; *q
; )
197 if (sp
== 0 && *q
== '%' && q
[1] == 'p')
200 for (r
= pidbuf
; *r
; )
208 fp
= fopen (fname
, "w");
213 #endif /* MALLOC_STATS || MALLOC_TRACE */