xref: /dragonfly/usr.bin/top/m_dragonfly.c (revision 7a491db4)
17af1b2bcSJan Lentfer /*
27af1b2bcSJan Lentfer  * top - a top users display for Unix
37af1b2bcSJan Lentfer  *
47af1b2bcSJan Lentfer  * SYNOPSIS:  For DragonFly 2.x and later
57af1b2bcSJan Lentfer  *
67af1b2bcSJan Lentfer  * DESCRIPTION:
77af1b2bcSJan Lentfer  * Originally written for BSD4.4 system by Christos Zoulas.
87af1b2bcSJan Lentfer  * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider
97af1b2bcSJan Lentfer  * Order support hacked in from top-3.5beta6/machine/m_aix41.c
107af1b2bcSJan Lentfer  *   by Monte Mitzelfelt (for latest top see http://www.groupsys.com/topinfo/)
117af1b2bcSJan Lentfer  *
127af1b2bcSJan Lentfer  * This is the machine-dependent module for DragonFly 2.5.1
137af1b2bcSJan Lentfer  * Should work for:
147af1b2bcSJan Lentfer  *	DragonFly 2.x and above
157af1b2bcSJan Lentfer  *
167af1b2bcSJan Lentfer  * LIBS: -lkvm
177af1b2bcSJan Lentfer  *
187af1b2bcSJan Lentfer  * AUTHOR: Jan Lentfer <Jan.Lentfer@web.de>
197af1b2bcSJan Lentfer  * This module has been put together from different sources and is based on the
207af1b2bcSJan Lentfer  * work of many other people, e.g. Matthew Dillon, Simon Schubert, Jordan Gordeev.
217af1b2bcSJan Lentfer  *
227af1b2bcSJan Lentfer  * $FreeBSD: src/usr.bin/top/machine.c,v 1.29.2.2 2001/07/31 20:27:05 tmm Exp $
237af1b2bcSJan Lentfer  */
247af1b2bcSJan Lentfer 
25e0ecab34SMatthew Dillon #include <sys/user.h>
267af1b2bcSJan Lentfer #include <sys/types.h>
27e0ecab34SMatthew Dillon #include <sys/time.h>
287af1b2bcSJan Lentfer #include <sys/signal.h>
297af1b2bcSJan Lentfer #include <sys/param.h>
307af1b2bcSJan Lentfer 
317af1b2bcSJan Lentfer #include "os.h"
327af1b2bcSJan Lentfer #include <err.h>
332c3b1d1bSSascha Wildner #include <fcntl.h>
347af1b2bcSJan Lentfer #include <kvm.h>
357af1b2bcSJan Lentfer #include <stdio.h>
367af1b2bcSJan Lentfer #include <unistd.h>
377af1b2bcSJan Lentfer #include <math.h>
387af1b2bcSJan Lentfer #include <pwd.h>
397af1b2bcSJan Lentfer #include <sys/errno.h>
407af1b2bcSJan Lentfer #include <sys/sysctl.h>
417af1b2bcSJan Lentfer #include <sys/vmmeter.h>
427af1b2bcSJan Lentfer #include <sys/resource.h>
437af1b2bcSJan Lentfer #include <sys/rtprio.h>
447af1b2bcSJan Lentfer 
457af1b2bcSJan Lentfer /* Swap */
467af1b2bcSJan Lentfer #include <stdlib.h>
47b5121966SSepherosa Ziehau #include <string.h>
487af1b2bcSJan Lentfer #include <sys/conf.h>
497af1b2bcSJan Lentfer 
507af1b2bcSJan Lentfer #include <osreldate.h>		/* for changes in kernel structures */
517af1b2bcSJan Lentfer 
527af1b2bcSJan Lentfer #include <sys/kinfo.h>
537af1b2bcSJan Lentfer #include <kinfo.h>
547af1b2bcSJan Lentfer #include "top.h"
557af1b2bcSJan Lentfer #include "display.h"
567af1b2bcSJan Lentfer #include "machine.h"
577af1b2bcSJan Lentfer #include "screen.h"
587af1b2bcSJan Lentfer #include "utils.h"
597af1b2bcSJan Lentfer 
607af1b2bcSJan Lentfer int swapmode(int *retavail, int *retfree);
617af1b2bcSJan Lentfer static int namelength;
627af1b2bcSJan Lentfer static int cmdlength;
63efde5811SJan Lentfer static int show_fullcmd;
647af1b2bcSJan Lentfer 
658ea225a8SSascha Wildner int n_cpus, enable_ncpus;
667af1b2bcSJan Lentfer 
677af1b2bcSJan Lentfer /* get_process_info passes back a handle.  This is what it looks like: */
687af1b2bcSJan Lentfer 
69961f1f09SJan Lentfer struct handle {
707af1b2bcSJan Lentfer 	struct kinfo_proc **next_proc;	/* points to next valid proc pointer */
717af1b2bcSJan Lentfer 	int remaining;		/* number of pointers remaining */
720ca59c34SSepherosa Ziehau 	int show_threads;
737af1b2bcSJan Lentfer };
747af1b2bcSJan Lentfer 
757af1b2bcSJan Lentfer /* declarations for load_avg */
767af1b2bcSJan Lentfer #include "loadavg.h"
777af1b2bcSJan Lentfer 
787af1b2bcSJan Lentfer #define PP(pp, field) ((pp)->kp_ ## field)
797af1b2bcSJan Lentfer #define LP(pp, field) ((pp)->kp_lwp.kl_ ## field)
807af1b2bcSJan Lentfer #define VP(pp, field) ((pp)->kp_vm_ ## field)
817af1b2bcSJan Lentfer 
827af1b2bcSJan Lentfer /* what we consider to be process size: */
837af1b2bcSJan Lentfer #define PROCSIZE(pp) (VP((pp), map_size) / 1024)
847af1b2bcSJan Lentfer 
857af1b2bcSJan Lentfer /*
867af1b2bcSJan Lentfer  * These definitions control the format of the per-process area
877af1b2bcSJan Lentfer  */
887af1b2bcSJan Lentfer 
897af1b2bcSJan Lentfer static char smp_header[] =
90c61c17edSSepherosa Ziehau "   PID %-*.*s NICE  SIZE    RES    STATE   C   TIME   CTIME    CPU COMMAND";
917af1b2bcSJan Lentfer 
927af1b2bcSJan Lentfer #define smp_Proc_format \
93c61c17edSSepherosa Ziehau 	"%6d %-*.*s %3d%7s %6s %8.8s %3d %6s %7s %5.2f%% %.*s"
947af1b2bcSJan Lentfer 
957af1b2bcSJan Lentfer 
967af1b2bcSJan Lentfer static kvm_t *kd;
977af1b2bcSJan Lentfer 
987af1b2bcSJan Lentfer /* values that we stash away in _init and use in later routines */
997af1b2bcSJan Lentfer 
1007af1b2bcSJan Lentfer static long lastpid;
1017af1b2bcSJan Lentfer 
1027af1b2bcSJan Lentfer /* these are for calculating cpu state percentages */
1037af1b2bcSJan Lentfer 
1047af1b2bcSJan Lentfer static struct kinfo_cputime *cp_time, *cp_old;
1057af1b2bcSJan Lentfer 
1067af1b2bcSJan Lentfer /* these are for detailing the process states */
1077af1b2bcSJan Lentfer 
10823c5b3d5SAaron LI enum {
10923c5b3d5SAaron LI 	PS_STARTING = 0,
11023c5b3d5SAaron LI 	PS_RUNNING,
11123c5b3d5SAaron LI 	PS_STOPPED,
11223c5b3d5SAaron LI 	PS_SLEEPING,
11323c5b3d5SAaron LI 	PS_ZOMBIE,
114*7a491db4SAaron LI 	PS_DUMPING,
11523c5b3d5SAaron LI 	PS_MAX,
11623c5b3d5SAaron LI };
117d6eee517SMatthew Dillon 
11823c5b3d5SAaron LI int process_states[PS_MAX + 1];
1197af1b2bcSJan Lentfer char *procstatenames[] = {
12023c5b3d5SAaron LI 	[PS_STARTING]	= " starting, ",
12123c5b3d5SAaron LI 	[PS_RUNNING]	= " running, ",
12223c5b3d5SAaron LI 	[PS_STOPPED]	= " stopped, ",
12323c5b3d5SAaron LI 	[PS_SLEEPING]	= " sleeping, ",
12423c5b3d5SAaron LI 	[PS_ZOMBIE]	= " zombie, ",
125*7a491db4SAaron LI 	[PS_DUMPING]	= " dumping, ",
12623c5b3d5SAaron LI 	[PS_MAX]	= NULL,
1277af1b2bcSJan Lentfer };
1287af1b2bcSJan Lentfer 
1298c086bfbSAaron LI /* process state names for the "STATE" column of the display */
1308c086bfbSAaron LI const char *state_abbrev[] = {
1318c086bfbSAaron LI 	[PS_STARTING]	= "START",
1328c086bfbSAaron LI 	[PS_RUNNING]	= "RUN",
1338c086bfbSAaron LI 	[PS_STOPPED]	= "STOP",
1348c086bfbSAaron LI 	[PS_SLEEPING]	= "SLEEP",
1358c086bfbSAaron LI 	[PS_ZOMBIE]	= "ZOMBIE",
136*7a491db4SAaron LI 	[PS_DUMPING]	= "DUMP",
1378c086bfbSAaron LI 	[PS_MAX]	= NULL,
1388c086bfbSAaron LI };
1398c086bfbSAaron LI 
1407af1b2bcSJan Lentfer /* these are for detailing the cpu states */
1417af1b2bcSJan Lentfer #define CPU_STATES 5
1427af1b2bcSJan Lentfer int *cpu_states;
143edc735acSJavier Alcázar int* cpu_averages;
1447af1b2bcSJan Lentfer char *cpustatenames[CPU_STATES + 1] = {
1457af1b2bcSJan Lentfer 	"user", "nice", "system", "interrupt", "idle", NULL
1467af1b2bcSJan Lentfer };
1477af1b2bcSJan Lentfer 
1487af1b2bcSJan Lentfer /* these are for detailing the memory statistics */
1497af1b2bcSJan Lentfer 
1507af1b2bcSJan Lentfer long memory_stats[7];
1517af1b2bcSJan Lentfer char *memorynames[] = {
1527af1b2bcSJan Lentfer 	"K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free",
1537af1b2bcSJan Lentfer 	NULL
1547af1b2bcSJan Lentfer };
1557af1b2bcSJan Lentfer 
1567af1b2bcSJan Lentfer long swap_stats[7];
1577af1b2bcSJan Lentfer char *swapnames[] = {
1587af1b2bcSJan Lentfer 	/* 0           1            2           3            4       5 */
1597af1b2bcSJan Lentfer 	"K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out",
1607af1b2bcSJan Lentfer 	NULL
1617af1b2bcSJan Lentfer };
1627af1b2bcSJan Lentfer 
1637af1b2bcSJan Lentfer 
1647af1b2bcSJan Lentfer /* these are for keeping track of the proc array */
1657af1b2bcSJan Lentfer 
1667af1b2bcSJan Lentfer static int nproc;
1677af1b2bcSJan Lentfer static int onproc = -1;
1687af1b2bcSJan Lentfer static int pref_len;
1697af1b2bcSJan Lentfer static struct kinfo_proc *pbase;
1707af1b2bcSJan Lentfer static struct kinfo_proc **pref;
1717af1b2bcSJan Lentfer 
172b5121966SSepherosa Ziehau static uint64_t prev_pbase_time;	/* unit: us */
173b5121966SSepherosa Ziehau static struct kinfo_proc *prev_pbase;
17476ccf3d0SSepherosa Ziehau static int prev_pbase_alloc;
17576ccf3d0SSepherosa Ziehau static int prev_nproc;
176b5121966SSepherosa Ziehau static int fscale;
177b5121966SSepherosa Ziehau 
1787af1b2bcSJan Lentfer /* these are for getting the memory statistics */
1797af1b2bcSJan Lentfer 
1807af1b2bcSJan Lentfer static int pageshift;		/* log base 2 of the pagesize */
1817af1b2bcSJan Lentfer 
1827af1b2bcSJan Lentfer /* define pagetok in terms of pageshift */
1837af1b2bcSJan Lentfer 
1847af1b2bcSJan Lentfer #define pagetok(size) ((size) << pageshift)
1857af1b2bcSJan Lentfer 
1867af1b2bcSJan Lentfer /* sorting orders. first is default */
1877af1b2bcSJan Lentfer char *ordernames[] = {
18850a55c46SMatthew Dillon   "cpu", "size", "res", "time", "pri", "thr", "pid", "ctime",  "pres", NULL
1897af1b2bcSJan Lentfer };
1907af1b2bcSJan Lentfer 
1917af1b2bcSJan Lentfer /* compare routines */
1928b72b421SJan Lentfer int proc_compare (struct kinfo_proc **, struct kinfo_proc **);
1938b72b421SJan Lentfer int compare_size (struct kinfo_proc **, struct kinfo_proc **);
1948b72b421SJan Lentfer int compare_res (struct kinfo_proc **, struct kinfo_proc **);
1958b72b421SJan Lentfer int compare_time (struct kinfo_proc **, struct kinfo_proc **);
196bcd4a7c1SJan Lentfer int compare_ctime (struct kinfo_proc **, struct kinfo_proc **);
1978b72b421SJan Lentfer int compare_prio(struct kinfo_proc **, struct kinfo_proc **);
1988b72b421SJan Lentfer int compare_thr (struct kinfo_proc **, struct kinfo_proc **);
1998b72b421SJan Lentfer int compare_pid (struct kinfo_proc **, struct kinfo_proc **);
20050a55c46SMatthew Dillon int compare_pres(struct kinfo_proc **, struct kinfo_proc **);
2017af1b2bcSJan Lentfer 
2028b72b421SJan Lentfer int (*proc_compares[]) (struct kinfo_proc **,struct kinfo_proc **) = {
2037af1b2bcSJan Lentfer 	proc_compare,
2047af1b2bcSJan Lentfer 	compare_size,
2057af1b2bcSJan Lentfer 	compare_res,
2067af1b2bcSJan Lentfer 	compare_time,
2077af1b2bcSJan Lentfer 	compare_prio,
2088b72b421SJan Lentfer 	compare_thr,
2098b72b421SJan Lentfer 	compare_pid,
210bcd4a7c1SJan Lentfer 	compare_ctime,
21150a55c46SMatthew Dillon 	compare_pres,
2127af1b2bcSJan Lentfer 	NULL
2137af1b2bcSJan Lentfer };
2147af1b2bcSJan Lentfer 
2157af1b2bcSJan Lentfer static void
cputime_percentages(int out[CPU_STATES],struct kinfo_cputime * new,struct kinfo_cputime * old)2167af1b2bcSJan Lentfer cputime_percentages(int out[CPU_STATES], struct kinfo_cputime *new,
2177af1b2bcSJan Lentfer     struct kinfo_cputime *old)
2187af1b2bcSJan Lentfer {
2197af1b2bcSJan Lentfer 	struct kinfo_cputime diffs;
2207af1b2bcSJan Lentfer 	uint64_t total_change, half_total;
2217af1b2bcSJan Lentfer 
2227af1b2bcSJan Lentfer 	/* initialization */
2237af1b2bcSJan Lentfer 	total_change = 0;
2247af1b2bcSJan Lentfer 
2257af1b2bcSJan Lentfer 	diffs.cp_user = new->cp_user - old->cp_user;
2267af1b2bcSJan Lentfer 	diffs.cp_nice = new->cp_nice - old->cp_nice;
2277af1b2bcSJan Lentfer 	diffs.cp_sys = new->cp_sys - old->cp_sys;
2287af1b2bcSJan Lentfer 	diffs.cp_intr = new->cp_intr - old->cp_intr;
2297af1b2bcSJan Lentfer 	diffs.cp_idle = new->cp_idle - old->cp_idle;
2307af1b2bcSJan Lentfer 	total_change = diffs.cp_user + diffs.cp_nice + diffs.cp_sys +
2317af1b2bcSJan Lentfer 	    diffs.cp_intr + diffs.cp_idle;
2327af1b2bcSJan Lentfer 	old->cp_user = new->cp_user;
2337af1b2bcSJan Lentfer 	old->cp_nice = new->cp_nice;
2347af1b2bcSJan Lentfer 	old->cp_sys = new->cp_sys;
2357af1b2bcSJan Lentfer 	old->cp_intr = new->cp_intr;
2367af1b2bcSJan Lentfer 	old->cp_idle = new->cp_idle;
2377af1b2bcSJan Lentfer 
2387af1b2bcSJan Lentfer 	/* avoid divide by zero potential */
2397af1b2bcSJan Lentfer 	if (total_change == 0)
2407af1b2bcSJan Lentfer 		total_change = 1;
2417af1b2bcSJan Lentfer 
2427af1b2bcSJan Lentfer 	/* calculate percentages based on overall change, rounding up */
2437af1b2bcSJan Lentfer 	half_total = total_change >> 1;
2447af1b2bcSJan Lentfer 
2457af1b2bcSJan Lentfer 	out[0] = ((diffs.cp_user * 1000LL + half_total) / total_change);
2467af1b2bcSJan Lentfer 	out[1] = ((diffs.cp_nice * 1000LL + half_total) / total_change);
2477af1b2bcSJan Lentfer 	out[2] = ((diffs.cp_sys * 1000LL + half_total) / total_change);
2487af1b2bcSJan Lentfer 	out[3] = ((diffs.cp_intr * 1000LL + half_total) / total_change);
2497af1b2bcSJan Lentfer 	out[4] = ((diffs.cp_idle * 1000LL + half_total) / total_change);
2507af1b2bcSJan Lentfer }
2517af1b2bcSJan Lentfer 
2527af1b2bcSJan Lentfer int
machine_init(struct statics * statics)2537af1b2bcSJan Lentfer machine_init(struct statics *statics)
2547af1b2bcSJan Lentfer {
2557af1b2bcSJan Lentfer 	int pagesize;
256da0d35cfSMatthew Dillon 	size_t prmlen;
2577af1b2bcSJan Lentfer 	struct passwd *pw;
2587af1b2bcSJan Lentfer 
2597af1b2bcSJan Lentfer 	if (n_cpus < 1) {
2607af1b2bcSJan Lentfer 		if (kinfo_get_cpus(&n_cpus))
2617af1b2bcSJan Lentfer 			err(1, "kinfo_get_cpus failed");
2627af1b2bcSJan Lentfer 	}
2637af1b2bcSJan Lentfer 	/* get boot time */
2647af1b2bcSJan Lentfer 
265b5121966SSepherosa Ziehau 	prmlen = sizeof(fscale);
266b5121966SSepherosa Ziehau 	if (sysctlbyname("kern.fscale", &fscale, &prmlen, NULL, 0) == -1)
26776ccf3d0SSepherosa Ziehau 		err(1, "sysctl kern.fscale failed");
268b5121966SSepherosa Ziehau 
2697af1b2bcSJan Lentfer 	while ((pw = getpwent()) != NULL) {
2707af1b2bcSJan Lentfer 		if ((int)strlen(pw->pw_name) > namelength)
2717af1b2bcSJan Lentfer 			namelength = strlen(pw->pw_name);
2727af1b2bcSJan Lentfer 	}
2737af1b2bcSJan Lentfer 	if (namelength < 8)
2747af1b2bcSJan Lentfer 		namelength = 8;
275975fc636SSascha Wildner 	if (namelength > 13)
2767af1b2bcSJan Lentfer 		namelength = 13;
2777af1b2bcSJan Lentfer 
278efde5811SJan Lentfer 	if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
2797af1b2bcSJan Lentfer 		return -1;
2807af1b2bcSJan Lentfer 
2817af1b2bcSJan Lentfer 	pbase = NULL;
2827af1b2bcSJan Lentfer 	pref = NULL;
2837af1b2bcSJan Lentfer 	nproc = 0;
2847af1b2bcSJan Lentfer 	onproc = -1;
285b5121966SSepherosa Ziehau 	prev_pbase = NULL;
28676ccf3d0SSepherosa Ziehau 	prev_pbase_alloc = 0;
28776ccf3d0SSepherosa Ziehau 	prev_pbase_time = 0;
28876ccf3d0SSepherosa Ziehau 	prev_nproc = 0;
289961f1f09SJan Lentfer 	/*
290961f1f09SJan Lentfer 	 * get the page size with "getpagesize" and calculate pageshift from
291961f1f09SJan Lentfer 	 * it
292961f1f09SJan Lentfer 	 */
2937af1b2bcSJan Lentfer 	pagesize = getpagesize();
2947af1b2bcSJan Lentfer 	pageshift = 0;
295961f1f09SJan Lentfer 	while (pagesize > 1) {
2967af1b2bcSJan Lentfer 		pageshift++;
2977af1b2bcSJan Lentfer 		pagesize >>= 1;
2987af1b2bcSJan Lentfer 	}
2997af1b2bcSJan Lentfer 
3007af1b2bcSJan Lentfer 	/* we only need the amount of log(2)1024 for our conversion */
3017af1b2bcSJan Lentfer 	pageshift -= LOG1024;
3027af1b2bcSJan Lentfer 
3037af1b2bcSJan Lentfer 	/* fill in the statics information */
3047af1b2bcSJan Lentfer 	statics->procstate_names = procstatenames;
3057af1b2bcSJan Lentfer 	statics->cpustate_names = cpustatenames;
3067af1b2bcSJan Lentfer 	statics->memory_names = memorynames;
307da0d35cfSMatthew Dillon 	statics->unused01 = 0;
3087af1b2bcSJan Lentfer 	statics->swap_names = swapnames;
3097af1b2bcSJan Lentfer 	statics->order_names = ordernames;
310efde5811SJan Lentfer 	/* we need kvm descriptor in order to show full commands */
311efde5811SJan Lentfer 	statics->flags.fullcmds = kd != NULL;
312cb68a542SAntonio Nikishaev 	statics->flags.threads = 1;
3137af1b2bcSJan Lentfer 
3147af1b2bcSJan Lentfer 	/* all done! */
3157af1b2bcSJan Lentfer 	return (0);
3167af1b2bcSJan Lentfer }
3177af1b2bcSJan Lentfer 
3187af1b2bcSJan Lentfer char *
format_header(char * uname_field)3197af1b2bcSJan Lentfer format_header(char *uname_field)
3207af1b2bcSJan Lentfer {
3217af1b2bcSJan Lentfer 	static char Header[128];
3227af1b2bcSJan Lentfer 
323975fc636SSascha Wildner 	snprintf(Header, sizeof(Header), smp_header,
3247af1b2bcSJan Lentfer 	    namelength, namelength, uname_field);
3257af1b2bcSJan Lentfer 
3267af1b2bcSJan Lentfer 	if (screen_width <= 79)
3277af1b2bcSJan Lentfer 		cmdlength = 80;
3287af1b2bcSJan Lentfer 	else
3298b72b421SJan Lentfer 		cmdlength = screen_width;
3307af1b2bcSJan Lentfer 
3317af1b2bcSJan Lentfer 	cmdlength = cmdlength - strlen(Header) + 6;
3327af1b2bcSJan Lentfer 
3337af1b2bcSJan Lentfer 	return Header;
3347af1b2bcSJan Lentfer }
3357af1b2bcSJan Lentfer 
3367af1b2bcSJan Lentfer static int swappgsin = -1;
3377af1b2bcSJan Lentfer static int swappgsout = -1;
3387af1b2bcSJan Lentfer extern struct timeval timeout;
3397af1b2bcSJan Lentfer 
3407af1b2bcSJan Lentfer void
get_system_info(struct system_info * si)3417af1b2bcSJan Lentfer get_system_info(struct system_info *si)
3427af1b2bcSJan Lentfer {
3437af1b2bcSJan Lentfer 	size_t len;
3447af1b2bcSJan Lentfer 	int cpu;
3457af1b2bcSJan Lentfer 
3467af1b2bcSJan Lentfer 	if (cpu_states == NULL) {
3477af1b2bcSJan Lentfer 		cpu_states = malloc(sizeof(*cpu_states) * CPU_STATES * n_cpus);
3487af1b2bcSJan Lentfer 		if (cpu_states == NULL)
3497af1b2bcSJan Lentfer 			err(1, "malloc");
3507af1b2bcSJan Lentfer 		bzero(cpu_states, sizeof(*cpu_states) * CPU_STATES * n_cpus);
3517af1b2bcSJan Lentfer 	}
3527af1b2bcSJan Lentfer 	if (cp_time == NULL) {
3537af1b2bcSJan Lentfer 		cp_time = malloc(2 * n_cpus * sizeof(cp_time[0]));
3547af1b2bcSJan Lentfer 		if (cp_time == NULL)
3557af1b2bcSJan Lentfer 			err(1, "cp_time");
3567af1b2bcSJan Lentfer 		cp_old = cp_time + n_cpus;
3577af1b2bcSJan Lentfer 		len = n_cpus * sizeof(cp_old[0]);
3587af1b2bcSJan Lentfer 		bzero(cp_time, len);
3597af1b2bcSJan Lentfer 		if (sysctlbyname("kern.cputime", cp_old, &len, NULL, 0))
3607af1b2bcSJan Lentfer 			err(1, "kern.cputime");
3617af1b2bcSJan Lentfer 	}
3627af1b2bcSJan Lentfer 	len = n_cpus * sizeof(cp_time[0]);
3637af1b2bcSJan Lentfer 	bzero(cp_time, len);
3647af1b2bcSJan Lentfer 	if (sysctlbyname("kern.cputime", cp_time, &len, NULL, 0))
3657af1b2bcSJan Lentfer 		err(1, "kern.cputime");
3667af1b2bcSJan Lentfer 
3677af1b2bcSJan Lentfer 	getloadavg(si->load_avg, 3);
3687af1b2bcSJan Lentfer 
3697af1b2bcSJan Lentfer 	lastpid = 0;
3707af1b2bcSJan Lentfer 
3717af1b2bcSJan Lentfer 	/* convert cp_time counts to percentages */
372edc735acSJavier Alcázar 	int combine_cpus = (enable_ncpus == 0 && n_cpus > 1);
3737af1b2bcSJan Lentfer 	for (cpu = 0; cpu < n_cpus; ++cpu) {
3747af1b2bcSJan Lentfer 		cputime_percentages(cpu_states + cpu * CPU_STATES,
3757af1b2bcSJan Lentfer 		    &cp_time[cpu], &cp_old[cpu]);
3767af1b2bcSJan Lentfer 	}
377edc735acSJavier Alcázar 	if (combine_cpus) {
378edc735acSJavier Alcázar 		if (cpu_averages == NULL) {
379edc735acSJavier Alcázar 			cpu_averages = malloc(sizeof(*cpu_averages) * CPU_STATES);
380edc735acSJavier Alcázar 			if (cpu_averages == NULL)
381edc735acSJavier Alcázar 				err(1, "cpu_averages");
382edc735acSJavier Alcázar 		}
383edc735acSJavier Alcázar 		bzero(cpu_averages, sizeof(*cpu_averages) * CPU_STATES);
384edc735acSJavier Alcázar 		for (cpu = 0; cpu < n_cpus; ++cpu) {
385edc735acSJavier Alcázar 			int j = 0;
386edc735acSJavier Alcázar 			cpu_averages[0] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
387edc735acSJavier Alcázar 			cpu_averages[1] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
388edc735acSJavier Alcázar 			cpu_averages[2] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
389edc735acSJavier Alcázar 			cpu_averages[3] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
390edc735acSJavier Alcázar 			cpu_averages[4] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
391edc735acSJavier Alcázar 		}
392edc735acSJavier Alcázar 		for (int i = 0; i < CPU_STATES; ++i)
393edc735acSJavier Alcázar 			cpu_averages[i] /= n_cpus;
394edc735acSJavier Alcázar 	}
3957af1b2bcSJan Lentfer 
3967af1b2bcSJan Lentfer 	/* sum memory & swap statistics */
3977af1b2bcSJan Lentfer 	{
3987af1b2bcSJan Lentfer 		struct vmmeter vmm;
3997af1b2bcSJan Lentfer 		struct vmstats vms;
4007af1b2bcSJan Lentfer 		size_t vms_size = sizeof(vms);
4017af1b2bcSJan Lentfer 		size_t vmm_size = sizeof(vmm);
4027af1b2bcSJan Lentfer 		static unsigned int swap_delay = 0;
4037af1b2bcSJan Lentfer 		static int swapavail = 0;
4047af1b2bcSJan Lentfer 		static int swapfree = 0;
4053583bbb4SMatthew Dillon 		static long bufspace = 0;
4067af1b2bcSJan Lentfer 
4077af1b2bcSJan Lentfer 		if (sysctlbyname("vm.vmstats", &vms, &vms_size, NULL, 0))
4087af1b2bcSJan Lentfer 			err(1, "sysctlbyname: vm.vmstats");
4097af1b2bcSJan Lentfer 
4107af1b2bcSJan Lentfer 		if (sysctlbyname("vm.vmmeter", &vmm, &vmm_size, NULL, 0))
4117af1b2bcSJan Lentfer 			err(1, "sysctlbyname: vm.vmmeter");
4127af1b2bcSJan Lentfer 
4137af1b2bcSJan Lentfer 		if (kinfo_get_vfs_bufspace(&bufspace))
4147af1b2bcSJan Lentfer 			err(1, "kinfo_get_vfs_bufspace");
4157af1b2bcSJan Lentfer 
4167af1b2bcSJan Lentfer 		/* convert memory stats to Kbytes */
4177af1b2bcSJan Lentfer 		memory_stats[0] = pagetok(vms.v_active_count);
4187af1b2bcSJan Lentfer 		memory_stats[1] = pagetok(vms.v_inactive_count);
4197af1b2bcSJan Lentfer 		memory_stats[2] = pagetok(vms.v_wire_count);
4207af1b2bcSJan Lentfer 		memory_stats[3] = pagetok(vms.v_cache_count);
4217af1b2bcSJan Lentfer 		memory_stats[4] = bufspace / 1024;
4227af1b2bcSJan Lentfer 		memory_stats[5] = pagetok(vms.v_free_count);
4237af1b2bcSJan Lentfer 		memory_stats[6] = -1;
4247af1b2bcSJan Lentfer 
4257af1b2bcSJan Lentfer 		/* first interval */
4267af1b2bcSJan Lentfer 		if (swappgsin < 0) {
4277af1b2bcSJan Lentfer 			swap_stats[4] = 0;
4287af1b2bcSJan Lentfer 			swap_stats[5] = 0;
4297af1b2bcSJan Lentfer 		}
4307af1b2bcSJan Lentfer 		/* compute differences between old and new swap statistic */
4317af1b2bcSJan Lentfer 		else {
4327af1b2bcSJan Lentfer 			swap_stats[4] = pagetok(((vmm.v_swappgsin - swappgsin)));
4337af1b2bcSJan Lentfer 			swap_stats[5] = pagetok(((vmm.v_swappgsout - swappgsout)));
4347af1b2bcSJan Lentfer 		}
4357af1b2bcSJan Lentfer 
4367af1b2bcSJan Lentfer 		swappgsin = vmm.v_swappgsin;
4377af1b2bcSJan Lentfer 		swappgsout = vmm.v_swappgsout;
4387af1b2bcSJan Lentfer 
4397af1b2bcSJan Lentfer 		/* call CPU heavy swapmode() only for changes */
4407af1b2bcSJan Lentfer 		if (swap_stats[4] > 0 || swap_stats[5] > 0 || swap_delay == 0) {
4417af1b2bcSJan Lentfer 			swap_stats[3] = swapmode(&swapavail, &swapfree);
4427af1b2bcSJan Lentfer 			swap_stats[0] = swapavail;
4437af1b2bcSJan Lentfer 			swap_stats[1] = swapavail - swapfree;
4447af1b2bcSJan Lentfer 			swap_stats[2] = swapfree;
4457af1b2bcSJan Lentfer 		}
4467af1b2bcSJan Lentfer 		swap_delay = 1;
4477af1b2bcSJan Lentfer 		swap_stats[6] = -1;
4487af1b2bcSJan Lentfer 	}
4497af1b2bcSJan Lentfer 
4507af1b2bcSJan Lentfer 	/* set arrays and strings */
451edc735acSJavier Alcázar 	si->cpustates = combine_cpus == 1 ?
452edc735acSJavier Alcázar 	    cpu_averages : cpu_states;
4537af1b2bcSJan Lentfer 	si->memory = memory_stats;
4547af1b2bcSJan Lentfer 	si->swap = swap_stats;
4557af1b2bcSJan Lentfer 
4567af1b2bcSJan Lentfer 
4577af1b2bcSJan Lentfer 	if (lastpid > 0) {
4587af1b2bcSJan Lentfer 		si->last_pid = lastpid;
4597af1b2bcSJan Lentfer 	} else {
4607af1b2bcSJan Lentfer 		si->last_pid = -1;
4617af1b2bcSJan Lentfer 	}
4627af1b2bcSJan Lentfer }
4637af1b2bcSJan Lentfer 
4647af1b2bcSJan Lentfer 
4657af1b2bcSJan Lentfer static struct handle handle;
4667af1b2bcSJan Lentfer 
467b5121966SSepherosa Ziehau static void
fixup_pctcpu(struct kinfo_proc * fixit,uint64_t d)46876ccf3d0SSepherosa Ziehau fixup_pctcpu(struct kinfo_proc *fixit, uint64_t d)
469b5121966SSepherosa Ziehau {
470b5121966SSepherosa Ziehau 	struct kinfo_proc *pp;
47176ccf3d0SSepherosa Ziehau 	uint64_t ticks;
472685dc2e1SSepherosa Ziehau 	int i;
473b5121966SSepherosa Ziehau 
47476ccf3d0SSepherosa Ziehau 	if (prev_nproc == 0 || d == 0)
475b5121966SSepherosa Ziehau 		return;
476b5121966SSepherosa Ziehau 
47776ccf3d0SSepherosa Ziehau 	if (LP(fixit, pid) == -1) {
47876ccf3d0SSepherosa Ziehau 		/* Skip kernel "idle" threads */
47976ccf3d0SSepherosa Ziehau 		if (PP(fixit, stat) == SIDL)
48076ccf3d0SSepherosa Ziehau 			return;
481b5121966SSepherosa Ziehau 		for (pp = prev_pbase, i = 0; i < prev_nproc; pp++, i++) {
48276ccf3d0SSepherosa Ziehau 			if (LP(pp, pid) == -1 &&
48376ccf3d0SSepherosa Ziehau 			    PP(pp, ktaddr) == PP(fixit, ktaddr))
48476ccf3d0SSepherosa Ziehau 				break;
48576ccf3d0SSepherosa Ziehau 		}
48676ccf3d0SSepherosa Ziehau 	} else {
48776ccf3d0SSepherosa Ziehau 		for (pp = prev_pbase, i = 0; i < prev_nproc; pp++, i++) {
48876ccf3d0SSepherosa Ziehau 			if (LP(pp, pid) == LP(fixit, pid) &&
48976ccf3d0SSepherosa Ziehau 			    LP(pp, tid) == LP(fixit, tid)) {
49076ccf3d0SSepherosa Ziehau 				if (PP(pp, paddr) != PP(fixit, paddr)) {
49176ccf3d0SSepherosa Ziehau 					/* pid/tid are reused */
49276ccf3d0SSepherosa Ziehau 					pp = NULL;
49376ccf3d0SSepherosa Ziehau 				}
494b5121966SSepherosa Ziehau 				break;
495b5121966SSepherosa Ziehau 			}
496b5121966SSepherosa Ziehau 		}
497b5121966SSepherosa Ziehau 	}
49876ccf3d0SSepherosa Ziehau 	if (i == prev_nproc || pp == NULL)
49976ccf3d0SSepherosa Ziehau 		return;
50076ccf3d0SSepherosa Ziehau 
50176ccf3d0SSepherosa Ziehau 	ticks = LP(fixit, iticks) - LP(pp, iticks);
50276ccf3d0SSepherosa Ziehau 	ticks += LP(fixit, sticks) - LP(pp, sticks);
50376ccf3d0SSepherosa Ziehau 	ticks += LP(fixit, uticks) - LP(pp, uticks);
5045deae5c6SMatthew Dillon 	if (ticks > d * 1000)
5055deae5c6SMatthew Dillon 		ticks = d * 1000;
50676ccf3d0SSepherosa Ziehau 	LP(fixit, pctcpu) = (ticks * (uint64_t)fscale) / d;
50776ccf3d0SSepherosa Ziehau }
508b5121966SSepherosa Ziehau 
509961f1f09SJan Lentfer caddr_t
get_process_info(struct system_info * si,struct process_select * sel,int compare_index)510961f1f09SJan Lentfer get_process_info(struct system_info *si, struct process_select *sel,
5117af1b2bcSJan Lentfer     int compare_index)
5127af1b2bcSJan Lentfer {
51376ccf3d0SSepherosa Ziehau 	struct timespec tv;
51476ccf3d0SSepherosa Ziehau 	uint64_t t, d = 0;
51576ccf3d0SSepherosa Ziehau 
5167af1b2bcSJan Lentfer 	int i;
5177af1b2bcSJan Lentfer 	int total_procs;
5187af1b2bcSJan Lentfer 	int active_procs;
5197af1b2bcSJan Lentfer 	struct kinfo_proc **prefp;
5207af1b2bcSJan Lentfer 	struct kinfo_proc *pp;
5217af1b2bcSJan Lentfer 
5227af1b2bcSJan Lentfer 	/* these are copied out of sel for speed */
5237af1b2bcSJan Lentfer 	int show_idle;
5247af1b2bcSJan Lentfer 	int show_system;
5257af1b2bcSJan Lentfer 	int show_uid;
526b0b07bbbSAlex Hornung 	int show_threads;
527ec1c3f3aSMatthew Dillon 	int kvmflags;
528ea03a758SImre Vadász 	char *match_command;
529b0b07bbbSAlex Hornung 
530b0b07bbbSAlex Hornung 	show_threads = sel->threads;
531ec1c3f3aSMatthew Dillon 	show_system = sel->system;
5327af1b2bcSJan Lentfer 
533ec1c3f3aSMatthew Dillon 	kvmflags = 0;
534ec1c3f3aSMatthew Dillon 	if (show_threads)
535ec1c3f3aSMatthew Dillon 		kvmflags |= KERN_PROC_FLAG_LWP;
536ec1c3f3aSMatthew Dillon #ifdef KERN_PROC_FLAG_LWKT
537ec1c3f3aSMatthew Dillon 	if (show_system)
538ec1c3f3aSMatthew Dillon 		kvmflags |= KERN_PROC_FLAG_LWKT;
539ec1c3f3aSMatthew Dillon #endif
540ec1c3f3aSMatthew Dillon 	pbase = kvm_getprocs(kd, KERN_PROC_ALL | kvmflags, 0, &nproc);
5417af1b2bcSJan Lentfer 	if (nproc > onproc)
5427af1b2bcSJan Lentfer 		pref = (struct kinfo_proc **)realloc(pref, sizeof(struct kinfo_proc *)
5437af1b2bcSJan Lentfer 		    * (onproc = nproc));
5447af1b2bcSJan Lentfer 	if (pref == NULL || pbase == NULL) {
5457af1b2bcSJan Lentfer 		(void)fprintf(stderr, "top: Out of memory.\n");
5467af1b2bcSJan Lentfer 		quit(23);
5477af1b2bcSJan Lentfer 	}
54876ccf3d0SSepherosa Ziehau 
54976ccf3d0SSepherosa Ziehau 	clock_gettime(CLOCK_MONOTONIC_PRECISE, &tv);
55076ccf3d0SSepherosa Ziehau 	t = (tv.tv_sec * 1000000ULL) + (tv.tv_nsec / 1000ULL);
55176ccf3d0SSepherosa Ziehau 	if (prev_pbase_time > 0 && t > prev_pbase_time)
55276ccf3d0SSepherosa Ziehau 		d = t - prev_pbase_time;
55376ccf3d0SSepherosa Ziehau 
5547af1b2bcSJan Lentfer 	/* get a pointer to the states summary array */
5557af1b2bcSJan Lentfer 	si->procstates = process_states;
5567af1b2bcSJan Lentfer 
5577af1b2bcSJan Lentfer 	/* set up flags which define what we are going to select */
5587af1b2bcSJan Lentfer 	show_idle = sel->idle;
5597af1b2bcSJan Lentfer 	show_uid = sel->uid != -1;
560efde5811SJan Lentfer 	show_fullcmd = sel->fullcmd;
561ea03a758SImre Vadász 	match_command = sel->command;
5627af1b2bcSJan Lentfer 
5637af1b2bcSJan Lentfer 	/* count up process states and get pointers to interesting procs */
5647af1b2bcSJan Lentfer 	total_procs = 0;
5657af1b2bcSJan Lentfer 	active_procs = 0;
5667af1b2bcSJan Lentfer 	memset((char *)process_states, 0, sizeof(process_states));
5677af1b2bcSJan Lentfer 	prefp = pref;
568961f1f09SJan Lentfer 	for (pp = pbase, i = 0; i < nproc; pp++, i++) {
5697af1b2bcSJan Lentfer 		/*
5707af1b2bcSJan Lentfer 		 * Place pointers to each valid proc structure in pref[].
5717af1b2bcSJan Lentfer 		 * Process slots that are actually in use have a non-zero
5727af1b2bcSJan Lentfer 		 * status field.  Processes with P_SYSTEM set are system
5737af1b2bcSJan Lentfer 		 * processes---these get ignored unless show_sysprocs is set.
5747af1b2bcSJan Lentfer 		 */
575bfb09e3bSMatthew Dillon 		if ((show_system && (LP(pp, pid) == -1)) ||
576961f1f09SJan Lentfer 		    (show_system || ((PP(pp, flags) & P_SYSTEM) == 0))) {
5770ce28ef3SJoris Giovannangeli 			int lpstate = LP(pp, stat);
5780ce28ef3SJoris Giovannangeli 			int pstate = PP(pp, stat);
57923c5b3d5SAaron LI 			int state;
580d6eee517SMatthew Dillon 
5817af1b2bcSJan Lentfer 			total_procs++;
58223c5b3d5SAaron LI 
58323c5b3d5SAaron LI 			switch (pstate) {
58423c5b3d5SAaron LI 			case SIDL:
58523c5b3d5SAaron LI 				state = PS_STARTING;
58623c5b3d5SAaron LI 				break;
58723c5b3d5SAaron LI 			case SACTIVE:
58823c5b3d5SAaron LI 				switch (lpstate) {
58923c5b3d5SAaron LI 				case LSRUN:
59023c5b3d5SAaron LI 					state = PS_RUNNING;
59123c5b3d5SAaron LI 					break;
59223c5b3d5SAaron LI 				case LSSTOP:
59323c5b3d5SAaron LI 					state = PS_STOPPED;
59423c5b3d5SAaron LI 					break;
59523c5b3d5SAaron LI 				case LSSLEEP:
59623c5b3d5SAaron LI 					state = PS_SLEEPING;
59723c5b3d5SAaron LI 					break;
59823c5b3d5SAaron LI 				default:
59923c5b3d5SAaron LI 					fprintf(stderr, "top: unknown LWP "
60023c5b3d5SAaron LI 						"state: %d\n", lpstate);
60123c5b3d5SAaron LI 					break;
60223c5b3d5SAaron LI 				}
60323c5b3d5SAaron LI 				break;
60423c5b3d5SAaron LI 			case SSTOP:
60523c5b3d5SAaron LI 				state = PS_STOPPED;
60623c5b3d5SAaron LI 				break;
60723c5b3d5SAaron LI 			case SZOMB:
60823c5b3d5SAaron LI 				state = PS_ZOMBIE;
60923c5b3d5SAaron LI 				break;
61023c5b3d5SAaron LI 			case SCORE:
611*7a491db4SAaron LI 				state = PS_DUMPING;
61223c5b3d5SAaron LI 				break;
61323c5b3d5SAaron LI 			default:
61423c5b3d5SAaron LI 				fprintf(stderr, "top: unknown process "
61523c5b3d5SAaron LI 					"state: %d\n", pstate);
61623c5b3d5SAaron LI 				break;
61723c5b3d5SAaron LI 			}
61823c5b3d5SAaron LI 			if (state < PS_MAX)
61923c5b3d5SAaron LI 				process_states[state]++;
62076ccf3d0SSepherosa Ziehau 
62176ccf3d0SSepherosa Ziehau 			if (match_command != NULL &&
62276ccf3d0SSepherosa Ziehau 			    strstr(PP(pp, comm), match_command) == NULL) {
62376ccf3d0SSepherosa Ziehau 				/* Command does not match */
62476ccf3d0SSepherosa Ziehau 				continue;
62576ccf3d0SSepherosa Ziehau 			}
62676ccf3d0SSepherosa Ziehau 
62776ccf3d0SSepherosa Ziehau 			if (show_uid && PP(pp, ruid) != (uid_t)sel->uid) {
62876ccf3d0SSepherosa Ziehau 				/* UID does not match */
62976ccf3d0SSepherosa Ziehau 				continue;
63076ccf3d0SSepherosa Ziehau 			}
63176ccf3d0SSepherosa Ziehau 
63276ccf3d0SSepherosa Ziehau 			if (!show_system && LP(pp, pid) == -1) {
63376ccf3d0SSepherosa Ziehau 				/* Don't show system processes */
63476ccf3d0SSepherosa Ziehau 				continue;
63576ccf3d0SSepherosa Ziehau 			}
63676ccf3d0SSepherosa Ziehau 
63776ccf3d0SSepherosa Ziehau 			/* Fix up pctcpu before show_idle test */
63876ccf3d0SSepherosa Ziehau 			fixup_pctcpu(pp, d);
63976ccf3d0SSepherosa Ziehau 
64076ccf3d0SSepherosa Ziehau 			if (!show_idle && LP(pp, pctcpu) == 0 &&
64176ccf3d0SSepherosa Ziehau 			    lpstate != LSRUN) {
64276ccf3d0SSepherosa Ziehau 				/* Don't show idle processes */
64376ccf3d0SSepherosa Ziehau 				continue;
64476ccf3d0SSepherosa Ziehau 			}
64576ccf3d0SSepherosa Ziehau 
6467af1b2bcSJan Lentfer 			*prefp++ = pp;
6477af1b2bcSJan Lentfer 			active_procs++;
6487af1b2bcSJan Lentfer 		}
6497af1b2bcSJan Lentfer 	}
6507af1b2bcSJan Lentfer 
65176ccf3d0SSepherosa Ziehau 	/*
65276ccf3d0SSepherosa Ziehau 	 * Save kinfo_procs for later pctcpu fixup.
65376ccf3d0SSepherosa Ziehau 	 */
65476ccf3d0SSepherosa Ziehau 	if (prev_pbase_alloc < nproc) {
65576ccf3d0SSepherosa Ziehau 		prev_pbase_alloc = nproc;
656b5121966SSepherosa Ziehau 		prev_pbase = realloc(prev_pbase,
65776ccf3d0SSepherosa Ziehau 		    prev_pbase_alloc * sizeof(struct kinfo_proc));
658b5121966SSepherosa Ziehau 		if (prev_pbase == NULL) {
659b5121966SSepherosa Ziehau 			fprintf(stderr, "top: Out of memory.\n");
660b5121966SSepherosa Ziehau 			quit(23);
661b5121966SSepherosa Ziehau 		}
662b5121966SSepherosa Ziehau 	}
66376ccf3d0SSepherosa Ziehau 	prev_nproc = nproc;
664b5121966SSepherosa Ziehau 	prev_pbase_time = t;
665b5121966SSepherosa Ziehau 	memcpy(prev_pbase, pbase, nproc * sizeof(struct kinfo_proc));
666b5121966SSepherosa Ziehau 
6677af1b2bcSJan Lentfer 	qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *),
6688b72b421SJan Lentfer 	    (int (*)(const void *, const void *))proc_compares[compare_index]);
6697af1b2bcSJan Lentfer 
6707af1b2bcSJan Lentfer 	/* remember active and total counts */
6717af1b2bcSJan Lentfer 	si->p_total = total_procs;
6727af1b2bcSJan Lentfer 	si->p_active = pref_len = active_procs;
6737af1b2bcSJan Lentfer 
6747af1b2bcSJan Lentfer 	/* pass back a handle */
6757af1b2bcSJan Lentfer 	handle.next_proc = pref;
6767af1b2bcSJan Lentfer 	handle.remaining = active_procs;
6770ca59c34SSepherosa Ziehau 	handle.show_threads = show_threads;
6787af1b2bcSJan Lentfer 	return ((caddr_t) & handle);
6797af1b2bcSJan Lentfer }
6807af1b2bcSJan Lentfer 
681cef6b642SMatthew Dillon char fmt[MAX_COLS];		/* static area where result is built */
6827af1b2bcSJan Lentfer 
6837af1b2bcSJan Lentfer char *
format_next_process(caddr_t xhandle,char * (* get_userid)(int))6847af1b2bcSJan Lentfer format_next_process(caddr_t xhandle, char *(*get_userid) (int))
6857af1b2bcSJan Lentfer {
6867af1b2bcSJan Lentfer 	struct kinfo_proc *pp;
6877af1b2bcSJan Lentfer 	long cputime;
688bcd4a7c1SJan Lentfer 	long ccputime;
6897af1b2bcSJan Lentfer 	double pct;
6907af1b2bcSJan Lentfer 	struct handle *hp;
6917af1b2bcSJan Lentfer 	char status[16];
6927af1b2bcSJan Lentfer 	int state;
6937af1b2bcSJan Lentfer 	int xnice;
6944d61aa97SAaron LI 	char *wmesg, *comm;
695bcd4a7c1SJan Lentfer 	char cputime_fmt[10], ccputime_fmt[10];
6967af1b2bcSJan Lentfer 
6977af1b2bcSJan Lentfer 	/* find and remember the next proc structure */
6987af1b2bcSJan Lentfer 	hp = (struct handle *)xhandle;
6997af1b2bcSJan Lentfer 	pp = *(hp->next_proc++);
7007af1b2bcSJan Lentfer 	hp->remaining--;
7017af1b2bcSJan Lentfer 
7027af1b2bcSJan Lentfer 	/* get the process's command name */
703efde5811SJan Lentfer 	if (show_fullcmd) {
704cb68a542SAntonio Nikishaev 		char **comm_full = kvm_getargv(kd, pp, 0);
7055e83d98bSSascha Wildner 		if (comm_full != NULL)
706cb68a542SAntonio Nikishaev 			comm = *comm_full;
707cb68a542SAntonio Nikishaev 		else
708826597b5SJohn Marino 			comm = PP(pp, comm);
7097af1b2bcSJan Lentfer 	}
710efde5811SJan Lentfer 	else {
711efde5811SJan Lentfer 		comm = PP(pp, comm);
712efde5811SJan Lentfer 	}
713efde5811SJan Lentfer 
714cb68a542SAntonio Nikishaev 	/* the actual field to display */
715cb68a542SAntonio Nikishaev 	char cmdfield[MAX_COLS];
716cb68a542SAntonio Nikishaev 
717cb68a542SAntonio Nikishaev 	if (PP(pp, flags) & P_SYSTEM) {
718cb68a542SAntonio Nikishaev 		/* system process */
719cb68a542SAntonio Nikishaev 		snprintf(cmdfield, sizeof cmdfield, "[%s]", comm);
7200ca59c34SSepherosa Ziehau 	} else if (hp->show_threads && PP(pp, nthreads) > 1) {
721cb68a542SAntonio Nikishaev 		/* display it as a thread */
7220ca59c34SSepherosa Ziehau 		if (strcmp(PP(pp, comm), LP(pp, comm)) == 0) {
7230ca59c34SSepherosa Ziehau 			snprintf(cmdfield, sizeof cmdfield, "%s{%d}", comm,
7240ca59c34SSepherosa Ziehau 			    LP(pp, tid));
7250ca59c34SSepherosa Ziehau 		} else {
7260ca59c34SSepherosa Ziehau 			/* show thread name in addition to tid */
7270ca59c34SSepherosa Ziehau 			snprintf(cmdfield, sizeof cmdfield, "%s{%d/%s}", comm,
7280ca59c34SSepherosa Ziehau 			    LP(pp, tid), LP(pp, comm));
7290ca59c34SSepherosa Ziehau 		}
730cb68a542SAntonio Nikishaev 	} else {
731cb68a542SAntonio Nikishaev 		snprintf(cmdfield, sizeof cmdfield, "%s", comm);
732cb68a542SAntonio Nikishaev 	}
733cb68a542SAntonio Nikishaev 
7347af1b2bcSJan Lentfer 	/*
7357af1b2bcSJan Lentfer 	 * Convert the process's runtime from microseconds to seconds.  This
736bcd4a7c1SJan Lentfer 	 * time includes the interrupt time to be in compliance with ps output.
7377af1b2bcSJan Lentfer 	 */
738bcd4a7c1SJan Lentfer 	cputime = (LP(pp, uticks) + LP(pp, sticks) + LP(pp, iticks)) / 1000000;
739bcd4a7c1SJan Lentfer 	ccputime = cputime + PP(pp, cru).ru_stime.tv_sec + PP(pp, cru).ru_utime.tv_sec;
740bcd4a7c1SJan Lentfer 	format_time(cputime, cputime_fmt, sizeof(cputime_fmt));
741bcd4a7c1SJan Lentfer 	format_time(ccputime, ccputime_fmt, sizeof(ccputime_fmt));
7427af1b2bcSJan Lentfer 
7437af1b2bcSJan Lentfer 	/* calculate the base for cpu percentages */
7447af1b2bcSJan Lentfer 	pct = pctdouble(LP(pp, pctcpu));
7457af1b2bcSJan Lentfer 
7467af1b2bcSJan Lentfer 	/* generate "STATE" field */
7478c086bfbSAaron LI 	state = PS_MAX;
7488c086bfbSAaron LI 	switch (PP(pp, stat)) {
7498c086bfbSAaron LI 	case SIDL:
7508c086bfbSAaron LI 		state = PS_STARTING;
7518c086bfbSAaron LI 		break;
7528c086bfbSAaron LI 	case SACTIVE:
7538c086bfbSAaron LI 		switch (LP(pp, stat)) {
7547af1b2bcSJan Lentfer 		case LSRUN:
755975fc636SSascha Wildner 			if (LP(pp, tdflags) & TDF_RUNNING)
7567af1b2bcSJan Lentfer 				sprintf(status, "CPU%d", LP(pp, cpuid));
7577af1b2bcSJan Lentfer 			else
7588c086bfbSAaron LI 				state = PS_RUNNING;
7598c086bfbSAaron LI 			break;
7608c086bfbSAaron LI 		case LSSTOP:
7618c086bfbSAaron LI 			state = PS_STOPPED;
7627af1b2bcSJan Lentfer 			break;
7637af1b2bcSJan Lentfer 		case LSSLEEP:
7644d61aa97SAaron LI 			wmesg = LP(pp, wmesg);
7658c086bfbSAaron LI 			if (wmesg[0] != '\0')
7664d61aa97SAaron LI 				sprintf(status, "%.8s", wmesg); /* WMESGLEN */
7677af1b2bcSJan Lentfer 			else
7688c086bfbSAaron LI 				state = PS_SLEEPING;
7698c086bfbSAaron LI 			break;
7708c086bfbSAaron LI 		default:
7718c086bfbSAaron LI 			sprintf(status, "?LP/%d", LP(pp, stat));
7727af1b2bcSJan Lentfer 			break;
7737af1b2bcSJan Lentfer 		}
7748c086bfbSAaron LI 		break;
7758c086bfbSAaron LI 	case SSTOP:
7768c086bfbSAaron LI 		state = PS_STOPPED;
7778c086bfbSAaron LI 		break;
7788c086bfbSAaron LI 	case SZOMB:
7798c086bfbSAaron LI 		state = PS_ZOMBIE;
7808c086bfbSAaron LI 		break;
7818c086bfbSAaron LI 	case SCORE:
782*7a491db4SAaron LI 		state = PS_DUMPING;
783*7a491db4SAaron LI 		break;
7848c086bfbSAaron LI 	default:
7858c086bfbSAaron LI 		sprintf(status, "?P/%d", PP(pp, stat));
7868c086bfbSAaron LI 		break;
7878c086bfbSAaron LI 	}
7888c086bfbSAaron LI 	if (state < PS_MAX)
7898c086bfbSAaron LI 		sprintf(status, "%.8s", state_abbrev[state]);
7907af1b2bcSJan Lentfer 
7917af1b2bcSJan Lentfer 	/*
792961f1f09SJan Lentfer 	 * idle time 0 - 31 -> nice value +21 - +52 normal time      -> nice
793961f1f09SJan Lentfer 	 * value -20 - +20 real time 0 - 31 -> nice value -52 - -21 thread
794961f1f09SJan Lentfer 	 * 0 - 31 -> nice value -53 -
7957af1b2bcSJan Lentfer 	 */
7967af1b2bcSJan Lentfer 	switch (LP(pp, rtprio.type)) {
7977af1b2bcSJan Lentfer 	case RTP_PRIO_REALTIME:
7987af1b2bcSJan Lentfer 		xnice = PRIO_MIN - 1 - RTP_PRIO_MAX + LP(pp, rtprio.prio);
7997af1b2bcSJan Lentfer 		break;
8007af1b2bcSJan Lentfer 	case RTP_PRIO_IDLE:
8017af1b2bcSJan Lentfer 		xnice = PRIO_MAX + 1 + LP(pp, rtprio.prio);
8027af1b2bcSJan Lentfer 		break;
8037af1b2bcSJan Lentfer 	case RTP_PRIO_THREAD:
8047af1b2bcSJan Lentfer 		xnice = PRIO_MIN - 1 - RTP_PRIO_MAX - LP(pp, rtprio.prio);
8057af1b2bcSJan Lentfer 		break;
8067af1b2bcSJan Lentfer 	default:
8077af1b2bcSJan Lentfer 		xnice = PP(pp, nice);
8087af1b2bcSJan Lentfer 		break;
8097af1b2bcSJan Lentfer 	}
8107af1b2bcSJan Lentfer 
8117af1b2bcSJan Lentfer 	/* format this entry */
8127af1b2bcSJan Lentfer 	snprintf(fmt, sizeof(fmt),
813975fc636SSascha Wildner 	    smp_Proc_format,
8147af1b2bcSJan Lentfer 	    (int)PP(pp, pid),
8157af1b2bcSJan Lentfer 	    namelength, namelength,
8167af1b2bcSJan Lentfer 	    get_userid(PP(pp, ruid)),
8177af1b2bcSJan Lentfer 	    (int)xnice,
8187af1b2bcSJan Lentfer 	    format_k(PROCSIZE(pp)),
81930277d08SMatthew Dillon 	    format_k(pagetok(VP(pp, rssize))),
8207af1b2bcSJan Lentfer 	    status,
821975fc636SSascha Wildner 	    LP(pp, cpuid),
822bcd4a7c1SJan Lentfer 	    cputime_fmt,
823bcd4a7c1SJan Lentfer 	    ccputime_fmt,
8247af1b2bcSJan Lentfer 	    100.0 * pct,
8257af1b2bcSJan Lentfer 	    cmdlength,
826cb68a542SAntonio Nikishaev 	    cmdfield);
8277af1b2bcSJan Lentfer 
8287af1b2bcSJan Lentfer 	/* return the result */
8297af1b2bcSJan Lentfer 	return (fmt);
8307af1b2bcSJan Lentfer }
8317af1b2bcSJan Lentfer 
8327af1b2bcSJan Lentfer /* comparison routines for qsort */
8337af1b2bcSJan Lentfer 
8347af1b2bcSJan Lentfer /*
8357af1b2bcSJan Lentfer  *  proc_compare - comparison function for "qsort"
8367af1b2bcSJan Lentfer  *	Compares the resource consumption of two processes using five
8377af1b2bcSJan Lentfer  *  	distinct keys.  The keys (in descending order of importance) are:
8387af1b2bcSJan Lentfer  *  	percent cpu, cpu ticks, state, resident set size, total virtual
8397af1b2bcSJan Lentfer  *  	memory usage.  The process states are ordered as follows (from least
8407af1b2bcSJan Lentfer  *  	to most important):  WAIT, zombie, sleep, stop, start, run.  The
8417af1b2bcSJan Lentfer  *  	array declaration below maps a process state index into a number
8427af1b2bcSJan Lentfer  *  	that reflects this ordering.
8437af1b2bcSJan Lentfer  */
8447af1b2bcSJan Lentfer 
8457af1b2bcSJan Lentfer static unsigned char sorted_state[] =
8467af1b2bcSJan Lentfer {
8477af1b2bcSJan Lentfer 	0,			/* not used		 */
8487af1b2bcSJan Lentfer 	3,			/* sleep		 */
8497af1b2bcSJan Lentfer 	1,			/* ABANDONED (WAIT)	 */
8507af1b2bcSJan Lentfer 	6,			/* run			 */
8517af1b2bcSJan Lentfer 	5,			/* start		 */
8527af1b2bcSJan Lentfer 	2,			/* zombie		 */
8537af1b2bcSJan Lentfer 	4			/* stop			 */
8547af1b2bcSJan Lentfer };
8557af1b2bcSJan Lentfer 
8567af1b2bcSJan Lentfer 
8577af1b2bcSJan Lentfer #define ORDERKEY_PCTCPU \
8587af1b2bcSJan Lentfer   if (lresult = (long) LP(p2, pctcpu) - (long) LP(p1, pctcpu), \
8597af1b2bcSJan Lentfer      (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
8607af1b2bcSJan Lentfer 
861bcd4a7c1SJan Lentfer #define CPTICKS(p)	(LP(p, uticks) + LP(p, sticks) + LP(p, iticks))
8627af1b2bcSJan Lentfer 
8637af1b2bcSJan Lentfer #define ORDERKEY_CPTICKS \
8647af1b2bcSJan Lentfer   if ((result = CPTICKS(p2) > CPTICKS(p1) ? 1 : \
8657af1b2bcSJan Lentfer 		CPTICKS(p2) < CPTICKS(p1) ? -1 : 0) == 0)
8667af1b2bcSJan Lentfer 
867bcd4a7c1SJan Lentfer #define CTIME(p)	(((LP(p, uticks) + LP(p, sticks) + LP(p, iticks))/1000000) + \
868bcd4a7c1SJan Lentfer   PP(p, cru).ru_stime.tv_sec + PP(p, cru).ru_utime.tv_sec)
869bcd4a7c1SJan Lentfer 
870bcd4a7c1SJan Lentfer #define ORDERKEY_CTIME \
871bcd4a7c1SJan Lentfer    if ((result = CTIME(p2) > CTIME(p1) ? 1 : \
872bcd4a7c1SJan Lentfer 		CTIME(p2) < CTIME(p1) ? -1 : 0) == 0)
873bcd4a7c1SJan Lentfer 
8747af1b2bcSJan Lentfer #define ORDERKEY_STATE \
8757af1b2bcSJan Lentfer   if ((result = sorted_state[(unsigned char) PP(p2, stat)] - \
8767af1b2bcSJan Lentfer                 sorted_state[(unsigned char) PP(p1, stat)]) == 0)
8777af1b2bcSJan Lentfer 
8787af1b2bcSJan Lentfer #define ORDERKEY_PRIO \
8797af1b2bcSJan Lentfer   if ((result = LP(p2, prio) - LP(p1, prio)) == 0)
8807af1b2bcSJan Lentfer 
8817af1b2bcSJan Lentfer #define ORDERKEY_KTHREADS \
8827af1b2bcSJan Lentfer   if ((result = (LP(p1, pid) == 0) - (LP(p2, pid) == 0)) == 0)
8837af1b2bcSJan Lentfer 
8847af1b2bcSJan Lentfer #define ORDERKEY_KTHREADS_PRIO \
8857af1b2bcSJan Lentfer   if ((result = LP(p2, tdprio) - LP(p1, tdprio)) == 0)
8867af1b2bcSJan Lentfer 
8877af1b2bcSJan Lentfer #define ORDERKEY_RSSIZE \
8887af1b2bcSJan Lentfer   if ((result = VP(p2, rssize) - VP(p1, rssize)) == 0)
8897af1b2bcSJan Lentfer 
8907af1b2bcSJan Lentfer #define ORDERKEY_MEM \
8917af1b2bcSJan Lentfer   if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 )
8927af1b2bcSJan Lentfer 
8938b72b421SJan Lentfer #define ORDERKEY_PID \
8948b72b421SJan Lentfer   if ( (result = PP(p1, pid) - PP(p2, pid)) == 0)
8958b72b421SJan Lentfer 
89650a55c46SMatthew Dillon #define ORDERKEY_PRSSIZE \
89750a55c46SMatthew Dillon   if((result = VP(p2, prssize) - VP(p1, prssize)) == 0)
89850a55c46SMatthew Dillon 
899bfbef474SSepherosa Ziehau static __inline int
orderkey_kernidle(const struct kinfo_proc * p1,const struct kinfo_proc * p2)900bfbef474SSepherosa Ziehau orderkey_kernidle(const struct kinfo_proc *p1, const struct kinfo_proc *p2)
901bfbef474SSepherosa Ziehau {
902bfbef474SSepherosa Ziehau 	int p1_kidle = 0, p2_kidle = 0;
903bfbef474SSepherosa Ziehau 
904bfbef474SSepherosa Ziehau 	if (LP(p1, pid) == -1 && PP(p1, stat) == SIDL)
905bfbef474SSepherosa Ziehau 		p1_kidle = 1;
906bfbef474SSepherosa Ziehau 	if (LP(p2, pid) == -1 && PP(p2, stat) == SIDL)
907bfbef474SSepherosa Ziehau 		p2_kidle = 1;
908bfbef474SSepherosa Ziehau 
909bfbef474SSepherosa Ziehau 	if (!p2_kidle && p1_kidle)
910bfbef474SSepherosa Ziehau 		return 1;
911bfbef474SSepherosa Ziehau 	if (p2_kidle && !p1_kidle)
912bfbef474SSepherosa Ziehau 		return -1;
913bfbef474SSepherosa Ziehau 	return 0;
914bfbef474SSepherosa Ziehau }
915bfbef474SSepherosa Ziehau 
916bfbef474SSepherosa Ziehau #define ORDERKEY_KIDLE	if ((result = orderkey_kernidle(p1, p2)) == 0)
917bfbef474SSepherosa Ziehau 
9187af1b2bcSJan Lentfer /* compare_cpu - the comparison function for sorting by cpu percentage */
9197af1b2bcSJan Lentfer 
9207af1b2bcSJan Lentfer int
proc_compare(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)9218b72b421SJan Lentfer proc_compare(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
9227af1b2bcSJan Lentfer {
9238b72b421SJan Lentfer 	struct kinfo_proc *p1;
9248b72b421SJan Lentfer 	struct kinfo_proc *p2;
9257af1b2bcSJan Lentfer 	int result;
9267af1b2bcSJan Lentfer 	pctcpu lresult;
9277af1b2bcSJan Lentfer 
9287af1b2bcSJan Lentfer 	/* remove one level of indirection */
9298b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
9308b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
9317af1b2bcSJan Lentfer 
932bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
9337af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
9347af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
9357af1b2bcSJan Lentfer 	ORDERKEY_STATE
9367af1b2bcSJan Lentfer 	ORDERKEY_PRIO
9377af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
9387af1b2bcSJan Lentfer 	ORDERKEY_MEM
9397af1b2bcSJan Lentfer 	{}
9407af1b2bcSJan Lentfer 
9417af1b2bcSJan Lentfer 	return (result);
9427af1b2bcSJan Lentfer }
9437af1b2bcSJan Lentfer 
9447af1b2bcSJan Lentfer /* compare_size - the comparison function for sorting by total memory usage */
9457af1b2bcSJan Lentfer 
9467af1b2bcSJan Lentfer int
compare_size(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)9478b72b421SJan Lentfer compare_size(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
9487af1b2bcSJan Lentfer {
9497af1b2bcSJan Lentfer 	struct kinfo_proc *p1;
9507af1b2bcSJan Lentfer 	struct kinfo_proc *p2;
9517af1b2bcSJan Lentfer 	int result;
9527af1b2bcSJan Lentfer 	pctcpu lresult;
9537af1b2bcSJan Lentfer 
9547af1b2bcSJan Lentfer 	/* remove one level of indirection */
9558b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
9568b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
9577af1b2bcSJan Lentfer 
9587af1b2bcSJan Lentfer 	ORDERKEY_MEM
9597af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
960bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
9617af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
9627af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
9637af1b2bcSJan Lentfer 	ORDERKEY_STATE
9647af1b2bcSJan Lentfer 	ORDERKEY_PRIO
9657af1b2bcSJan Lentfer 	{}
9667af1b2bcSJan Lentfer 
9677af1b2bcSJan Lentfer 	return (result);
9687af1b2bcSJan Lentfer }
9697af1b2bcSJan Lentfer 
9707af1b2bcSJan Lentfer /* compare_res - the comparison function for sorting by resident set size */
9717af1b2bcSJan Lentfer 
9727af1b2bcSJan Lentfer int
compare_res(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)9738b72b421SJan Lentfer compare_res(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
9747af1b2bcSJan Lentfer {
9757af1b2bcSJan Lentfer 	struct kinfo_proc *p1;
9767af1b2bcSJan Lentfer 	struct kinfo_proc *p2;
9777af1b2bcSJan Lentfer 	int result;
9787af1b2bcSJan Lentfer 	pctcpu lresult;
9797af1b2bcSJan Lentfer 
9807af1b2bcSJan Lentfer 	/* remove one level of indirection */
9818b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
9828b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
9837af1b2bcSJan Lentfer 
9847af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
9857af1b2bcSJan Lentfer 	ORDERKEY_MEM
986bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
9877af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
9887af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
9897af1b2bcSJan Lentfer 	ORDERKEY_STATE
9907af1b2bcSJan Lentfer 	ORDERKEY_PRIO
9917af1b2bcSJan Lentfer 	{}
9927af1b2bcSJan Lentfer 
9937af1b2bcSJan Lentfer 	return (result);
9947af1b2bcSJan Lentfer }
9957af1b2bcSJan Lentfer 
99650a55c46SMatthew Dillon /* compare_pres - the comparison function for sorting by proportional resident set size */
99750a55c46SMatthew Dillon 
99850a55c46SMatthew Dillon int
compare_pres(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)99950a55c46SMatthew Dillon compare_pres(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
100050a55c46SMatthew Dillon {
100150a55c46SMatthew Dillon 	struct kinfo_proc *p1;
100250a55c46SMatthew Dillon 	struct kinfo_proc *p2;
100350a55c46SMatthew Dillon 	int result;
100450a55c46SMatthew Dillon 	pctcpu lresult;
100550a55c46SMatthew Dillon 
100650a55c46SMatthew Dillon 	/* remove one level of indirection */
100750a55c46SMatthew Dillon 	p1 = *(struct kinfo_proc **) pp1;
100850a55c46SMatthew Dillon 	p2 = *(struct kinfo_proc **) pp2;
100950a55c46SMatthew Dillon 
101050a55c46SMatthew Dillon 	ORDERKEY_PRSSIZE
101150a55c46SMatthew Dillon 	ORDERKEY_RSSIZE
101250a55c46SMatthew Dillon 	ORDERKEY_MEM
1013bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
101450a55c46SMatthew Dillon 	ORDERKEY_PCTCPU
101550a55c46SMatthew Dillon 	ORDERKEY_CPTICKS
101650a55c46SMatthew Dillon 	ORDERKEY_STATE
101750a55c46SMatthew Dillon 	ORDERKEY_PRIO
101850a55c46SMatthew Dillon 	{}
101950a55c46SMatthew Dillon 
102050a55c46SMatthew Dillon 	return (result);
102150a55c46SMatthew Dillon }
102250a55c46SMatthew Dillon 
10237af1b2bcSJan Lentfer /* compare_time - the comparison function for sorting by total cpu time */
10247af1b2bcSJan Lentfer 
10257af1b2bcSJan Lentfer int
compare_time(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)10268b72b421SJan Lentfer compare_time(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
10277af1b2bcSJan Lentfer {
10288b72b421SJan Lentfer 	struct kinfo_proc *p1;
10298b72b421SJan Lentfer 	struct kinfo_proc *p2;
10307af1b2bcSJan Lentfer 	int result;
10317af1b2bcSJan Lentfer 	pctcpu lresult;
10327af1b2bcSJan Lentfer 
10337af1b2bcSJan Lentfer 	/* remove one level of indirection */
10348b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
10358b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
10367af1b2bcSJan Lentfer 
1037bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
10387af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
10397af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
10407af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS
10417af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS_PRIO
10427af1b2bcSJan Lentfer 	ORDERKEY_STATE
10437af1b2bcSJan Lentfer 	ORDERKEY_PRIO
10447af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
10457af1b2bcSJan Lentfer 	ORDERKEY_MEM
10467af1b2bcSJan Lentfer 	{}
10477af1b2bcSJan Lentfer 
10487af1b2bcSJan Lentfer 	return (result);
10497af1b2bcSJan Lentfer }
10507af1b2bcSJan Lentfer 
1051bcd4a7c1SJan Lentfer int
compare_ctime(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)1052bcd4a7c1SJan Lentfer compare_ctime(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
1053bcd4a7c1SJan Lentfer {
1054bcd4a7c1SJan Lentfer 	struct kinfo_proc *p1;
1055bcd4a7c1SJan Lentfer 	struct kinfo_proc *p2;
1056bcd4a7c1SJan Lentfer 	int result;
1057bcd4a7c1SJan Lentfer 	pctcpu lresult;
1058bcd4a7c1SJan Lentfer 
1059bcd4a7c1SJan Lentfer 	/* remove one level of indirection */
1060bcd4a7c1SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
1061bcd4a7c1SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
1062bcd4a7c1SJan Lentfer 
1063bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
1064bcd4a7c1SJan Lentfer 	ORDERKEY_CTIME
1065bcd4a7c1SJan Lentfer 	ORDERKEY_PCTCPU
1066bcd4a7c1SJan Lentfer 	ORDERKEY_KTHREADS
1067bcd4a7c1SJan Lentfer 	ORDERKEY_KTHREADS_PRIO
1068bcd4a7c1SJan Lentfer 	ORDERKEY_STATE
1069bcd4a7c1SJan Lentfer 	ORDERKEY_PRIO
1070bcd4a7c1SJan Lentfer 	ORDERKEY_RSSIZE
1071bcd4a7c1SJan Lentfer 	ORDERKEY_MEM
1072bcd4a7c1SJan Lentfer 	{}
1073bcd4a7c1SJan Lentfer 
1074bcd4a7c1SJan Lentfer 	return (result);
1075bcd4a7c1SJan Lentfer }
1076bcd4a7c1SJan Lentfer 
10777af1b2bcSJan Lentfer /* compare_prio - the comparison function for sorting by cpu percentage */
10787af1b2bcSJan Lentfer 
10797af1b2bcSJan Lentfer int
compare_prio(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)10808b72b421SJan Lentfer compare_prio(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
10817af1b2bcSJan Lentfer {
10828b72b421SJan Lentfer 	struct kinfo_proc *p1;
10838b72b421SJan Lentfer 	struct kinfo_proc *p2;
10847af1b2bcSJan Lentfer 	int result;
10857af1b2bcSJan Lentfer 	pctcpu lresult;
10867af1b2bcSJan Lentfer 
10877af1b2bcSJan Lentfer 	/* remove one level of indirection */
10888b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
10898b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
10907af1b2bcSJan Lentfer 
10917af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS
10927af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS_PRIO
10937af1b2bcSJan Lentfer 	ORDERKEY_PRIO
1094bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
10957af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
10967af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
10977af1b2bcSJan Lentfer 	ORDERKEY_STATE
10987af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
10997af1b2bcSJan Lentfer 	ORDERKEY_MEM
11007af1b2bcSJan Lentfer 	{}
11017af1b2bcSJan Lentfer 
11027af1b2bcSJan Lentfer 	return (result);
11037af1b2bcSJan Lentfer }
11047af1b2bcSJan Lentfer 
11057af1b2bcSJan Lentfer int
compare_thr(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)11068b72b421SJan Lentfer compare_thr(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
11077af1b2bcSJan Lentfer {
11088b72b421SJan Lentfer 	struct kinfo_proc *p1;
11098b72b421SJan Lentfer 	struct kinfo_proc *p2;
11107af1b2bcSJan Lentfer 	int result;
11117af1b2bcSJan Lentfer 	pctcpu lresult;
11127af1b2bcSJan Lentfer 
11137af1b2bcSJan Lentfer 	/* remove one level of indirection */
11148b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **)pp1;
11158b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **)pp2;
11167af1b2bcSJan Lentfer 
11177af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS
11187af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS_PRIO
1119bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
11207af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
11217af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
11227af1b2bcSJan Lentfer 	ORDERKEY_STATE
11237af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
11247af1b2bcSJan Lentfer 	ORDERKEY_MEM
11257af1b2bcSJan Lentfer 	{}
11267af1b2bcSJan Lentfer 
11277af1b2bcSJan Lentfer 	return (result);
11287af1b2bcSJan Lentfer }
11297af1b2bcSJan Lentfer 
11308b72b421SJan Lentfer /* compare_pid - the comparison function for sorting by process id */
11318b72b421SJan Lentfer 
11328b72b421SJan Lentfer int
compare_pid(struct kinfo_proc ** pp1,struct kinfo_proc ** pp2)11338b72b421SJan Lentfer compare_pid(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
11348b72b421SJan Lentfer {
11358b72b421SJan Lentfer 	struct kinfo_proc *p1;
11368b72b421SJan Lentfer 	struct kinfo_proc *p2;
11378b72b421SJan Lentfer 	int result;
11388b72b421SJan Lentfer 
11398b72b421SJan Lentfer 	/* remove one level of indirection */
11408b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
11418b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
11428b72b421SJan Lentfer 
11438b72b421SJan Lentfer 	ORDERKEY_PID
11448b72b421SJan Lentfer 	;
11458b72b421SJan Lentfer 
11468b72b421SJan Lentfer 	return(result);
11478b72b421SJan Lentfer }
11488b72b421SJan Lentfer 
11497af1b2bcSJan Lentfer /*
11507af1b2bcSJan Lentfer  * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
11517af1b2bcSJan Lentfer  *		the process does not exist.
11527af1b2bcSJan Lentfer  *		It is EXTREMLY IMPORTANT that this function work correctly.
11537af1b2bcSJan Lentfer  *		If top runs setuid root (as in SVR4), then this function
11547af1b2bcSJan Lentfer  *		is the only thing that stands in the way of a serious
11557af1b2bcSJan Lentfer  *		security problem.  It validates requests for the "kill"
11567af1b2bcSJan Lentfer  *		and "renice" commands.
11577af1b2bcSJan Lentfer  */
11587af1b2bcSJan Lentfer 
11597af1b2bcSJan Lentfer int
proc_owner(int pid)11607af1b2bcSJan Lentfer proc_owner(int pid)
11617af1b2bcSJan Lentfer {
11627af1b2bcSJan Lentfer 	int xcnt;
11637af1b2bcSJan Lentfer 	struct kinfo_proc **prefp;
11647af1b2bcSJan Lentfer 	struct kinfo_proc *pp;
11657af1b2bcSJan Lentfer 
11667af1b2bcSJan Lentfer 	prefp = pref;
11677af1b2bcSJan Lentfer 	xcnt = pref_len;
1168961f1f09SJan Lentfer 	while (--xcnt >= 0) {
11697af1b2bcSJan Lentfer 		pp = *prefp++;
1170961f1f09SJan Lentfer 		if (PP(pp, pid) == (pid_t) pid) {
11717af1b2bcSJan Lentfer 			return ((int)PP(pp, ruid));
11727af1b2bcSJan Lentfer 		}
11737af1b2bcSJan Lentfer 	}
11747af1b2bcSJan Lentfer 	return (-1);
11757af1b2bcSJan Lentfer }
11767af1b2bcSJan Lentfer 
11777af1b2bcSJan Lentfer 
11787af1b2bcSJan Lentfer /*
11797af1b2bcSJan Lentfer  * swapmode is based on a program called swapinfo written
11807af1b2bcSJan Lentfer  * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
11817af1b2bcSJan Lentfer  */
11827af1b2bcSJan Lentfer int
swapmode(int * retavail,int * retfree)11837af1b2bcSJan Lentfer swapmode(int *retavail, int *retfree)
11847af1b2bcSJan Lentfer {
11857af1b2bcSJan Lentfer 	int n;
11867af1b2bcSJan Lentfer 	int pagesize = getpagesize();
11877af1b2bcSJan Lentfer 	struct kvm_swap swapary[1];
11887af1b2bcSJan Lentfer 
11897af1b2bcSJan Lentfer 	*retavail = 0;
11907af1b2bcSJan Lentfer 	*retfree = 0;
11917af1b2bcSJan Lentfer 
11927af1b2bcSJan Lentfer #define CONVERT(v)	((quad_t)(v) * pagesize / 1024)
11937af1b2bcSJan Lentfer 
11947af1b2bcSJan Lentfer 	n = kvm_getswapinfo(kd, swapary, 1, 0);
11957af1b2bcSJan Lentfer 	if (n < 0 || swapary[0].ksw_total == 0)
11967af1b2bcSJan Lentfer 		return (0);
11977af1b2bcSJan Lentfer 
11987af1b2bcSJan Lentfer 	*retavail = CONVERT(swapary[0].ksw_total);
11997af1b2bcSJan Lentfer 	*retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
12007af1b2bcSJan Lentfer 
12017af1b2bcSJan Lentfer 	n = (int)((double)swapary[0].ksw_used * 100.0 /
12027af1b2bcSJan Lentfer 	    (double)swapary[0].ksw_total);
12037af1b2bcSJan Lentfer 	return (n);
12047af1b2bcSJan Lentfer }
1205