summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1996-02-03 07:08:36 +0000
committerMiles Bader <miles@gnu.org>1996-02-03 07:08:36 +0000
commitf0b14ffdbc961ff993452810bb8110a05d5c40ca (patch)
tree723f3379ce980428fbf47921fd5921b0aa05061e /utils
parentf813b59cdcee8c3d2939b4d0d428cb7a93b99a23 (diff)
Initial revision
Diffstat (limited to 'utils')
-rw-r--r--utils/vmstat.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/utils/vmstat.c b/utils/vmstat.c
new file mode 100644
index 00000000..04cc1baa
--- /dev/null
+++ b/utils/vmstat.c
@@ -0,0 +1,210 @@
+/* Print vm statistics
+
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <argp.h>
+#include <error.h>
+#include <string.h>
+
+#include <mach.h>
+#include <mach/vm_statistics.h>
+
+struct field {
+ /* Name of the field; used for the option name. */
+ char *name;
+
+ /* A descriptive title used for long output format. */
+ char *desc;
+
+ /* Terse header used for the columnar style output. */
+ char *hdr;
+
+ /* Offset of the integer_t field in a vm_statistics structure */
+ int offs;
+};
+
+/* Returns the byte offset of the field FIELD in a vm_statistics structure. */
+#define FOFFS(field) offsetof (struct vm_statistics, field)
+
+/* vm_statistics fields we know about. */
+static struct field fields[] = {
+ { "pagesize", "Pagesize", "pgsz", FOFFS (pagesize) },
+ { "free", "Free pages", "free", FOFFS (free_count) },
+ { "active", "Active pages", "actv", FOFFS (active_count) },
+ { "inactive", "Inactive pages", "inact", FOFFS (inactive_count) },
+ { "wired", "Wired pages", "wired", FOFFS (wire_count) },
+ { "zero-filled", "Zero'd pages", "zero", FOFFS (zero_fill_count) },
+ { "reactivations","Reactivations", "react", FOFFS (reactivations) },
+ { "pageins", "Pageins", "pgin", FOFFS (pageins) },
+ { "pageouts", "Pageouts", "pgout", FOFFS (pageouts) },
+ { "faults", "Faults", "faults", FOFFS (faults) },
+ { "cow-faults", "Cow faults", "cowf", FOFFS (cow_faults) },
+ { "cache-lookups","Cache lookups", "clkup", FOFFS (lookups) },
+ { "cache-hits", "Cache hits", "chits", FOFFS (hits) },
+ {0}
+};
+
+static struct argp_option options[] = {
+ {"terse", 't', 0, 0, "Use short one-line output format", 1 },
+ {"no-header", 'H', 0, 0, "Don't print a descriptive header line"},
+ {"prefix", 'p', 0, 0, "Always display a description before stats"},
+ {"no-prefix", 'P', 0, 0, "Never display a description before stats"},
+
+ /* A header for all the individual field options. */
+ { 0,0,0,0, "Selecting which statistics to show:", 2},
+
+ {0}
+};
+static char *args_doc = 0;
+static char *doc = 0;
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ struct field *field;
+ struct vm_statistics stats;
+ int num_fields = 0; /* Number of vm_fields known. */
+ unsigned long output_fields = 0; /* A bit per field, from 0. */
+
+ int terse = 0, print_heading = 1, print_prefix = -1;
+
+ /* Parse our options... */
+ error_t parse_opt (int key, char *arg, struct argp_state *state)
+ {
+ if (key < 0)
+ /* A field option. */
+ output_fields |= (1 << (-1 - key));
+ else
+ switch (key)
+ {
+ case 't': terse = 1; break;
+ case 'p': print_prefix = 1; break;
+ case 'P': print_prefix = 0; break;
+ case 'H': print_heading = 0; break;
+ default: return EINVAL;
+ }
+ return 0;
+ }
+ struct argp_option *field_opts;
+ int field_opts_size;
+ struct argp field_argp = { 0, parse_opt };
+ struct argp *parents[] = { &field_argp, 0 };
+ struct argp argp = { options, parse_opt, args_doc, doc, parents };
+
+ /* See how many fields we know about. */
+ for (field = fields; field->name; field++)
+ num_fields++;
+
+ /* Construct an options vector for them. */
+ field_opts_size = ((num_fields + 1) * sizeof (struct argp_option));
+ field_opts = alloca (field_opts_size);
+ bzero (field_opts, field_opts_size);
+
+ for (field = fields; field->name; field++)
+ {
+ int which = field - fields;
+ struct argp_option *opt = &field_opts[which];
+
+ opt->name = field->name;
+ opt->key = -1 - which; /* options are numbered -1 ... -(N - 1). */
+ opt->doc = field->desc;
+ opt->group = 2;
+ }
+ /* No need to terminate FIELD_OPTS because the bzero above's done so. */
+
+ field_argp.options = field_opts;
+
+ /* Parse our arguments. */
+ argp_parse (&argp, argc, argv, 0, 0);
+
+ if (output_fields == 0)
+ output_fields = ~0; /* By default, show all fields. */
+
+ /* Actually fetch the statistics. */
+ err = vm_statistics (mach_task_self (), &stats);
+ if (err)
+ error (2, err, "vm_statistics");
+
+ /* Print them. */
+ if (terse)
+ {
+ int first = 1;
+ if (print_heading)
+ {
+ int which;
+ for (which = 0; which < num_fields; which++)
+ if (output_fields & (1 << which))
+ {
+ if (first)
+ first = 0;
+ else
+ putchar (' ');
+ fputs (fields[which].hdr, stdout);
+ }
+ putchar ('\n');
+ }
+ first = 1;
+ for (field = fields; field->name; field++)
+ if (output_fields & (1 << (field - fields)))
+ {
+ int width = strlen (field->hdr);
+ if (first)
+ first = 0;
+ else
+ putchar (' ');
+ printf ("%*d", width,
+ *(integer_t *)((char *)&stats + field->offs));
+ }
+ putchar ('\n');
+ }
+ else
+ /* Verbose output. */
+ {
+ int max_desc_width = 0;
+
+ if (print_prefix < 0)
+ /* By default, only print a prefix if there are multiple fields. */
+ print_prefix = (output_fields & (output_fields - 1));
+
+ if (print_prefix)
+ /* Find the widest description string, so we can align the output. */
+ for (field = fields; field->name; field++)
+ if (output_fields & (1 << (field - fields)))
+ {
+ int desc_len = strlen (field->desc);
+ if (desc_len > max_desc_width)
+ max_desc_width = desc_len;
+ }
+
+ for (field = fields; field->name; field++)
+ if (output_fields & (1 << (field - fields)))
+ if (print_prefix)
+ printf ("%s: %*d\n",
+ field->desc,
+ max_desc_width + 6 - strlen (field->desc),
+ *(integer_t *)((char *)&stats + field->offs));
+ else
+ printf ("%d\n", *(integer_t *)((char *)&stats + field->offs));
+ }
+
+ exit (0);
+}