]> git.saurik.com Git - apple/system_cmds.git/blob - zprint.tproj/zprint.c
system_cmds-433.8.tar.gz
[apple/system_cmds.git] / zprint.tproj / zprint.c
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>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <mach/mach.h>
45 #include <mach_debug/mach_debug.h>
46 #include <mach/mach_error.h>
47
48 #define streql(a, b) (strcmp((a), (b)) == 0)
49 #define strneql(a, b, n) (strncmp((a), (b), (n)) == 0)
50
51 static void printzone();
52 static void colprintzone();
53 static void colprintzoneheader();
54 static void printk();
55 static int strnlen();
56 static boolean_t substr();
57
58 static char *program;
59
60 static boolean_t ShowWasted = FALSE;
61 static boolean_t SortZones = FALSE;
62 static boolean_t ColFormat = TRUE;
63 static boolean_t PrintHeader = TRUE;
64
65 static unsigned int totalsize = 0;
66 static unsigned int totalused = 0;
67
68 static void
69 usage()
70 {
71 fprintf(stderr, "usage: %s [-w] [-s] [-c] [-h] [name]\n", program);
72 exit(1);
73 }
74
75 int
76 main(argc, argv)
77 int argc;
78 char *argv[];
79 {
80 zone_name_t name_buf[1024];
81 zone_name_t *name = name_buf;
82 unsigned int nameCnt = sizeof name_buf/sizeof name_buf[0];
83 zone_info_t info_buf[1024];
84 zone_info_t *info = info_buf;
85 unsigned int infoCnt = sizeof info_buf/sizeof info_buf[0];
86
87 char *zname = NULL;
88 int znamelen = 0;
89
90 kern_return_t kr;
91 int i, j;
92
93 program = strrchr(argv[0], '/');
94 if (program == NULL)
95 program = argv[0];
96 else
97 program++;
98
99 for (i = 1; i < argc; i++) {
100 if (streql(argv[i], "-w"))
101 ShowWasted = TRUE;
102 else if (streql(argv[i], "-W"))
103 ShowWasted = FALSE;
104 else if (streql(argv[i], "-s"))
105 SortZones = TRUE;
106 else if (streql(argv[i], "-S"))
107 SortZones = FALSE;
108 else if (streql(argv[i], "-c"))
109 ColFormat = TRUE;
110 else if (streql(argv[i], "-C"))
111 ColFormat = FALSE;
112 else if (streql(argv[i], "-H"))
113 PrintHeader = FALSE;
114 else if (streql(argv[i], "--")) {
115 i++;
116 break;
117 } else if (argv[i][0] == '-')
118 usage();
119 else
120 break;
121 }
122
123 switch (argc - i) {
124 case 0:
125 zname = "";
126 znamelen = 0;
127 break;
128
129 case 1:
130 zname = argv[i];
131 znamelen = strlen(zname);
132 break;
133
134 default:
135 usage();
136 }
137
138 kr = host_zone_info(mach_host_self(),
139 &name, &nameCnt, &info, &infoCnt);
140 if (kr != KERN_SUCCESS) {
141 fprintf(stderr, "%s: host_zone_info: %s\n",
142 program, mach_error_string(kr));
143 exit(1);
144 }
145 else if (nameCnt != infoCnt) {
146 fprintf(stderr, "%s: host_zone_info: counts not equal?\n",
147 program);
148 exit(1);
149 }
150
151 if (SortZones) {
152 for (i = 0; i < nameCnt-1; i++)
153 for (j = i+1; j < nameCnt; j++) {
154 int wastei, wastej;
155
156 wastei = (info[i].zi_cur_size -
157 (info[i].zi_elem_size *
158 info[i].zi_count));
159 wastej = (info[j].zi_cur_size -
160 (info[j].zi_elem_size *
161 info[j].zi_count));
162
163 if (wastej > wastei) {
164 zone_info_t tinfo;
165 zone_name_t tname;
166
167 tinfo = info[i];
168 info[i] = info[j];
169 info[j] = tinfo;
170
171 tname = name[i];
172 name[i] = name[j];
173 name[j] = tname;
174 }
175 }
176 }
177
178 if (ColFormat) {
179 colprintzoneheader();
180 }
181 for (i = 0; i < nameCnt; i++)
182 if (substr(zname, znamelen, name[i].zn_name,
183 strnlen(name[i].zn_name, sizeof name[i].zn_name)))
184 if (ColFormat)
185 colprintzone(&name[i], &info[i]);
186 else
187 printzone(&name[i], &info[i]);
188
189 if ((name != name_buf) && (nameCnt != 0)) {
190 kr = vm_deallocate(mach_task_self(), (vm_address_t) name,
191 (vm_size_t) (nameCnt * sizeof *name));
192 if (kr != KERN_SUCCESS) {
193 fprintf(stderr, "%s: vm_deallocate: %s\n",
194 program, mach_error_string(kr));
195 exit(1);
196 }
197 }
198
199 if ((info != info_buf) && (infoCnt != 0)) {
200 kr = vm_deallocate(mach_task_self(), (vm_address_t) info,
201 (vm_size_t) (infoCnt * sizeof *info));
202 if (kr != KERN_SUCCESS) {
203 fprintf(stderr, "%s: vm_deallocate: %s\n",
204 program, mach_error_string(kr));
205 exit(1);
206 }
207 }
208
209 if (ShowWasted && PrintHeader) {
210 printf("TOTAL SIZE = %u\n", totalsize);
211 printf("TOTAL USED = %u\n", totalused);
212 printf("TOTAL WASTED = %d\n", totalsize - totalused);
213 }
214
215 exit(0);
216 }
217
218 static int
219 strnlen(s, n)
220 char *s;
221 int n;
222 {
223 int len = 0;
224
225 while ((len < n) && (*s++ != '\0'))
226 len++;
227
228 return len;
229 }
230
231 static boolean_t
232 substr(a, alen, b, blen)
233 char *a;
234 int alen;
235 char *b;
236 int blen;
237 {
238 int i;
239
240 for (i = 0; i <= blen - alen; i++)
241 if (strneql(a, b+i, alen))
242 return TRUE;
243
244 return FALSE;
245 }
246
247 static void
248 printzone(name, info)
249 zone_name_t *name;
250 zone_info_t *info;
251 {
252 unsigned int used, size;
253
254 printf("%.*s zone:\n", (int)sizeof name->zn_name, name->zn_name);
255 printf("\tcur_size: %dK bytes (%d elements)\n",
256 info->zi_cur_size/1024,
257 info->zi_cur_size/info->zi_elem_size);
258 printf("\tmax_size: %dK bytes (%d elements)\n",
259 info->zi_max_size/1024,
260 info->zi_max_size/info->zi_elem_size);
261 printf("\telem_size: %d bytes\n",
262 info->zi_elem_size);
263 printf("\t# of elems: %d\n",
264 info->zi_count);
265 printf("\talloc_size: %dK bytes (%d elements)\n",
266 info->zi_alloc_size/1024,
267 info->zi_alloc_size/info->zi_elem_size);
268 if (info->zi_pageable)
269 printf("\tPAGEABLE\n");
270 if (info->zi_collectable)
271 printf("\tCOLLECTABLE\n");
272
273 if (ShowWasted) {
274 totalused += used = info->zi_elem_size * info->zi_count;
275 totalsize += size = info->zi_cur_size;
276 printf("\t\t\t\t\tWASTED: %d\n", size - used);
277 }
278 }
279
280 static void
281 printk(fmt, i)
282 char *fmt;
283 int i;
284 {
285 printf(fmt, i / 1024);
286 putchar('K');
287 }
288
289 static void
290 colprintzone(zone_name, info)
291 zone_name_t *zone_name;
292 zone_info_t *info;
293 {
294 char *name = zone_name->zn_name;
295 int j, namewidth;
296 unsigned int used, size;
297
298 namewidth = 25;
299 if (ShowWasted) {
300 namewidth -= 7;
301 }
302 for (j = 0; j < namewidth - 1 && name[j]; j++) {
303 if (name[j] == ' ') {
304 putchar('.');
305 } else {
306 putchar(name[j]);
307 }
308 }
309 if (j == namewidth - 1) {
310 if (name[j]) {
311 putchar('$');
312 } else {
313 putchar(' ');
314 }
315 } else {
316 for (; j < namewidth; j++) {
317 putchar(' ');
318 }
319 }
320 printf("%5d", info->zi_elem_size);
321 printk("%6d", info->zi_cur_size);
322 if (info->zi_max_size >= 99999 * 1024) {
323 printf(" ----");
324 } else {
325 printk("%6d", info->zi_max_size);
326 }
327 printf("%7d", info->zi_cur_size / info->zi_elem_size);
328 if (info->zi_max_size >= 99999 * 1024) {
329 printf(" ----");
330 } else {
331 printf("%7d", info->zi_max_size / info->zi_elem_size);
332 }
333 printf("%6d", info->zi_count);
334 printk("%5d", info->zi_alloc_size);
335 printf("%6d", info->zi_alloc_size / info->zi_elem_size);
336
337 totalused += used = info->zi_elem_size * info->zi_count;
338 totalsize += size = info->zi_cur_size;
339 if (ShowWasted) {
340 printf("%7d", size - used);
341 }
342
343 printf("%c%c\n",
344 (info->zi_pageable ? 'P' : ' '),
345 (info->zi_collectable ? 'C' : ' '));
346 }
347
348 static void
349 colprintzoneheader()
350 {
351 if (! PrintHeader) {
352 return;
353 }
354 if (ShowWasted) {
355 printf(" elem cur max cur max%s",
356 " cur alloc alloc\n");
357 printf("zone name size size size #elts #elts%s",
358 " inuse size count wasted\n");
359 } else {
360 printf(" elem cur max cur%s",
361 " max cur alloc alloc\n");
362 printf("zone name size size size #elts%s",
363 " #elts inuse size count\n");
364 }
365 printf("-----------------------------------------------%s",
366 "--------------------------------\n");
367 }