Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/top/machine.c
Show All 16 Lines | |||||
*/ | */ | ||||
#include <sys/errno.h> | #include <sys/errno.h> | ||||
#include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/priority.h> | #include <sys/priority.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <sys/sbuf.h> | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/user.h> | #include <sys/user.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <kvm.h> | #include <kvm.h> | ||||
#include <math.h> | #include <math.h> | ||||
Show All 11 Lines | |||||
#include "display.h" | #include "display.h" | ||||
#include "machine.h" | #include "machine.h" | ||||
#include "loadavg.h" | #include "loadavg.h" | ||||
#include "screen.h" | #include "screen.h" | ||||
#include "utils.h" | #include "utils.h" | ||||
#include "layout.h" | #include "layout.h" | ||||
#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) | #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) | ||||
#define SMPUNAMELEN 13 | |||||
#define UPUNAMELEN 15 | |||||
extern struct timeval timeout; | extern struct timeval timeout; | ||||
static int smpmode; | static int smpmode; | ||||
enum displaymodes displaymode; | enum displaymodes displaymode; | ||||
static int namelength = 8; | static const int namelength = 10; | ||||
/* TOP_JID_LEN based on max of 999999 */ | /* TOP_JID_LEN based on max of 999999 */ | ||||
#define TOP_JID_LEN 7 | #define TOP_JID_LEN 6 | ||||
#define TOP_SWAP_LEN 6 | #define TOP_SWAP_LEN 5 | ||||
static int jidlength; | |||||
static int swaplength; | |||||
static int cmdlengthdelta; | static int cmdlengthdelta; | ||||
/* get_process_info passes back a handle. This is what it looks like: */ | /* get_process_info passes back a handle. This is what it looks like: */ | ||||
struct handle { | struct handle { | ||||
struct kinfo_proc **next_proc; /* points to next valid proc pointer */ | struct kinfo_proc **next_proc; /* points to next valid proc pointer */ | ||||
int remaining; /* number of pointers remaining */ | int remaining; /* number of pointers remaining */ | ||||
}; | }; | ||||
Show All 15 Lines | |||||
*/ | */ | ||||
static const char io_header[] = | static const char io_header[] = | ||||
" %s%*s %-*.*s VCSW IVCSW READ WRITE FAULT TOTAL PERCENT COMMAND"; | " %s%*s %-*.*s VCSW IVCSW READ WRITE FAULT TOTAL PERCENT COMMAND"; | ||||
static const char io_Proc_format[] = | static const char io_Proc_format[] = | ||||
"%5d%*s %-*.*s %6ld %6ld %6ld %6ld %6ld %6ld %6.2f%% %.*s"; | "%5d%*s %-*.*s %6ld %6ld %6ld %6ld %6ld %6ld %6.2f%% %.*s"; | ||||
/* XXX: build up header instead of statically defining them. | |||||
* This will also allow for a "format string" to be supplied | |||||
* as an argument to top(1) instead of having predefined options */ | |||||
static const char smp_header_thr_and_pid[] = | |||||
" %s%*s %-*.*s THR PRI NICE SIZE RES%*s STATE C TIME %7s COMMAND"; | |||||
static const char smp_header_id_only[] = | |||||
" %s%*s %-*.*s PRI NICE SIZE RES%*s STATE C TIME %7s COMMAND"; | |||||
static const char smp_Proc_format[] = | static const char smp_Proc_format[] = | ||||
"%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s %2d%7s %6.2f%% %.*s"; | "%5d%*s %-*.*s %s%3d %4s%6s %5s%*.*s %-6.6s %2d%7s %6.2f%% %.*s"; | ||||
static char up_header_thr_and_pid[] = | |||||
" %s%*s %-*.*s THR PRI NICE SIZE RES%*s STATE TIME %7s COMMAND"; | |||||
static char up_header_id_only[] = | |||||
" %s%*s %-*.*s PRI NICE SIZE RES%*s STATE TIME %7s COMMAND"; | |||||
static char up_Proc_format[] = | static char up_Proc_format[] = | ||||
"%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s%.0d%7s %6.2f%% %.*s"; | "%5d%*s %-*.*s %s%3d %4s%6s %5s%*.*s %-6.6s%.0d%7s %6.2f%% %.*s"; | ||||
/* process state names for the "STATE" column of the display */ | /* process state names for the "STATE" column of the display */ | ||||
/* the extra nulls in the string "run" are for adding a slash and | /* the extra nulls in the string "run" are for adding a slash and | ||||
the processor number when needed */ | the processor number when needed */ | ||||
static const char *state_abbrev[] = { | static const char *state_abbrev[] = { | ||||
"", "START", "RUN\0\0\0", "SLEEP", "STOP", "ZOMB", "WAIT", "LOCK" | "", "START", "RUN\0\0\0", "SLEEP", "STOP", "ZOMB", "WAIT", "LOCK" | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Lines | if (sysctlbyname("kstat.zfs.misc.arcstats.size", &arc_size, &size, | ||||
NULL, 0) == 0 && arc_size != 0) | NULL, 0) == 0 && arc_size != 0) | ||||
arc_enabled = 1; | arc_enabled = 1; | ||||
size = sizeof(carc_en); | size = sizeof(carc_en); | ||||
if (arc_enabled && | if (arc_enabled && | ||||
sysctlbyname("vfs.zfs.compressed_arc_enabled", &carc_en, &size, | sysctlbyname("vfs.zfs.compressed_arc_enabled", &carc_en, &size, | ||||
NULL, 0) == 0 && carc_en == 1) | NULL, 0) == 0 && carc_en == 1) | ||||
carc_enabled = 1; | carc_enabled = 1; | ||||
namelength = MAXLOGNAME; | |||||
if (smpmode && namelength > SMPUNAMELEN) | |||||
namelength = SMPUNAMELEN; | |||||
else if (namelength > UPUNAMELEN) | |||||
namelength = UPUNAMELEN; | |||||
kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); | kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); | ||||
if (kd == NULL) | if (kd == NULL) | ||||
return (-1); | return (-1); | ||||
GETSYSCTL("kern.ccpu", ccpu); | GETSYSCTL("kern.ccpu", ccpu); | ||||
/* this is used in calculating WCPU -- calculate it ahead of time */ | /* this is used in calculating WCPU -- calculate it ahead of time */ | ||||
logcpu = log(loaddouble(ccpu)); | logcpu = log(loaddouble(ccpu)); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | machine_init(struct statics *statics) | ||||
statics->ncpus = ncpus; | statics->ncpus = ncpus; | ||||
update_layout(); | update_layout(); | ||||
/* all done! */ | /* all done! */ | ||||
return (0); | return (0); | ||||
} | } | ||||
const char * | char * | ||||
format_header(const char *uname_field) | format_header(const char *uname_field) | ||||
{ | { | ||||
static char Header[128]; | static struct sbuf* header = NULL; | ||||
const char *prehead; | |||||
if (ps.jail) | /* clean up from last time. */ | ||||
jidlength = TOP_JID_LEN + 1; /* +1 for extra left space. */ | if (header != NULL) { | ||||
else | sbuf_delete(header); | ||||
jidlength = 0; | } | ||||
header = sbuf_new_auto(); | |||||
if (ps.swap) | |||||
swaplength = TOP_SWAP_LEN + 1; /* +1 for extra left space */ | |||||
else | |||||
swaplength = 0; | |||||
switch (displaymode) { | switch (displaymode) { | ||||
case DISP_CPU: | case DISP_CPU: { | ||||
/* | sbuf_printf(header, " %s", ps.thread_id ? " THR" : "PID"); | ||||
* The logic of picking the right header is confusing, and | sbuf_printf(header, "%*s", ps.jail ? TOP_JID_LEN : 0, | ||||
* depends on too much. We should instead have a struct of | ps.jail ? " JID" : ""); | ||||
* "header name", and "header format" which we build up. | sbuf_printf(header, " %-*.*s", namelength, namelength, uname_field); | ||||
* This would also fix the duplicate of effort into up vs smp | sbuf_cat(header, " THR PRI NICE SIZE RES"); | ||||
* mode. | sbuf_printf(header, "%*s", ps.swap ? TOP_SWAP_LEN : 0, | ||||
*/ | ps.swap ? " SWAP" : ""); | ||||
if (smpmode) { | sbuf_printf(header, "%s", smpmode ? " STATE C " : " STATE "); | ||||
prehead = ps.thread ? | sbuf_cat(header, "TIME"); | ||||
smp_header_id_only : smp_header_thr_and_pid; | sbuf_printf(header, " %7s", ps.wcpu ? "WCPU" : "CPU"); | ||||
snprintf(Header, sizeof(Header), prehead, | sbuf_cat(header, " COMMAND"); | ||||
ps.thread_id ? " THR" : "PID", | sbuf_finish(header); | ||||
jidlength, ps.jail ? " JID" : "", | |||||
namelength, namelength, uname_field, | |||||
swaplength, ps.swap ? " SWAP" : "", | |||||
ps.wcpu ? "WCPU" : "CPU"); | |||||
} else { | |||||
prehead = ps.thread ? | |||||
up_header_id_only : up_header_thr_and_pid; | |||||
snprintf(Header, sizeof(Header), prehead, | |||||
ps.thread_id ? " THR" : "PID", | |||||
jidlength, ps.jail ? " JID" : "", | |||||
namelength, namelength, uname_field, | |||||
swaplength, ps.swap ? " SWAP" : "", | |||||
ps.wcpu ? "WCPU" : "CPU"); | |||||
} | |||||
break; | break; | ||||
case DISP_IO: | } | ||||
prehead = io_header; | case DISP_IO: { | ||||
snprintf(Header, sizeof(Header), prehead, | sbuf_printf(header, io_header, | ||||
ps.thread_id ? " THR" : "PID", | ps.thread_id ? " THR" : "PID", | ||||
jidlength, ps.jail ? " JID" : "", | ps.jail ? TOP_JID_LEN : 0, ps.jail ? " JID" : "", | ||||
namelength, namelength, uname_field); | namelength, namelength, uname_field); | ||||
break; | break; | ||||
} | |||||
case DISP_MAX: | case DISP_MAX: | ||||
assert("displaymode must not be set to DISP_MAX"); | assert("displaymode must not be set to DISP_MAX"); | ||||
} | } | ||||
cmdlengthdelta = strlen(Header) - 7; | |||||
return (Header); | cmdlengthdelta = sbuf_len(header) - 7; | ||||
return sbuf_data(header); | |||||
} | } | ||||
static int swappgsin = -1; | static int swappgsin = -1; | ||||
static int swappgsout = -1; | static int swappgsout = -1; | ||||
void | void | ||||
get_system_info(struct system_info *si) | get_system_info(struct system_info *si) | ||||
▲ Show 20 Lines • Show All 443 Lines • ▼ Show 20 Lines | format_next_process(void* xhandle, char *(*get_userid)(int), int flags) | ||||
struct handle *hp; | struct handle *hp; | ||||
char status[22]; | char status[22]; | ||||
int cpu; | int cpu; | ||||
size_t state; | size_t state; | ||||
struct rusage ru, *rup; | struct rusage ru, *rup; | ||||
long p_tot, s_tot; | long p_tot, s_tot; | ||||
const char *proc_fmt; | const char *proc_fmt; | ||||
char thr_buf[6]; | char thr_buf[6]; | ||||
char jid_buf[TOP_JID_LEN + 1], swap_buf[TOP_SWAP_LEN + 1]; | char jid_buf[TOP_JID_LEN], swap_buf[TOP_SWAP_LEN]; | ||||
char *cmdbuf = NULL; | char *cmdbuf = NULL; | ||||
char **args; | char **args; | ||||
const int cmdlen = 128; | const int cmdlen = 128; | ||||
/* find and remember the next proc structure */ | /* find and remember the next proc structure */ | ||||
hp = (struct handle *)xhandle; | hp = (struct handle *)xhandle; | ||||
pp = *(hp->next_proc++); | pp = *(hp->next_proc++); | ||||
hp->remaining--; | hp->remaining--; | ||||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | if (pp->ki_flag & P_SYSTEM || | ||||
free(argbuf); | free(argbuf); | ||||
} | } | ||||
} | } | ||||
if (ps.jail == 0) | if (ps.jail == 0) | ||||
jid_buf[0] = '\0'; | jid_buf[0] = '\0'; | ||||
else | else | ||||
snprintf(jid_buf, sizeof(jid_buf), "%*d", | snprintf(jid_buf, sizeof(jid_buf), "%*d", | ||||
jidlength - 1, pp->ki_jid); | TOP_JID_LEN - 1, pp->ki_jid); | ||||
if (ps.swap == 0) | if (ps.swap == 0) | ||||
swap_buf[0] = '\0'; | swap_buf[0] = '\0'; | ||||
else | else | ||||
snprintf(swap_buf, sizeof(swap_buf), "%*s", | snprintf(swap_buf, sizeof(swap_buf), "%*s", | ||||
swaplength - 1, | TOP_SWAP_LEN - 1, | ||||
format_k(pagetok(ki_swap(pp)))); /* XXX */ | format_k(pagetok(ki_swap(pp)))); /* XXX */ | ||||
if (displaymode == DISP_IO) { | if (displaymode == DISP_IO) { | ||||
oldp = get_old_proc(pp); | oldp = get_old_proc(pp); | ||||
if (oldp != NULL) { | if (oldp != NULL) { | ||||
ru.ru_inblock = RU(pp)->ru_inblock - | ru.ru_inblock = RU(pp)->ru_inblock - | ||||
RU(oldp)->ru_inblock; | RU(oldp)->ru_inblock; | ||||
ru.ru_oublock = RU(pp)->ru_oublock - | ru.ru_oublock = RU(pp)->ru_oublock - | ||||
RU(oldp)->ru_oublock; | RU(oldp)->ru_oublock; | ||||
ru.ru_majflt = RU(pp)->ru_majflt - RU(oldp)->ru_majflt; | ru.ru_majflt = RU(pp)->ru_majflt - RU(oldp)->ru_majflt; | ||||
ru.ru_nvcsw = RU(pp)->ru_nvcsw - RU(oldp)->ru_nvcsw; | ru.ru_nvcsw = RU(pp)->ru_nvcsw - RU(oldp)->ru_nvcsw; | ||||
ru.ru_nivcsw = RU(pp)->ru_nivcsw - RU(oldp)->ru_nivcsw; | ru.ru_nivcsw = RU(pp)->ru_nivcsw - RU(oldp)->ru_nivcsw; | ||||
rup = &ru; | rup = &ru; | ||||
} else { | } else { | ||||
rup = RU(pp); | rup = RU(pp); | ||||
} | } | ||||
p_tot = rup->ru_inblock + rup->ru_oublock + rup->ru_majflt; | p_tot = rup->ru_inblock + rup->ru_oublock + rup->ru_majflt; | ||||
s_tot = total_inblock + total_oublock + total_majflt; | s_tot = total_inblock + total_oublock + total_majflt; | ||||
snprintf(fmt, sizeof(fmt), io_Proc_format, | snprintf(fmt, sizeof(fmt), io_Proc_format, | ||||
pp->ki_pid, | pp->ki_pid, | ||||
jidlength, jid_buf, | ps.jail ? TOP_JID_LEN : 0, jid_buf, | ||||
namelength, namelength, (*get_userid)(pp->ki_ruid), | namelength, namelength, (*get_userid)(pp->ki_ruid), | ||||
rup->ru_nvcsw, | rup->ru_nvcsw, | ||||
rup->ru_nivcsw, | rup->ru_nivcsw, | ||||
rup->ru_inblock, | rup->ru_inblock, | ||||
rup->ru_oublock, | rup->ru_oublock, | ||||
rup->ru_majflt, | rup->ru_majflt, | ||||
p_tot, | p_tot, | ||||
s_tot == 0 ? 0.0 : (p_tot * 100.0 / s_tot), | s_tot == 0 ? 0.0 : (p_tot * 100.0 / s_tot), | ||||
Show All 16 Lines | if (smpmode) { | ||||
cpu = 0; | cpu = 0; | ||||
proc_fmt = smpmode ? smp_Proc_format : up_Proc_format; | proc_fmt = smpmode ? smp_Proc_format : up_Proc_format; | ||||
if (ps.thread != 0) | if (ps.thread != 0) | ||||
thr_buf[0] = '\0'; | thr_buf[0] = '\0'; | ||||
else | else | ||||
snprintf(thr_buf, sizeof(thr_buf), "%*d ", | snprintf(thr_buf, sizeof(thr_buf), "%*d ", | ||||
(int)(sizeof(thr_buf) - 2), pp->ki_numthreads); | (int)(sizeof(thr_buf) - 2), pp->ki_numthreads); | ||||
snprintf(fmt, sizeof(fmt), proc_fmt, | snprintf(fmt, sizeof(fmt), proc_fmt, | ||||
(ps.thread_id) ? pp->ki_tid : pp->ki_pid, | (ps.thread_id) ? pp->ki_tid : pp->ki_pid, | ||||
jidlength, jid_buf, | ps.jail ? TOP_JID_LEN : 0, jid_buf, | ||||
namelength, namelength, (*get_userid)(pp->ki_ruid), | namelength, namelength, (*get_userid)(pp->ki_ruid), | ||||
thr_buf, | thr_buf, | ||||
pp->ki_pri.pri_level - PZERO, | pp->ki_pri.pri_level - PZERO, | ||||
format_nice(pp), | format_nice(pp), | ||||
format_k(PROCSIZE(pp)), | format_k(PROCSIZE(pp)), | ||||
format_k(pagetok(pp->ki_rssize)), | format_k(pagetok(pp->ki_rssize)), | ||||
swaplength, swaplength, swap_buf, | ps.swap ? TOP_SWAP_LEN : 0, ps.swap ? TOP_SWAP_LEN : 0, swap_buf, | ||||
status, | status, | ||||
cpu, | cpu, | ||||
format_time(cputime), | format_time(cputime), | ||||
ps.wcpu ? 100.0 * weighted_cpu(pct, pp) : 100.0 * pct, | ps.wcpu ? 100.0 * weighted_cpu(pct, pp) : 100.0 * pct, | ||||
screen_width > cmdlengthdelta ? screen_width - cmdlengthdelta : 0, | screen_width > cmdlengthdelta ? screen_width - cmdlengthdelta : 0, | ||||
printable(cmdbuf)); | printable(cmdbuf)); | ||||
free(cmdbuf); | free(cmdbuf); | ||||
▲ Show 20 Lines • Show All 477 Lines • Show Last 20 Lines |