]> git.saurik.com Git - apple/system_cmds.git/blame - zprint.tproj/zprint.c
system_cmds-496.tar.gz
[apple/system_cmds.git] / zprint.tproj / zprint.c
CommitLineData
1815bff5
A
1/*
2 * @OSF_COPYRIGHT@
3 */
4/*
5 * Mach Operating System
6 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
7 * All Rights Reserved.
8 *
9 * Permission to use, copy, modify and distribute this software and its
10 * documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29/*
30 * zprint.c
31 *
32 * utility for printing out zone structures
33 *
34 * With no arguments, prints information on all zone structures.
35 * With an argument, prints information only on those zones for
36 * which the given name is a substring of the zone's name.
37 * With a "-w" flag, calculates how much much space is allocated
38 * to zones but not currently in use.
39 */
40
41#include <stdio.h>
34d340d7 42#include <stdlib.h>
1815bff5
A
43#include <string.h>
44#include <mach/mach.h>
45#include <mach_debug/mach_debug.h>
46#include <mach/mach_error.h>
ef8ad44b
A
47#include <libutil.h>
48#include <errno.h>
1815bff5
A
49
50#define streql(a, b) (strcmp((a), (b)) == 0)
51#define strneql(a, b, n) (strncmp((a), (b), (n)) == 0)
52
53static void printzone();
54static void colprintzone();
55static void colprintzoneheader();
56static void printk();
57static int strnlen();
58static boolean_t substr();
59
60static char *program;
61
62static boolean_t ShowWasted = FALSE;
63static boolean_t SortZones = FALSE;
64static boolean_t ColFormat = TRUE;
65static boolean_t PrintHeader = TRUE;
66
67static unsigned int totalsize = 0;
68static unsigned int totalused = 0;
69
70static void
71usage()
72{
73 fprintf(stderr, "usage: %s [-w] [-s] [-c] [-h] [name]\n", program);
74 exit(1);
75}
76
34d340d7 77int
1815bff5
A
78main(argc, argv)
79 int argc;
80 char *argv[];
81{
82 zone_name_t name_buf[1024];
83 zone_name_t *name = name_buf;
84 unsigned int nameCnt = sizeof name_buf/sizeof name_buf[0];
85 zone_info_t info_buf[1024];
86 zone_info_t *info = info_buf;
87 unsigned int infoCnt = sizeof info_buf/sizeof info_buf[0];
88
89 char *zname = NULL;
34d340d7 90 int znamelen = 0;
1815bff5
A
91
92 kern_return_t kr;
93 int i, j;
94
ef8ad44b
A
95 if (0 != reexec_to_match_kernel()) {
96 fprintf(stderr, "Could not re-execute: %d\n", errno);
97 exit(1);
98 }
99
1815bff5
A
100 program = strrchr(argv[0], '/');
101 if (program == NULL)
102 program = argv[0];
103 else
104 program++;
105
106 for (i = 1; i < argc; i++) {
107 if (streql(argv[i], "-w"))
108 ShowWasted = TRUE;
109 else if (streql(argv[i], "-W"))
110 ShowWasted = FALSE;
111 else if (streql(argv[i], "-s"))
112 SortZones = TRUE;
113 else if (streql(argv[i], "-S"))
114 SortZones = FALSE;
115 else if (streql(argv[i], "-c"))
116 ColFormat = TRUE;
117 else if (streql(argv[i], "-C"))
118 ColFormat = FALSE;
119 else if (streql(argv[i], "-H"))
120 PrintHeader = FALSE;
121 else if (streql(argv[i], "--")) {
122 i++;
123 break;
124 } else if (argv[i][0] == '-')
125 usage();
126 else
127 break;
128 }
129
130 switch (argc - i) {
131 case 0:
132 zname = "";
133 znamelen = 0;
134 break;
135
136 case 1:
137 zname = argv[i];
138 znamelen = strlen(zname);
139 break;
140
141 default:
142 usage();
143 }
144
145 kr = host_zone_info(mach_host_self(),
146 &name, &nameCnt, &info, &infoCnt);
147 if (kr != KERN_SUCCESS) {
148 fprintf(stderr, "%s: host_zone_info: %s\n",
149 program, mach_error_string(kr));
150 exit(1);
151 }
152 else if (nameCnt != infoCnt) {
153 fprintf(stderr, "%s: host_zone_info: counts not equal?\n",
154 program);
155 exit(1);
156 }
157
158 if (SortZones) {
159 for (i = 0; i < nameCnt-1; i++)
160 for (j = i+1; j < nameCnt; j++) {
161 int wastei, wastej;
162
163 wastei = (info[i].zi_cur_size -
164 (info[i].zi_elem_size *
165 info[i].zi_count));
166 wastej = (info[j].zi_cur_size -
167 (info[j].zi_elem_size *
168 info[j].zi_count));
169
170 if (wastej > wastei) {
171 zone_info_t tinfo;
172 zone_name_t tname;
173
174 tinfo = info[i];
175 info[i] = info[j];
176 info[j] = tinfo;
177
178 tname = name[i];
179 name[i] = name[j];
180 name[j] = tname;
181 }
182 }
183 }
184
185 if (ColFormat) {
186 colprintzoneheader();
187 }
188 for (i = 0; i < nameCnt; i++)
189 if (substr(zname, znamelen, name[i].zn_name,
190 strnlen(name[i].zn_name, sizeof name[i].zn_name)))
191 if (ColFormat)
192 colprintzone(&name[i], &info[i]);
193 else
194 printzone(&name[i], &info[i]);
195
196 if ((name != name_buf) && (nameCnt != 0)) {
197 kr = vm_deallocate(mach_task_self(), (vm_address_t) name,
198 (vm_size_t) (nameCnt * sizeof *name));
199 if (kr != KERN_SUCCESS) {
200 fprintf(stderr, "%s: vm_deallocate: %s\n",
201 program, mach_error_string(kr));
202 exit(1);
203 }
204 }
205
206 if ((info != info_buf) && (infoCnt != 0)) {
207 kr = vm_deallocate(mach_task_self(), (vm_address_t) info,
208 (vm_size_t) (infoCnt * sizeof *info));
209 if (kr != KERN_SUCCESS) {
210 fprintf(stderr, "%s: vm_deallocate: %s\n",
211 program, mach_error_string(kr));
212 exit(1);
213 }
214 }
215
216 if (ShowWasted && PrintHeader) {
217 printf("TOTAL SIZE = %u\n", totalsize);
218 printf("TOTAL USED = %u\n", totalused);
219 printf("TOTAL WASTED = %d\n", totalsize - totalused);
220 }
221
222 exit(0);
223}
224
225static int
226strnlen(s, n)
227 char *s;
228 int n;
229{
230 int len = 0;
231
232 while ((len < n) && (*s++ != '\0'))
233 len++;
234
235 return len;
236}
237
238static boolean_t
239substr(a, alen, b, blen)
240 char *a;
241 int alen;
242 char *b;
243 int blen;
244{
245 int i;
246
247 for (i = 0; i <= blen - alen; i++)
248 if (strneql(a, b+i, alen))
249 return TRUE;
250
251 return FALSE;
252}
253
254static void
255printzone(name, info)
256 zone_name_t *name;
257 zone_info_t *info;
258{
259 unsigned int used, size;
260
34d340d7 261 printf("%.*s zone:\n", (int)sizeof name->zn_name, name->zn_name);
1815bff5
A
262 printf("\tcur_size: %dK bytes (%d elements)\n",
263 info->zi_cur_size/1024,
264 info->zi_cur_size/info->zi_elem_size);
265 printf("\tmax_size: %dK bytes (%d elements)\n",
266 info->zi_max_size/1024,
267 info->zi_max_size/info->zi_elem_size);
268 printf("\telem_size: %d bytes\n",
269 info->zi_elem_size);
270 printf("\t# of elems: %d\n",
271 info->zi_count);
272 printf("\talloc_size: %dK bytes (%d elements)\n",
273 info->zi_alloc_size/1024,
274 info->zi_alloc_size/info->zi_elem_size);
275 if (info->zi_pageable)
276 printf("\tPAGEABLE\n");
277 if (info->zi_collectable)
278 printf("\tCOLLECTABLE\n");
279
280 if (ShowWasted) {
281 totalused += used = info->zi_elem_size * info->zi_count;
282 totalsize += size = info->zi_cur_size;
283 printf("\t\t\t\t\tWASTED: %d\n", size - used);
284 }
285}
286
287static void
288printk(fmt, i)
289 char *fmt;
290 int i;
291{
292 printf(fmt, i / 1024);
293 putchar('K');
294}
295
296static void
297colprintzone(zone_name, info)
298 zone_name_t *zone_name;
299 zone_info_t *info;
300{
301 char *name = zone_name->zn_name;
34d340d7 302 int j, namewidth;
1815bff5
A
303 unsigned int used, size;
304
305 namewidth = 25;
306 if (ShowWasted) {
307 namewidth -= 7;
308 }
309 for (j = 0; j < namewidth - 1 && name[j]; j++) {
310 if (name[j] == ' ') {
311 putchar('.');
312 } else {
313 putchar(name[j]);
314 }
315 }
316 if (j == namewidth - 1) {
317 if (name[j]) {
318 putchar('$');
319 } else {
320 putchar(' ');
321 }
322 } else {
323 for (; j < namewidth; j++) {
324 putchar(' ');
325 }
326 }
327 printf("%5d", info->zi_elem_size);
328 printk("%6d", info->zi_cur_size);
329 if (info->zi_max_size >= 99999 * 1024) {
330 printf(" ----");
331 } else {
332 printk("%6d", info->zi_max_size);
333 }
334 printf("%7d", info->zi_cur_size / info->zi_elem_size);
335 if (info->zi_max_size >= 99999 * 1024) {
336 printf(" ----");
337 } else {
338 printf("%7d", info->zi_max_size / info->zi_elem_size);
339 }
340 printf("%6d", info->zi_count);
341 printk("%5d", info->zi_alloc_size);
342 printf("%6d", info->zi_alloc_size / info->zi_elem_size);
343
344 totalused += used = info->zi_elem_size * info->zi_count;
345 totalsize += size = info->zi_cur_size;
346 if (ShowWasted) {
347 printf("%7d", size - used);
348 }
349
350 printf("%c%c\n",
351 (info->zi_pageable ? 'P' : ' '),
352 (info->zi_collectable ? 'C' : ' '));
353}
354
355static void
356colprintzoneheader()
357{
358 if (! PrintHeader) {
359 return;
360 }
361 if (ShowWasted) {
362 printf(" elem cur max cur max%s",
363 " cur alloc alloc\n");
364 printf("zone name size size size #elts #elts%s",
365 " inuse size count wasted\n");
366 } else {
367 printf(" elem cur max cur%s",
368 " max cur alloc alloc\n");
369 printf("zone name size size size #elts%s",
370 " #elts inuse size count\n");
371 }
372 printf("-----------------------------------------------%s",
373 "--------------------------------\n");
374}