Include code to display per system call counts and times.
This commit is contained in:
parent
d64834e4f1
commit
49c5f0e9e5
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.32 2006/04/14 13:14:06 blymn Exp $
|
||||
# $NetBSD: Makefile,v 1.33 2007/02/18 17:00:08 dsl Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
.include <bsd.own.mk>
|
||||
@ -13,7 +13,8 @@ CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/vmstat -DSUPPORT_UTMP -DSUPPORT_UTMPX \
|
||||
CWARNFLAGS+= -Wno-format-y2k
|
||||
SRCS= bufcache.c cmds.c cmdtab.c disks.c df.c drvstats.c fetch.c \
|
||||
globalcmds.c icmp.c iostat.c ip.c keyboard.c main.c mbufs.c \
|
||||
netcmds.c netstat.c pigs.c ps.c swap.c tcp.c vmstat.c utmpentry.c
|
||||
netcmds.c netstat.c pigs.c ps.c swap.c tcp.c vmstat.c utmpentry.c \
|
||||
syscall.c
|
||||
DPADD= ${LIBCURSES} ${LIBM} ${LIBKVM}
|
||||
LDADD= -lutil -lcurses -lm -lkvm
|
||||
BINGRP= kmem
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cmdtab.c,v 1.22 2006/10/22 16:43:24 christos Exp $ */
|
||||
/* $NetBSD: cmdtab.c,v 1.23 2007/02/18 17:00:08 dsl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1992, 1993
|
||||
@ -34,7 +34,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
__RCSID("$NetBSD: cmdtab.c,v 1.22 2006/10/22 16:43:24 christos Exp $");
|
||||
__RCSID("$NetBSD: cmdtab.c,v 1.23 2007/02/18 17:00:08 dsl Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include "systat.h"
|
||||
@ -148,6 +148,16 @@ struct command vmstat_commands[] = {
|
||||
{ .c_name = NULL }
|
||||
};
|
||||
|
||||
struct command syscall_commands[] = {
|
||||
{ "boot", syscall_boot, "show total syscall stats since boot"},
|
||||
{ "run", syscall_run, "show running total syscall stats"},
|
||||
{ "time", syscall_time, "show syscall stats for each sample time"},
|
||||
{ "zero", syscall_zero, "re-zero running totals"},
|
||||
{ "sort", syscall_order, "sort by [name|count|syscall]"},
|
||||
{ "show", syscall_show, "show [count|time]"},
|
||||
{ .c_name = NULL }
|
||||
};
|
||||
|
||||
struct mode modes[] = {
|
||||
/* "pigs" is the default, it must be first. */
|
||||
{ "pigs", showpigs, fetchpigs, labelpigs,
|
||||
@ -199,6 +209,9 @@ struct mode modes[] = {
|
||||
{ "vmstat", showvmstat, fetchvmstat, labelvmstat,
|
||||
initvmstat, openvmstat, closevmstat, vmstat_commands,
|
||||
0 },
|
||||
{ "syscall", showsyscall, fetchsyscall, labelsyscall,
|
||||
initsyscall, opensyscall, closesyscall, syscall_commands,
|
||||
0 },
|
||||
{ .c_name = NULL }
|
||||
};
|
||||
struct mode *curmode = &modes[0];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.36 2005/02/26 22:12:33 dsl Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.37 2007/02/18 17:00:08 dsl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -77,6 +77,7 @@ void closeicmp(WINDOW *);
|
||||
void closeiostat(WINDOW *);
|
||||
void closeip(WINDOW *);
|
||||
void closevmstat(WINDOW *);
|
||||
void closesyscall(WINDOW *);
|
||||
void closembufs(WINDOW *);
|
||||
void closenetstat(WINDOW *);
|
||||
void closepigs(WINDOW *);
|
||||
@ -98,6 +99,7 @@ void fetchicmp(void);
|
||||
void fetchiostat(void);
|
||||
void fetchip(void);
|
||||
void fetchvmstat(void);
|
||||
void fetchsyscall(void);
|
||||
void fetchmbufs(void);
|
||||
void fetchnetstat(void);
|
||||
void fetchpigs(void);
|
||||
@ -119,6 +121,7 @@ int initicmp(void);
|
||||
int initiostat(void);
|
||||
int initip(void);
|
||||
int initvmstat(void);
|
||||
int initsyscall(void);
|
||||
int initmbufs(void);
|
||||
int initnetstat(void);
|
||||
int initpigs(void);
|
||||
@ -141,6 +144,7 @@ void labelicmp(void);
|
||||
void labeliostat(void);
|
||||
void labelip(void);
|
||||
void labelvmstat(void);
|
||||
void labelsyscall(void);
|
||||
void labelmbufs(void);
|
||||
void labelnetstat(void);
|
||||
void labelpigs(void);
|
||||
@ -165,6 +169,7 @@ WINDOW *openicmp(void);
|
||||
WINDOW *openiostat(void);
|
||||
WINDOW *openip(void);
|
||||
WINDOW *openvmstat(void);
|
||||
WINDOW *opensyscall(void);
|
||||
WINDOW *openmbufs(void);
|
||||
WINDOW *opennetstat(void);
|
||||
WINDOW *openpigs(void);
|
||||
@ -178,6 +183,7 @@ void showicmp(void);
|
||||
void showiostat(void);
|
||||
void showip(void);
|
||||
void showvmstat(void);
|
||||
void showsyscall(void);
|
||||
void showmbufs(void);
|
||||
void shownetstat(void);
|
||||
void showpigs(void);
|
||||
@ -195,6 +201,12 @@ void vmstat_boot(char *);
|
||||
void vmstat_run(char *);
|
||||
void vmstat_time(char *);
|
||||
void vmstat_zero(char *);
|
||||
void syscall_boot(char *);
|
||||
void syscall_run(char *);
|
||||
void syscall_time(char *);
|
||||
void syscall_zero(char *);
|
||||
void syscall_order(char *);
|
||||
void syscall_show(char *);
|
||||
|
||||
#ifdef INET6
|
||||
void closeip6(WINDOW *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: syscall.c,v 1.2 2006/05/20 20:07:35 dsl Exp $ */
|
||||
/* $NetBSD: syscall.c,v 1.3 2007/02/18 17:00:08 dsl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: syscall.c,v 1.2 2006/05/20 20:07:35 dsl Exp $");
|
||||
__RCSID("$NetBSD: syscall.c,v 1.3 2007/02/18 17:00:08 dsl Exp $");
|
||||
|
||||
/* System call stats */
|
||||
|
||||
@ -66,7 +66,10 @@ static struct Info {
|
||||
struct vmtotal Total;
|
||||
uint64_t counts[SYS_NSYSENT];
|
||||
uint64_t times[SYS_NSYSENT];
|
||||
} s, s1, s2, irf;
|
||||
} s, s1, s2;
|
||||
|
||||
static uint64_t irf[SYS_NSYSENT], val[SYS_NSYSENT];
|
||||
static int irf_first = 1;
|
||||
|
||||
int syscall_sort[SYS_NSYSENT];
|
||||
|
||||
@ -78,7 +81,7 @@ static int show = SHOW_COUNTS;
|
||||
|
||||
static void getinfo(struct Info *, int);
|
||||
|
||||
static char buf[26];
|
||||
static char buf[32];
|
||||
static float hertz;
|
||||
|
||||
static size_t counts_mib_len, times_mib_len;
|
||||
@ -151,30 +154,34 @@ labelsyscall(void)
|
||||
|
||||
#define MAXFAIL 5
|
||||
|
||||
static int
|
||||
compare_counts(const void *a, const void *b)
|
||||
static void
|
||||
putuint64(uint64_t v, int row, int col, int width)
|
||||
{
|
||||
int ia = *(const int *)a, ib = *(const int *)b;
|
||||
int64_t delta;
|
||||
static const char suffix[] = "KMDT";
|
||||
int len, i;
|
||||
|
||||
if (display_mode == TIME)
|
||||
delta = irf.counts[ib] - irf.counts[ia];
|
||||
else
|
||||
delta = s.counts[ib] - s1.counts[ib]
|
||||
- (s.counts[ia] - s1.counts[ia]);
|
||||
return delta ? delta < 0 ? -1 : 1 : 0;
|
||||
len = snprintf(buf, sizeof buf, "%" PRIu64, v);
|
||||
if (len > width) {
|
||||
i = (len - width) / 3;
|
||||
if (i >= sizeof suffix) {
|
||||
memset(buf, '*', width);
|
||||
len = width;
|
||||
} else {
|
||||
len -= (i + 1) * 3;
|
||||
buf[len++] = suffix[i];
|
||||
}
|
||||
buf[len] = 0;
|
||||
}
|
||||
mvprintw(row, col, "%*s", width, buf);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_times(const void *a, const void *b)
|
||||
compare_irf(const void *a, const void *b)
|
||||
{
|
||||
int ia = *(const int *)a, ib = *(const int *)b;
|
||||
int64_t delta;
|
||||
|
||||
if (display_mode == TIME)
|
||||
delta = irf.times[ib] - irf.times[ia];
|
||||
else
|
||||
delta = s.times[ib] - s1.times[ib] - s.times[ia] + s1.times[ia];
|
||||
delta = irf[ib] - irf[ia];
|
||||
return delta ? delta < 0 ? -1 : 1 : 0;
|
||||
}
|
||||
|
||||
@ -182,10 +189,11 @@ void
|
||||
showsyscall(void)
|
||||
{
|
||||
int i, ii, l, c;
|
||||
uint64_t val;
|
||||
uint64_t v;
|
||||
static int failcnt = 0;
|
||||
static int relabel = 0;
|
||||
static char pigs[] = "pigs";
|
||||
uint64_t itime;
|
||||
|
||||
if (relabel) {
|
||||
labelsyscall();
|
||||
@ -212,40 +220,49 @@ showsyscall(void)
|
||||
}
|
||||
} else
|
||||
etime = 1.0;
|
||||
itime = etime * 100;
|
||||
|
||||
failcnt = 0;
|
||||
|
||||
show_vmstat_top(&s.Total, &s.uvmexp, &s1.uvmexp);
|
||||
|
||||
if (sort_order == COUNTS) {
|
||||
/* Sort out the values we are going to display */
|
||||
for (i = 0; i < nelem(s.counts); i++) {
|
||||
switch (show) {
|
||||
default:
|
||||
case SHOW_COUNTS:
|
||||
v = s.counts[i] - s1.counts[i];
|
||||
break;
|
||||
case SHOW_TIMES:
|
||||
v = s.times[i] - s1.times[i];
|
||||
break;
|
||||
case SHOW_COUNTS | SHOW_TIMES: /* time/count */
|
||||
v = s.counts[i] - s1.counts[i];
|
||||
v = v ? (s.times[i] - s1.times[i]) / v : 0;
|
||||
}
|
||||
|
||||
if (display_mode == TIME)
|
||||
v = (v * 100 + itime/2) / itime;
|
||||
|
||||
val[i] = v;
|
||||
|
||||
/*
|
||||
* We use an 'infinite response filter' in a vague
|
||||
* attempt to stop the data leaping around too much.
|
||||
* I suspect there are other/better methods in use.
|
||||
*/
|
||||
if (show & SHOW_COUNTS) {
|
||||
for (i = 0; i < nelem(s.counts); i++) {
|
||||
val = s.counts[i] - s1.counts[i];
|
||||
if (irf.counts[i] > 0xfffffff)
|
||||
irf.counts[i] = irf.counts[i] / 8 * 7 + val;
|
||||
else
|
||||
irf.counts[i] = irf.counts[i] * 7 / 8 + val;
|
||||
}
|
||||
}
|
||||
if (show & SHOW_TIMES) {
|
||||
for (i = 0; i < nelem(s.times); i++) {
|
||||
val = s.times[i] - s1.times[i];
|
||||
if (irf.times[i] > 0xfffffff)
|
||||
irf.times[i] = irf.times[i] / 8 * 7 + val;
|
||||
else
|
||||
irf.times[i] = irf.times[i] * 7 / 8 + val;
|
||||
}
|
||||
if (irf_first) {
|
||||
irf[i] = v;
|
||||
irf_first = 0;
|
||||
} else {
|
||||
irf[i] = irf[i] * 7 / 8 + v;
|
||||
}
|
||||
}
|
||||
|
||||
if (sort_order == COUNTS) {
|
||||
/* mergesort() doesn't swap equal values about... */
|
||||
mergesort(syscall_sort, nelem(syscall_sort),
|
||||
sizeof syscall_sort[0],
|
||||
show & SHOW_COUNTS ? compare_counts : compare_times);
|
||||
sizeof syscall_sort[0], compare_irf);
|
||||
}
|
||||
|
||||
l = SYSCALLROW;
|
||||
@ -253,20 +270,7 @@ showsyscall(void)
|
||||
move(l, c);
|
||||
for (ii = 0; ii < nelem(s.counts); ii++) {
|
||||
i = syscall_sort[ii];
|
||||
switch (show) {
|
||||
default:
|
||||
case SHOW_COUNTS:
|
||||
val = s.counts[i] - s1.counts[i];
|
||||
break;
|
||||
case SHOW_TIMES:
|
||||
val = s.times[i] - s1.times[i];
|
||||
break;
|
||||
case SHOW_COUNTS | SHOW_TIMES:
|
||||
val = s.counts[i] - s1.counts[i];
|
||||
if (val != 0)
|
||||
val = (s.times[i] - s1.times[i]) / val;
|
||||
}
|
||||
if (val == 0 && irf.counts[i] == 0 && irf.times[i] == 0)
|
||||
if (val[i] == 0 && irf[i] == 0)
|
||||
continue;
|
||||
|
||||
if (i < nelem(syscallnames)) {
|
||||
@ -279,7 +283,7 @@ showsyscall(void)
|
||||
} else
|
||||
mvprintw(l, c, "syscall #%d ", i);
|
||||
|
||||
putint((unsigned int)((double)val/etime + 0.5), l, c + 17, 9);
|
||||
putuint64(val[i], l, c + 18, 8);
|
||||
c += 27;
|
||||
if (c + 26 > COLS) {
|
||||
c = 0;
|
||||
@ -351,10 +355,9 @@ syscall_order(char *args)
|
||||
if (args[len + strspn(args + len, " \t\r\n")])
|
||||
goto usage;
|
||||
|
||||
if (memcmp(args, "count", len) == 0) {
|
||||
if (memcmp(args, "count", len) == 0)
|
||||
sort_order = COUNTS;
|
||||
memset(&irf, 0, sizeof irf);
|
||||
} else if (memcmp(args, "name", len) == 0)
|
||||
else if (memcmp(args, "name", len) == 0)
|
||||
sort_order = NAMES;
|
||||
else if (memcmp(args, "syscall", len) == 0)
|
||||
sort_order = UNSORTED;
|
||||
@ -398,6 +401,9 @@ syscall_show(char *args)
|
||||
else
|
||||
goto usage;
|
||||
|
||||
memset(&irf, 0, sizeof irf);
|
||||
irf_first = 1;
|
||||
|
||||
return;
|
||||
|
||||
usage:
|
||||
|
Loading…
Reference in New Issue
Block a user