Add a toggle to display the approximate amount of swap used by each
process. We don't *quite* pull that number out of our backside, as the actual number is difficult to determine without modifying the VM system to report it, but it's still useful to get an idea of what's going on when a machine unexpectedly starts swapping. MFC after: 1 week
This commit is contained in:
parent
031986c4f3
commit
b6924c9309
@ -104,6 +104,7 @@ S - toggle the displaying of system processes\n\
|
||||
a - toggle the displaying of process titles\n\
|
||||
t - toggle the display of this process\n\
|
||||
u - display processes for only one user (+ selects all users)\n\
|
||||
w - toggle the display of swap use for each process\n\
|
||||
z - toggle the displaying of the system idle process\n\
|
||||
\n\
|
||||
\n", stdout);
|
||||
|
@ -72,6 +72,7 @@ struct process_select
|
||||
int wcpu; /* show weighted cpu */
|
||||
int jid; /* only this jid (unless jid == -1) */
|
||||
int jail; /* show jail ID */
|
||||
int swap; /* show swap usage */
|
||||
int kidle; /* show per-CPU idle threads */
|
||||
char *command; /* only this command (unless == NULL) */
|
||||
};
|
||||
@ -82,8 +83,8 @@ char *format_header();
|
||||
char *format_next_process();
|
||||
void toggle_pcpustats(void);
|
||||
void get_system_info(struct system_info *si);
|
||||
int machine_init(struct statics *statics, char do_unames);
|
||||
int proc_owner(int pid);
|
||||
int machine_init(struct statics *statics, char do_unames);
|
||||
int proc_owner(int pid);
|
||||
|
||||
/* non-int routines typically used by the machine dependent module */
|
||||
char *printable();
|
||||
|
@ -188,9 +188,9 @@ char *argv[];
|
||||
fd_set readfds;
|
||||
|
||||
#ifdef ORDER
|
||||
static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJo";
|
||||
static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJwo";
|
||||
#else
|
||||
static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJ";
|
||||
static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJw";
|
||||
#endif
|
||||
/* these defines enumerate the "strchr"s of the commands in command_chars */
|
||||
#define CMD_redraw 0
|
||||
@ -219,8 +219,9 @@ char *argv[];
|
||||
#define CMD_kidletog 22
|
||||
#define CMD_pcputog 23
|
||||
#define CMD_jail 24
|
||||
#define CMD_swaptog 25
|
||||
#ifdef ORDER
|
||||
#define CMD_order 25
|
||||
#define CMD_order 26
|
||||
#endif
|
||||
|
||||
/* set the buffer for stdout */
|
||||
@ -254,6 +255,7 @@ char *argv[];
|
||||
ps.wcpu = 1;
|
||||
ps.jid = -1;
|
||||
ps.jail = No;
|
||||
ps.swap = No;
|
||||
ps.kidle = Yes;
|
||||
ps.command = NULL;
|
||||
|
||||
@ -280,7 +282,7 @@ char *argv[];
|
||||
optind = 1;
|
||||
}
|
||||
|
||||
while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:t")) != EOF)
|
||||
while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:tw")) != EOF)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
@ -418,6 +420,10 @@ char *argv[];
|
||||
pcpu_stats = !pcpu_stats;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
ps.swap = 1;
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
ps.kidle = !ps.kidle;
|
||||
break;
|
||||
@ -1141,6 +1147,15 @@ char *argv[];
|
||||
reset_display();
|
||||
putchar('\r');
|
||||
break;
|
||||
case CMD_swaptog:
|
||||
ps.swap = !ps.swap;
|
||||
new_message(MT_standout | MT_delayed,
|
||||
" %sisplaying per-process swap usage.",
|
||||
ps.swap ? "D" : "Not d");
|
||||
header_text = format_header(uname_field);
|
||||
reset_display();
|
||||
putchar('\r');
|
||||
break;
|
||||
default:
|
||||
new_message(MT_standout, " BAD CASE IN SWITCH!");
|
||||
putchar('\r');
|
||||
|
@ -10,7 +10,7 @@ top \- display and update information about the top cpu processes
|
||||
.SH SYNOPSIS
|
||||
.B top
|
||||
[
|
||||
.B \-abCHIijnPqStuvz
|
||||
.B \-abCHIijnPqStuvwz
|
||||
] [
|
||||
.BI \-d count
|
||||
] [
|
||||
@ -148,6 +148,9 @@ Write version number information to stderr then exit immediately.
|
||||
No other processing takes place when this option is used. To see current
|
||||
revision information while top is running, use the help command \*(lq?\*(rq.
|
||||
.TP
|
||||
.B \-w
|
||||
Display approximate swap usage for each process.
|
||||
.TP
|
||||
.B \-z
|
||||
Do not display the system idle process.
|
||||
.TP
|
||||
@ -167,11 +170,12 @@ Set the delay between screen updates to
|
||||
seconds. The default delay between updates is \nD seconds.
|
||||
.TP
|
||||
.BI \-o field
|
||||
Sort the process display area on the specified field. The field name is
|
||||
the name of the column as seen in the output, but in lower case. Likely
|
||||
values are \*(lqcpu\*(rq, \*(lqsize\*(rq, \*(lqres\*(rq, and \*(lqtime\*(rq,
|
||||
but may vary on different operating systems. Note that
|
||||
not all operating systems support this option.
|
||||
Sort the process display area on the specified field. The field name
|
||||
is the name of the column as seen in the output, but in lower case:
|
||||
\*(lqcpu\*(lq, \*(rqsize\*(lq, \*(rqres\*(lq, \*(rqtime\*(lq,
|
||||
\*(rqpri\*(lq, \*(rqthreads\*(lq, \*(lqtotal\*(lq, \*(rqread\*(lq,
|
||||
\*(rqwrite\*(lq, \*(rqfault\*(lq, \*(rqvcsw\*(lq, \*(rqivcsw\*(lq,
|
||||
\*(lqjid\*(lq, \*(rqswap\*(lq or \*(rqpid\*(lq.
|
||||
.TP
|
||||
.BI \-J jail
|
||||
Show only those processes owned by
|
||||
@ -226,6 +230,7 @@ The options
|
||||
.BR \-S ,
|
||||
.BR \-t ,
|
||||
.BR \-u ,
|
||||
.BR \-w ,
|
||||
and
|
||||
.B \-z
|
||||
are actually toggles. A second specification of any of these options
|
||||
@ -346,6 +351,9 @@ Toggle the display of the
|
||||
.I top
|
||||
process.
|
||||
.TP
|
||||
.B w
|
||||
Toggle the display of swap usage.
|
||||
.TP
|
||||
.B z
|
||||
Toggle the display of the system idle process.
|
||||
.SH "THE DISPLAY"
|
||||
@ -379,8 +387,9 @@ is specified, a UID column will be substituted for USERNAME),
|
||||
PRI is the current priority of the process,
|
||||
NICE is the nice amount (in the range \-20 to 20),
|
||||
SIZE is the total size of the process (text, data, and stack),
|
||||
RES is the current amount of resident memory (both SIZE and RES are
|
||||
given in kilobytes),
|
||||
RES is the current amount of resident memory,
|
||||
SWAP is the approximate amount of swap, if enabled
|
||||
(SIZE, RES and SWAP are given in kilobytes),
|
||||
STATE is the current state (one of \*(lqSTART\*(rq, \*(lqRUN\*(rq
|
||||
(shown as \*(lqCPUn\*(rq on SMP systems), \*(lqSLEEP\*(rq, \*(lqSTOP\*(rq,
|
||||
\*(lqZOMB\*(rq, \*(lqWAIT\*(rq, \*(lqLOCK\*(rq or the event on which the
|
||||
|
@ -69,7 +69,9 @@ static int namelength = 8;
|
||||
#endif
|
||||
/* TOP_JID_LEN based on max of 999999 */
|
||||
#define TOP_JID_LEN 7
|
||||
#define TOP_SWAP_LEN 6
|
||||
static int jidlength;
|
||||
static int swaplength;
|
||||
static int cmdlengthdelta;
|
||||
|
||||
/* Prototypes for top internals */
|
||||
@ -111,20 +113,20 @@ static char io_header[] =
|
||||
"%5d%*s %-*.*s %6ld %6ld %6ld %6ld %6ld %6ld %6.2f%% %.*s"
|
||||
|
||||
static char smp_header_thr[] =
|
||||
" PID%*s %-*.*s THR PRI NICE SIZE RES STATE C TIME %7s COMMAND";
|
||||
" PID%*s %-*.*s THR PRI NICE SIZE RES%*s STATE C TIME %7s COMMAND";
|
||||
static char smp_header[] =
|
||||
" PID%*s %-*.*s " "PRI NICE SIZE RES STATE C TIME %7s COMMAND";
|
||||
" PID%*s %-*.*s " "PRI NICE SIZE RES%*s STATE C TIME %7s COMMAND";
|
||||
|
||||
#define smp_Proc_format \
|
||||
"%5d%*s %-*.*s %s%3d %4s%7s %6s %-6.6s %2d%7s %6.2f%% %.*s"
|
||||
"%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s %2d%7s %6.2f%% %.*s"
|
||||
|
||||
static char up_header_thr[] =
|
||||
" PID%*s %-*.*s THR PRI NICE SIZE RES STATE TIME %7s COMMAND";
|
||||
" PID%*s %-*.*s THR PRI NICE SIZE RES%*s STATE TIME %7s COMMAND";
|
||||
static char up_header[] =
|
||||
" PID%*s %-*.*s " "PRI NICE SIZE RES STATE TIME %7s COMMAND";
|
||||
" PID%*s %-*.*s " "PRI NICE SIZE RES%*s STATE TIME %7s COMMAND";
|
||||
|
||||
#define up_Proc_format \
|
||||
"%5d%*s %-*.*s %s%3d %4s%7s %6s %-6.6s%.0d%7s %6.2f%% %.*s"
|
||||
"%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s%.0d%7s %6.2f%% %.*s"
|
||||
|
||||
|
||||
/* process state names for the "STATE" column of the display */
|
||||
@ -227,6 +229,10 @@ static int pageshift; /* log base 2 of the pagesize */
|
||||
|
||||
#define pagetok(size) ((size) << pageshift)
|
||||
|
||||
/* swap usage */
|
||||
#define ki_swap(kip) \
|
||||
((kip)->ki_swrss > (kip)->ki_rssize ? (kip)->ki_swrss - (kip)->ki_rssize : 0)
|
||||
|
||||
/* useful externals */
|
||||
long percentages();
|
||||
|
||||
@ -237,7 +243,7 @@ long percentages();
|
||||
char *ordernames[] = {
|
||||
"cpu", "size", "res", "time", "pri", "threads",
|
||||
"total", "read", "write", "fault", "vcsw", "ivcsw",
|
||||
"jid", "pid", NULL
|
||||
"jid", "swap", "pid", NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -252,6 +258,7 @@ static long *pcpu_cp_old;
|
||||
static long *pcpu_cp_diff;
|
||||
static int *pcpu_cpu_states;
|
||||
|
||||
static int compare_swap(const void *a, const void *b);
|
||||
static int compare_jid(const void *a, const void *b);
|
||||
static int compare_pid(const void *a, const void *b);
|
||||
static int compare_tid(const void *a, const void *b);
|
||||
@ -412,6 +419,11 @@ format_header(char *uname_field)
|
||||
else
|
||||
jidlength = 0;
|
||||
|
||||
if (ps.swap)
|
||||
swaplength = TOP_SWAP_LEN + 1; /* +1 for extra left space */
|
||||
else
|
||||
swaplength = 0;
|
||||
|
||||
switch (displaymode) {
|
||||
case DISP_CPU:
|
||||
/*
|
||||
@ -426,6 +438,7 @@ format_header(char *uname_field)
|
||||
snprintf(Header, sizeof(Header), prehead,
|
||||
jidlength, ps.jail ? " JID" : "",
|
||||
namelength, namelength, uname_field,
|
||||
swaplength, ps.swap ? " SWAP" : "",
|
||||
ps.wcpu ? "WCPU" : "CPU");
|
||||
break;
|
||||
case DISP_IO:
|
||||
@ -902,7 +915,8 @@ format_next_process(caddr_t handle, char *(*get_userid)(int), int flags)
|
||||
int cpu, state;
|
||||
struct rusage ru, *rup;
|
||||
long p_tot, s_tot;
|
||||
char *proc_fmt, thr_buf[6], jid_buf[TOP_JID_LEN + 1];
|
||||
char *proc_fmt, thr_buf[6];
|
||||
char jid_buf[TOP_JID_LEN + 1], swap_buf[TOP_SWAP_LEN + 1];
|
||||
char *cmdbuf = NULL;
|
||||
char **args;
|
||||
const int cmdlen = 128;
|
||||
@ -1061,6 +1075,13 @@ format_next_process(caddr_t handle, char *(*get_userid)(int), int flags)
|
||||
snprintf(jid_buf, sizeof(jid_buf), "%*d",
|
||||
jidlength - 1, pp->ki_jid);
|
||||
|
||||
if (ps.swap == 0)
|
||||
swap_buf[0] = '\0';
|
||||
else
|
||||
snprintf(swap_buf, sizeof(swap_buf), "%*s",
|
||||
swaplength - 1,
|
||||
format_k2(pagetok(ki_swap(pp)))); /* XXX */
|
||||
|
||||
if (displaymode == DISP_IO) {
|
||||
oldp = get_old_proc(pp);
|
||||
if (oldp != NULL) {
|
||||
@ -1122,6 +1143,7 @@ format_next_process(caddr_t handle, char *(*get_userid)(int), int flags)
|
||||
format_nice(pp),
|
||||
format_k2(PROCSIZE(pp)),
|
||||
format_k2(pagetok(pp->ki_rssize)),
|
||||
swaplength, swaplength, swap_buf,
|
||||
status,
|
||||
cpu,
|
||||
format_time(cputime),
|
||||
@ -1309,6 +1331,12 @@ static int sorted_state[] = {
|
||||
return (diff > 0 ? 1 : -1); \
|
||||
} while (0)
|
||||
|
||||
#define ORDERKEY_SWAP(a, b) do { \
|
||||
int diff = (int)ki_swap(b) - (int)ki_swap(a); \
|
||||
if (diff != 0) \
|
||||
return (diff > 0 ? 1 : -1); \
|
||||
} while (0)
|
||||
|
||||
/* compare_cpu - the comparison function for sorting by cpu percentage */
|
||||
|
||||
int
|
||||
@ -1357,6 +1385,7 @@ int (*compares[])() = {
|
||||
compare_vcsw,
|
||||
compare_ivcsw,
|
||||
compare_jid,
|
||||
compare_swap,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -1467,6 +1496,24 @@ compare_jid(const void *arg1, const void *arg2)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* compare_swap - the comparison function for sorting by swap */
|
||||
static int
|
||||
compare_swap(const void *arg1, const void *arg2)
|
||||
{
|
||||
struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1;
|
||||
struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2;
|
||||
|
||||
ORDERKEY_SWAP(p1, p2);
|
||||
ORDERKEY_PCTCPU(p1, p2);
|
||||
ORDERKEY_CPTICKS(p1, p2);
|
||||
ORDERKEY_STATE(p1, p2);
|
||||
ORDERKEY_PRIO(p1, p2);
|
||||
ORDERKEY_RSSIZE(p1, p2);
|
||||
ORDERKEY_MEM(p1, p2);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* ORDER */
|
||||
|
||||
/* assorted comparison functions for sorting by i/o */
|
||||
|
Loading…
Reference in New Issue
Block a user