]> git.saurik.com Git - apple/system_cmds.git/blame - vm_stat.tproj/vm_stat.c
system_cmds-880.100.5.tar.gz
[apple/system_cmds.git] / vm_stat.tproj / vm_stat.c
CommitLineData
1815bff5 1/*
cf37c299 2 * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
1815bff5
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
cf37c299 5 *
2fc1e207
A
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
cf37c299 13 *
1815bff5
A
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2fc1e207
A
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
cf37c299 21 *
1815bff5
A
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * File: vm_stat.c
26 * Author: Avadis Tevanian, Jr.
27 *
28 * Copyright (C) 1986, Avadis Tevanian, Jr.
29 *
30 *
31 * Display Mach VM statistics.
32 *
33 ************************************************************************
34 * HISTORY
35 * 6-Jun-86 Avadis Tevanian, Jr. (avie) at Carnegie-Mellon University
36 * Use official Mach interface.
37 *
38 * 25-mar-99 A.Ramesh at Apple
39 * Ported to MacOS X
cf37c299 40 *
ef8ad44b 41 * 22-Jan-09 R.Branche at Apple
cf37c299 42 * Changed some fields to 64-bit to alleviate overflows
1815bff5
A
43 ************************************************************************
44 */
45
fc6d9e4b 46#include <err.h>
83f6dbe8
A
47#include <stddef.h>
48#include <stdlib.h>
1815bff5
A
49#include <unistd.h>
50#include <stdio.h>
51
52#include <mach/mach.h>
1a7e3f61 53#include <mach/vm_page_size.h>
1815bff5 54
ef8ad44b 55vm_statistics64_data_t vm_stat, last;
1815bff5
A
56char *pgmname;
57mach_port_t myHost;
1815bff5 58
83f6dbe8 59void usage(void);
83f6dbe8 60void snapshot(void);
ef8ad44b
A
61void sspstat(char *str, uint64_t n);
62void banner(void);
83f6dbe8 63void print_stats(void);
ef8ad44b
A
64void get_stats(vm_statistics64_t stat);
65
66void pstat(uint64_t n, int width);
1815bff5
A
67
68int
83f6dbe8 69main(int argc, char *argv[])
1815bff5 70{
fc6d9e4b
A
71 double delay = 0.0;
72 int count = 0;
1815bff5 73
fc6d9e4b 74 pgmname = argv[0];
1815bff5
A
75
76 setlinebuf (stdout);
77
fc6d9e4b
A
78 int c;
79 while ((c = getopt (argc, argv, "c:")) != -1) {
80 switch (c) {
81 case 'c':
82 count = (int)strtol(optarg, NULL, 10);
83 if (count < 1) {
84 warnx("count must be positive");
85 usage();
86 }
87 break;
88 default:
89 usage();
90 break;
91 }
92 }
93
94 argc -= optind; argv += optind;
95
96 if (argc == 1) {
97 delay = strtod(argv[0], NULL);
98 if (delay < 0.0)
1815bff5 99 usage();
fc6d9e4b
A
100 } else if (argc > 1) {
101 usage();
1815bff5
A
102 }
103
104 myHost = mach_host_self();
105
fc6d9e4b 106 if (delay == 0.0) {
1815bff5 107 snapshot();
fc6d9e4b
A
108 } else {
109 print_stats();
110 for (int i = 1; i < count || count == 0; i++ ){
111 usleep((int)(delay * USEC_PER_SEC));
1815bff5 112 print_stats();
1815bff5
A
113 }
114 }
83f6dbe8 115 exit(EXIT_SUCCESS);
1815bff5
A
116}
117
118void
83f6dbe8 119usage(void)
1815bff5 120{
fc6d9e4b 121 fprintf(stderr, "usage: %s [[-c count] interval]\n", pgmname);
83f6dbe8 122 exit(EXIT_FAILURE);
1815bff5
A
123}
124
ef8ad44b
A
125void
126snapshot(void)
127{
ef8ad44b 128 get_stats(&vm_stat);
1a7e3f61 129 printf("Mach Virtual Memory Statistics: (page size of %llu bytes)\n", (mach_vm_size_t)vm_kernel_page_size);
ef8ad44b
A
130
131 sspstat("Pages free:", (uint64_t) (vm_stat.free_count - vm_stat.speculative_count));
132 sspstat("Pages active:", (uint64_t) (vm_stat.active_count));
133 sspstat("Pages inactive:", (uint64_t) (vm_stat.inactive_count));
134 sspstat("Pages speculative:", (uint64_t) (vm_stat.speculative_count));
fc6d9e4b 135 sspstat("Pages throttled:", (uint64_t) (vm_stat.throttled_count));
ef8ad44b 136 sspstat("Pages wired down:", (uint64_t) (vm_stat.wire_count));
fc6d9e4b 137 sspstat("Pages purgeable:", (uint64_t) (vm_stat.purgeable_count));
ef8ad44b
A
138 sspstat("\"Translation faults\":", (uint64_t) (vm_stat.faults));
139 sspstat("Pages copy-on-write:", (uint64_t) (vm_stat.cow_faults));
140 sspstat("Pages zero filled:", (uint64_t) (vm_stat.zero_fill_count));
141 sspstat("Pages reactivated:", (uint64_t) (vm_stat.reactivations));
fc6d9e4b
A
142 sspstat("Pages purged:", (uint64_t) (vm_stat.purges));
143 sspstat("File-backed pages:", (uint64_t) (vm_stat.external_page_count));
144 sspstat("Anonymous pages:", (uint64_t) (vm_stat.internal_page_count));
145 sspstat("Pages stored in compressor:", (uint64_t) (vm_stat.total_uncompressed_pages_in_compressor));
146 sspstat("Pages occupied by compressor:", (uint64_t) (vm_stat.compressor_page_count));
147 sspstat("Decompressions:", (uint64_t) (vm_stat.decompressions));
148 sspstat("Compressions:", (uint64_t) (vm_stat.compressions));
ef8ad44b
A
149 sspstat("Pageins:", (uint64_t) (vm_stat.pageins));
150 sspstat("Pageouts:", (uint64_t) (vm_stat.pageouts));
fc6d9e4b
A
151 sspstat("Swapins:", (uint64_t) (vm_stat.swapins));
152 sspstat("Swapouts:", (uint64_t) (vm_stat.swapouts));
ef8ad44b
A
153}
154
155void
156sspstat(char *str, uint64_t n)
157{
fc6d9e4b 158 printf("%-30s %16llu.\n", str, n);
ef8ad44b
A
159}
160
1815bff5 161void
83f6dbe8 162banner(void)
1815bff5
A
163{
164 get_stats(&vm_stat);
165 printf("Mach Virtual Memory Statistics: ");
1a7e3f61 166 printf("(page size of %llu bytes)\n", (mach_vm_size_t)vm_kernel_page_size);
fc6d9e4b
A
167 printf("%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %11s %9s %8s %8s %8s %8s %8s %8s %8s %8s\n",
168 "free",
169 "active",
170 "specul",
171 "inactive",
172 "throttle",
173 "wired",
174 "prgable",
175 "faults",
176 "copy",
177 "0fill",
178 "reactive",
179 "purged",
180 "file-backed",
181 "anonymous",
182 "cmprssed",
183 "cmprssor",
184 "dcomprs",
185 "comprs",
186 "pageins",
187 "pageout",
188 "swapins",
189 "swapouts");
1815bff5
A
190 bzero(&last, sizeof(last));
191}
192
1815bff5 193void
83f6dbe8 194print_stats(void)
1815bff5 195{
83f6dbe8 196 static int count = 0;
1815bff5
A
197
198 if (count++ == 0)
199 banner();
200
201 if (count > 20)
202 count = 0;
203
204 get_stats(&vm_stat);
fc6d9e4b
A
205 pstat((uint64_t) (vm_stat.free_count - vm_stat.speculative_count), 8);
206 pstat((uint64_t) (vm_stat.active_count), 8);
207 pstat((uint64_t) (vm_stat.speculative_count), 8);
ef8ad44b 208 pstat((uint64_t) (vm_stat.inactive_count), 8);
fc6d9e4b
A
209 pstat((uint64_t) (vm_stat.throttled_count), 8);
210 pstat((uint64_t) (vm_stat.wire_count), 8);
211 pstat((uint64_t) (vm_stat.purgeable_count), 8);
ef8ad44b
A
212 pstat((uint64_t) (vm_stat.faults - last.faults), 8);
213 pstat((uint64_t) (vm_stat.cow_faults - last.cow_faults), 8);
214 pstat((uint64_t) (vm_stat.zero_fill_count - last.zero_fill_count), 8);
215 pstat((uint64_t) (vm_stat.reactivations - last.reactivations), 8);
fc6d9e4b
A
216 pstat((uint64_t) (vm_stat.purges - last.purges), 8);
217 pstat((uint64_t) (vm_stat.external_page_count), 11);
218 pstat((uint64_t) (vm_stat.internal_page_count), 9);
219 pstat((uint64_t) (vm_stat.total_uncompressed_pages_in_compressor), 8);
220 pstat((uint64_t) (vm_stat.compressor_page_count), 8);
221 pstat((uint64_t) (vm_stat.decompressions - last.decompressions), 8);
222 pstat((uint64_t) (vm_stat.compressions - last.compressions), 8);
ef8ad44b
A
223 pstat((uint64_t) (vm_stat.pageins - last.pageins), 8);
224 pstat((uint64_t) (vm_stat.pageouts - last.pageouts), 8);
fc6d9e4b
A
225 pstat((uint64_t) (vm_stat.swapins - last.swapins), 8);
226 pstat((uint64_t) (vm_stat.swapouts - last.swapouts), 8);
ef8ad44b 227 putchar('\n');
1815bff5
A
228 last = vm_stat;
229}
230
231void
ef8ad44b
A
232pstat(uint64_t n, int width)
233{
234 char buf[80];
235 if (width >= sizeof(buf)) {
236 width = sizeof(buf) -1;
237 }
238
ef8ad44b
A
239 /* Now that we have the speculative field, there is really not enough
240 space, but we were actually overflowing three or four fields before
241 anyway. So any field that overflows we drop some insignifigant
242 digets and slap on the appropriate suffix
243 */
244 int w = snprintf(buf, sizeof(buf), "%*llu", width, n);
245 if (w > width) {
246 w = snprintf(buf, sizeof(buf), "%*lluK", width -1, n / 1000);
247 if (w > width) {
248 w = snprintf(buf, sizeof(buf), "%*lluM", width -1, n / 1000000);
249 if (w > width) {
250 w = snprintf(buf, sizeof(buf), "%*lluG", width -1, n / 1000000000);
251 }
252 }
253 }
254 fputs(buf, stdout);
255 putchar(' ');
256}
257
258void
259get_stats(vm_statistics64_t stat)
1815bff5 260{
ef8ad44b 261 unsigned int count = HOST_VM_INFO64_COUNT;
381af97e
A
262 kern_return_t ret;
263 if ((ret = host_statistics64(myHost, HOST_VM_INFO64, (host_info64_t)stat, &count) != KERN_SUCCESS)) {
264 fprintf(stderr, "%s: failed to get statistics. error %d\n", pgmname, ret);
83f6dbe8 265 exit(EXIT_FAILURE);
1815bff5 266 }
1815bff5 267}