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