xref: /dragonfly/usr.bin/top/m_dragonfly.c (revision 5deae5c6)
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>
337af1b2bcSJan Lentfer #include <kvm.h>
347af1b2bcSJan Lentfer #include <stdio.h>
357af1b2bcSJan Lentfer #include <unistd.h>
367af1b2bcSJan Lentfer #include <math.h>
377af1b2bcSJan Lentfer #include <pwd.h>
387af1b2bcSJan Lentfer #include <sys/errno.h>
397af1b2bcSJan Lentfer #include <sys/sysctl.h>
407af1b2bcSJan Lentfer #include <sys/file.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 
657af1b2bcSJan Lentfer int n_cpus = 0;
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 /* process state names for the "STATE" column of the display */
96961f1f09SJan Lentfer /*
97961f1f09SJan Lentfer  * the extra nulls in the string "run" are for adding a slash and the
98961f1f09SJan Lentfer  * processor number when needed
99961f1f09SJan Lentfer  */
1007af1b2bcSJan Lentfer 
101961f1f09SJan Lentfer const char *state_abbrev[] = {
1027af1b2bcSJan Lentfer 	"", "RUN\0\0\0", "STOP", "SLEEP",
1037af1b2bcSJan Lentfer };
1047af1b2bcSJan Lentfer 
1057af1b2bcSJan Lentfer 
1067af1b2bcSJan Lentfer static kvm_t *kd;
1077af1b2bcSJan Lentfer 
1087af1b2bcSJan Lentfer /* values that we stash away in _init and use in later routines */
1097af1b2bcSJan Lentfer 
1107af1b2bcSJan Lentfer static long lastpid;
1117af1b2bcSJan Lentfer 
1127af1b2bcSJan Lentfer /* these are for calculating cpu state percentages */
1137af1b2bcSJan Lentfer 
1147af1b2bcSJan Lentfer static struct kinfo_cputime *cp_time, *cp_old;
1157af1b2bcSJan Lentfer 
1167af1b2bcSJan Lentfer /* these are for detailing the process states */
1177af1b2bcSJan Lentfer 
118d6eee517SMatthew Dillon #define MAXPSTATES	6
119d6eee517SMatthew Dillon 
120d6eee517SMatthew Dillon int process_states[MAXPSTATES];
121d6eee517SMatthew Dillon 
1227af1b2bcSJan Lentfer char *procstatenames[] = {
123bc40e61dSStathis Kamperis 	" running, ", " idle, ", " active, ", " stopped, ", " zombie, ",
1247af1b2bcSJan Lentfer 	NULL
1257af1b2bcSJan Lentfer };
1267af1b2bcSJan Lentfer 
1277af1b2bcSJan Lentfer /* these are for detailing the cpu states */
1287af1b2bcSJan Lentfer #define CPU_STATES 5
1297af1b2bcSJan Lentfer int *cpu_states;
130edc735acSJavier Alcázar int* cpu_averages;
1317af1b2bcSJan Lentfer char *cpustatenames[CPU_STATES + 1] = {
1327af1b2bcSJan Lentfer 	"user", "nice", "system", "interrupt", "idle", NULL
1337af1b2bcSJan Lentfer };
1347af1b2bcSJan Lentfer 
1357af1b2bcSJan Lentfer /* these are for detailing the memory statistics */
1367af1b2bcSJan Lentfer 
1377af1b2bcSJan Lentfer long memory_stats[7];
1387af1b2bcSJan Lentfer char *memorynames[] = {
1397af1b2bcSJan Lentfer 	"K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free",
1407af1b2bcSJan Lentfer 	NULL
1417af1b2bcSJan Lentfer };
1427af1b2bcSJan Lentfer 
1437af1b2bcSJan Lentfer long swap_stats[7];
1447af1b2bcSJan Lentfer char *swapnames[] = {
1457af1b2bcSJan Lentfer 	/* 0           1            2           3            4       5 */
1467af1b2bcSJan Lentfer 	"K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out",
1477af1b2bcSJan Lentfer 	NULL
1487af1b2bcSJan Lentfer };
1497af1b2bcSJan Lentfer 
1507af1b2bcSJan Lentfer 
1517af1b2bcSJan Lentfer /* these are for keeping track of the proc array */
1527af1b2bcSJan Lentfer 
1537af1b2bcSJan Lentfer static int nproc;
1547af1b2bcSJan Lentfer static int onproc = -1;
1557af1b2bcSJan Lentfer static int pref_len;
1567af1b2bcSJan Lentfer static struct kinfo_proc *pbase;
1577af1b2bcSJan Lentfer static struct kinfo_proc **pref;
1587af1b2bcSJan Lentfer 
159b5121966SSepherosa Ziehau static uint64_t prev_pbase_time;	/* unit: us */
160b5121966SSepherosa Ziehau static struct kinfo_proc *prev_pbase;
16176ccf3d0SSepherosa Ziehau static int prev_pbase_alloc;
16276ccf3d0SSepherosa Ziehau static int prev_nproc;
163b5121966SSepherosa Ziehau static int fscale;
164b5121966SSepherosa Ziehau 
1657af1b2bcSJan Lentfer /* these are for getting the memory statistics */
1667af1b2bcSJan Lentfer 
1677af1b2bcSJan Lentfer static int pageshift;		/* log base 2 of the pagesize */
1687af1b2bcSJan Lentfer 
1697af1b2bcSJan Lentfer /* define pagetok in terms of pageshift */
1707af1b2bcSJan Lentfer 
1717af1b2bcSJan Lentfer #define pagetok(size) ((size) << pageshift)
1727af1b2bcSJan Lentfer 
1737af1b2bcSJan Lentfer /* sorting orders. first is default */
1747af1b2bcSJan Lentfer char *ordernames[] = {
17550a55c46SMatthew Dillon   "cpu", "size", "res", "time", "pri", "thr", "pid", "ctime",  "pres", NULL
1767af1b2bcSJan Lentfer };
1777af1b2bcSJan Lentfer 
1787af1b2bcSJan Lentfer /* compare routines */
1798b72b421SJan Lentfer int proc_compare (struct kinfo_proc **, struct kinfo_proc **);
1808b72b421SJan Lentfer int compare_size (struct kinfo_proc **, struct kinfo_proc **);
1818b72b421SJan Lentfer int compare_res (struct kinfo_proc **, struct kinfo_proc **);
1828b72b421SJan Lentfer int compare_time (struct kinfo_proc **, struct kinfo_proc **);
183bcd4a7c1SJan Lentfer int compare_ctime (struct kinfo_proc **, struct kinfo_proc **);
1848b72b421SJan Lentfer int compare_prio(struct kinfo_proc **, struct kinfo_proc **);
1858b72b421SJan Lentfer int compare_thr (struct kinfo_proc **, struct kinfo_proc **);
1868b72b421SJan Lentfer int compare_pid (struct kinfo_proc **, struct kinfo_proc **);
18750a55c46SMatthew Dillon int compare_pres(struct kinfo_proc **, struct kinfo_proc **);
1887af1b2bcSJan Lentfer 
1898b72b421SJan Lentfer int (*proc_compares[]) (struct kinfo_proc **,struct kinfo_proc **) = {
1907af1b2bcSJan Lentfer 	proc_compare,
1917af1b2bcSJan Lentfer 	compare_size,
1927af1b2bcSJan Lentfer 	compare_res,
1937af1b2bcSJan Lentfer 	compare_time,
1947af1b2bcSJan Lentfer 	compare_prio,
1958b72b421SJan Lentfer 	compare_thr,
1968b72b421SJan Lentfer 	compare_pid,
197bcd4a7c1SJan Lentfer 	compare_ctime,
19850a55c46SMatthew Dillon 	compare_pres,
1997af1b2bcSJan Lentfer 	NULL
2007af1b2bcSJan Lentfer };
2017af1b2bcSJan Lentfer 
2027af1b2bcSJan Lentfer static void
2037af1b2bcSJan Lentfer cputime_percentages(int out[CPU_STATES], struct kinfo_cputime *new,
2047af1b2bcSJan Lentfer     struct kinfo_cputime *old)
2057af1b2bcSJan Lentfer {
2067af1b2bcSJan Lentfer 	struct kinfo_cputime diffs;
2077af1b2bcSJan Lentfer 	uint64_t total_change, half_total;
2087af1b2bcSJan Lentfer 
2097af1b2bcSJan Lentfer 	/* initialization */
2107af1b2bcSJan Lentfer 	total_change = 0;
2117af1b2bcSJan Lentfer 
2127af1b2bcSJan Lentfer 	diffs.cp_user = new->cp_user - old->cp_user;
2137af1b2bcSJan Lentfer 	diffs.cp_nice = new->cp_nice - old->cp_nice;
2147af1b2bcSJan Lentfer 	diffs.cp_sys = new->cp_sys - old->cp_sys;
2157af1b2bcSJan Lentfer 	diffs.cp_intr = new->cp_intr - old->cp_intr;
2167af1b2bcSJan Lentfer 	diffs.cp_idle = new->cp_idle - old->cp_idle;
2177af1b2bcSJan Lentfer 	total_change = diffs.cp_user + diffs.cp_nice + diffs.cp_sys +
2187af1b2bcSJan Lentfer 	    diffs.cp_intr + diffs.cp_idle;
2197af1b2bcSJan Lentfer 	old->cp_user = new->cp_user;
2207af1b2bcSJan Lentfer 	old->cp_nice = new->cp_nice;
2217af1b2bcSJan Lentfer 	old->cp_sys = new->cp_sys;
2227af1b2bcSJan Lentfer 	old->cp_intr = new->cp_intr;
2237af1b2bcSJan Lentfer 	old->cp_idle = new->cp_idle;
2247af1b2bcSJan Lentfer 
2257af1b2bcSJan Lentfer 	/* avoid divide by zero potential */
2267af1b2bcSJan Lentfer 	if (total_change == 0)
2277af1b2bcSJan Lentfer 		total_change = 1;
2287af1b2bcSJan Lentfer 
2297af1b2bcSJan Lentfer 	/* calculate percentages based on overall change, rounding up */
2307af1b2bcSJan Lentfer 	half_total = total_change >> 1;
2317af1b2bcSJan Lentfer 
2327af1b2bcSJan Lentfer 	out[0] = ((diffs.cp_user * 1000LL + half_total) / total_change);
2337af1b2bcSJan Lentfer 	out[1] = ((diffs.cp_nice * 1000LL + half_total) / total_change);
2347af1b2bcSJan Lentfer 	out[2] = ((diffs.cp_sys * 1000LL + half_total) / total_change);
2357af1b2bcSJan Lentfer 	out[3] = ((diffs.cp_intr * 1000LL + half_total) / total_change);
2367af1b2bcSJan Lentfer 	out[4] = ((diffs.cp_idle * 1000LL + half_total) / total_change);
2377af1b2bcSJan Lentfer }
2387af1b2bcSJan Lentfer 
2397af1b2bcSJan Lentfer int
2407af1b2bcSJan Lentfer machine_init(struct statics *statics)
2417af1b2bcSJan Lentfer {
2427af1b2bcSJan Lentfer 	int pagesize;
243b5121966SSepherosa Ziehau 	size_t modelen, prmlen;
2447af1b2bcSJan Lentfer 	struct passwd *pw;
2457af1b2bcSJan Lentfer 	struct timeval boottime;
2467af1b2bcSJan Lentfer 
2477af1b2bcSJan Lentfer 	if (n_cpus < 1) {
2487af1b2bcSJan Lentfer 		if (kinfo_get_cpus(&n_cpus))
2497af1b2bcSJan Lentfer 			err(1, "kinfo_get_cpus failed");
2507af1b2bcSJan Lentfer 	}
2517af1b2bcSJan Lentfer 	/* get boot time */
2527af1b2bcSJan Lentfer 	modelen = sizeof(boottime);
2537af1b2bcSJan Lentfer 	if (sysctlbyname("kern.boottime", &boottime, &modelen, NULL, 0) == -1) {
2547af1b2bcSJan Lentfer 		/* we have no boottime to report */
2557af1b2bcSJan Lentfer 		boottime.tv_sec = -1;
2567af1b2bcSJan Lentfer 	}
2577af1b2bcSJan Lentfer 
258b5121966SSepherosa Ziehau 	prmlen = sizeof(fscale);
259b5121966SSepherosa Ziehau 	if (sysctlbyname("kern.fscale", &fscale, &prmlen, NULL, 0) == -1)
26076ccf3d0SSepherosa Ziehau 		err(1, "sysctl kern.fscale failed");
261b5121966SSepherosa Ziehau 
2627af1b2bcSJan Lentfer 	while ((pw = getpwent()) != NULL) {
2637af1b2bcSJan Lentfer 		if ((int)strlen(pw->pw_name) > namelength)
2647af1b2bcSJan Lentfer 			namelength = strlen(pw->pw_name);
2657af1b2bcSJan Lentfer 	}
2667af1b2bcSJan Lentfer 	if (namelength < 8)
2677af1b2bcSJan Lentfer 		namelength = 8;
268975fc636SSascha Wildner 	if (namelength > 13)
2697af1b2bcSJan Lentfer 		namelength = 13;
2707af1b2bcSJan Lentfer 
271efde5811SJan Lentfer 	if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
2727af1b2bcSJan Lentfer 		return -1;
2737af1b2bcSJan Lentfer 
2747af1b2bcSJan Lentfer 	pbase = NULL;
2757af1b2bcSJan Lentfer 	pref = NULL;
2767af1b2bcSJan Lentfer 	nproc = 0;
2777af1b2bcSJan Lentfer 	onproc = -1;
278b5121966SSepherosa Ziehau 	prev_pbase = NULL;
27976ccf3d0SSepherosa Ziehau 	prev_pbase_alloc = 0;
28076ccf3d0SSepherosa Ziehau 	prev_pbase_time = 0;
28176ccf3d0SSepherosa Ziehau 	prev_nproc = 0;
282961f1f09SJan Lentfer 	/*
283961f1f09SJan Lentfer 	 * get the page size with "getpagesize" and calculate pageshift from
284961f1f09SJan Lentfer 	 * it
285961f1f09SJan Lentfer 	 */
2867af1b2bcSJan Lentfer 	pagesize = getpagesize();
2877af1b2bcSJan Lentfer 	pageshift = 0;
288961f1f09SJan Lentfer 	while (pagesize > 1) {
2897af1b2bcSJan Lentfer 		pageshift++;
2907af1b2bcSJan Lentfer 		pagesize >>= 1;
2917af1b2bcSJan Lentfer 	}
2927af1b2bcSJan Lentfer 
2937af1b2bcSJan Lentfer 	/* we only need the amount of log(2)1024 for our conversion */
2947af1b2bcSJan Lentfer 	pageshift -= LOG1024;
2957af1b2bcSJan Lentfer 
2967af1b2bcSJan Lentfer 	/* fill in the statics information */
2977af1b2bcSJan Lentfer 	statics->procstate_names = procstatenames;
2987af1b2bcSJan Lentfer 	statics->cpustate_names = cpustatenames;
2997af1b2bcSJan Lentfer 	statics->memory_names = memorynames;
3007af1b2bcSJan Lentfer 	statics->boottime = boottime.tv_sec;
3017af1b2bcSJan Lentfer 	statics->swap_names = swapnames;
3027af1b2bcSJan Lentfer 	statics->order_names = ordernames;
303efde5811SJan Lentfer 	/* we need kvm descriptor in order to show full commands */
304efde5811SJan Lentfer 	statics->flags.fullcmds = kd != NULL;
305cb68a542SAntonio Nikishaev 	statics->flags.threads = 1;
3067af1b2bcSJan Lentfer 
3077af1b2bcSJan Lentfer 	/* all done! */
3087af1b2bcSJan Lentfer 	return (0);
3097af1b2bcSJan Lentfer }
3107af1b2bcSJan Lentfer 
3117af1b2bcSJan Lentfer char *
3127af1b2bcSJan Lentfer format_header(char *uname_field)
3137af1b2bcSJan Lentfer {
3147af1b2bcSJan Lentfer 	static char Header[128];
3157af1b2bcSJan Lentfer 
316975fc636SSascha Wildner 	snprintf(Header, sizeof(Header), smp_header,
3177af1b2bcSJan Lentfer 	    namelength, namelength, uname_field);
3187af1b2bcSJan Lentfer 
3197af1b2bcSJan Lentfer 	if (screen_width <= 79)
3207af1b2bcSJan Lentfer 		cmdlength = 80;
3217af1b2bcSJan Lentfer 	else
3228b72b421SJan Lentfer 		cmdlength = screen_width;
3237af1b2bcSJan Lentfer 
3247af1b2bcSJan Lentfer 	cmdlength = cmdlength - strlen(Header) + 6;
3257af1b2bcSJan Lentfer 
3267af1b2bcSJan Lentfer 	return Header;
3277af1b2bcSJan Lentfer }
3287af1b2bcSJan Lentfer 
3297af1b2bcSJan Lentfer static int swappgsin = -1;
3307af1b2bcSJan Lentfer static int swappgsout = -1;
3317af1b2bcSJan Lentfer extern struct timeval timeout;
3327af1b2bcSJan Lentfer 
3337af1b2bcSJan Lentfer void
3347af1b2bcSJan Lentfer get_system_info(struct system_info *si)
3357af1b2bcSJan Lentfer {
3367af1b2bcSJan Lentfer 	size_t len;
3377af1b2bcSJan Lentfer 	int cpu;
3387af1b2bcSJan Lentfer 
3397af1b2bcSJan Lentfer 	if (cpu_states == NULL) {
3407af1b2bcSJan Lentfer 		cpu_states = malloc(sizeof(*cpu_states) * CPU_STATES * n_cpus);
3417af1b2bcSJan Lentfer 		if (cpu_states == NULL)
3427af1b2bcSJan Lentfer 			err(1, "malloc");
3437af1b2bcSJan Lentfer 		bzero(cpu_states, sizeof(*cpu_states) * CPU_STATES * n_cpus);
3447af1b2bcSJan Lentfer 	}
3457af1b2bcSJan Lentfer 	if (cp_time == NULL) {
3467af1b2bcSJan Lentfer 		cp_time = malloc(2 * n_cpus * sizeof(cp_time[0]));
3477af1b2bcSJan Lentfer 		if (cp_time == NULL)
3487af1b2bcSJan Lentfer 			err(1, "cp_time");
3497af1b2bcSJan Lentfer 		cp_old = cp_time + n_cpus;
3507af1b2bcSJan Lentfer 		len = n_cpus * sizeof(cp_old[0]);
3517af1b2bcSJan Lentfer 		bzero(cp_time, len);
3527af1b2bcSJan Lentfer 		if (sysctlbyname("kern.cputime", cp_old, &len, NULL, 0))
3537af1b2bcSJan Lentfer 			err(1, "kern.cputime");
3547af1b2bcSJan Lentfer 	}
3557af1b2bcSJan Lentfer 	len = n_cpus * sizeof(cp_time[0]);
3567af1b2bcSJan Lentfer 	bzero(cp_time, len);
3577af1b2bcSJan Lentfer 	if (sysctlbyname("kern.cputime", cp_time, &len, NULL, 0))
3587af1b2bcSJan Lentfer 		err(1, "kern.cputime");
3597af1b2bcSJan Lentfer 
3607af1b2bcSJan Lentfer 	getloadavg(si->load_avg, 3);
3617af1b2bcSJan Lentfer 
3627af1b2bcSJan Lentfer 	lastpid = 0;
3637af1b2bcSJan Lentfer 
3647af1b2bcSJan Lentfer 	/* convert cp_time counts to percentages */
365edc735acSJavier Alcázar 	int combine_cpus = (enable_ncpus == 0 && n_cpus > 1);
3667af1b2bcSJan Lentfer 	for (cpu = 0; cpu < n_cpus; ++cpu) {
3677af1b2bcSJan Lentfer 		cputime_percentages(cpu_states + cpu * CPU_STATES,
3687af1b2bcSJan Lentfer 		    &cp_time[cpu], &cp_old[cpu]);
3697af1b2bcSJan Lentfer 	}
370edc735acSJavier Alcázar 	if (combine_cpus) {
371edc735acSJavier Alcázar 		if (cpu_averages == NULL) {
372edc735acSJavier Alcázar 			cpu_averages = malloc(sizeof(*cpu_averages) * CPU_STATES);
373edc735acSJavier Alcázar 			if (cpu_averages == NULL)
374edc735acSJavier Alcázar 				err(1, "cpu_averages");
375edc735acSJavier Alcázar 		}
376edc735acSJavier Alcázar 		bzero(cpu_averages, sizeof(*cpu_averages) * CPU_STATES);
377edc735acSJavier Alcázar 		for (cpu = 0; cpu < n_cpus; ++cpu) {
378edc735acSJavier Alcázar 			int j = 0;
379edc735acSJavier Alcázar 			cpu_averages[0] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
380edc735acSJavier Alcázar 			cpu_averages[1] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
381edc735acSJavier Alcázar 			cpu_averages[2] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
382edc735acSJavier Alcázar 			cpu_averages[3] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
383edc735acSJavier Alcázar 			cpu_averages[4] += *(cpu_states + ((cpu * CPU_STATES) + j++) );
384edc735acSJavier Alcázar 		}
385edc735acSJavier Alcázar 		for (int i = 0; i < CPU_STATES; ++i)
386edc735acSJavier Alcázar 			cpu_averages[i] /= n_cpus;
387edc735acSJavier Alcázar 	}
3887af1b2bcSJan Lentfer 
3897af1b2bcSJan Lentfer 	/* sum memory & swap statistics */
3907af1b2bcSJan Lentfer 	{
3917af1b2bcSJan Lentfer 		struct vmmeter vmm;
3927af1b2bcSJan Lentfer 		struct vmstats vms;
3937af1b2bcSJan Lentfer 		size_t vms_size = sizeof(vms);
3947af1b2bcSJan Lentfer 		size_t vmm_size = sizeof(vmm);
3957af1b2bcSJan Lentfer 		static unsigned int swap_delay = 0;
3967af1b2bcSJan Lentfer 		static int swapavail = 0;
3977af1b2bcSJan Lentfer 		static int swapfree = 0;
3983583bbb4SMatthew Dillon 		static long bufspace = 0;
3997af1b2bcSJan Lentfer 
4007af1b2bcSJan Lentfer 		if (sysctlbyname("vm.vmstats", &vms, &vms_size, NULL, 0))
4017af1b2bcSJan Lentfer 			err(1, "sysctlbyname: vm.vmstats");
4027af1b2bcSJan Lentfer 
4037af1b2bcSJan Lentfer 		if (sysctlbyname("vm.vmmeter", &vmm, &vmm_size, NULL, 0))
4047af1b2bcSJan Lentfer 			err(1, "sysctlbyname: vm.vmmeter");
4057af1b2bcSJan Lentfer 
4067af1b2bcSJan Lentfer 		if (kinfo_get_vfs_bufspace(&bufspace))
4077af1b2bcSJan Lentfer 			err(1, "kinfo_get_vfs_bufspace");
4087af1b2bcSJan Lentfer 
4097af1b2bcSJan Lentfer 		/* convert memory stats to Kbytes */
4107af1b2bcSJan Lentfer 		memory_stats[0] = pagetok(vms.v_active_count);
4117af1b2bcSJan Lentfer 		memory_stats[1] = pagetok(vms.v_inactive_count);
4127af1b2bcSJan Lentfer 		memory_stats[2] = pagetok(vms.v_wire_count);
4137af1b2bcSJan Lentfer 		memory_stats[3] = pagetok(vms.v_cache_count);
4147af1b2bcSJan Lentfer 		memory_stats[4] = bufspace / 1024;
4157af1b2bcSJan Lentfer 		memory_stats[5] = pagetok(vms.v_free_count);
4167af1b2bcSJan Lentfer 		memory_stats[6] = -1;
4177af1b2bcSJan Lentfer 
4187af1b2bcSJan Lentfer 		/* first interval */
4197af1b2bcSJan Lentfer 		if (swappgsin < 0) {
4207af1b2bcSJan Lentfer 			swap_stats[4] = 0;
4217af1b2bcSJan Lentfer 			swap_stats[5] = 0;
4227af1b2bcSJan Lentfer 		}
4237af1b2bcSJan Lentfer 		/* compute differences between old and new swap statistic */
4247af1b2bcSJan Lentfer 		else {
4257af1b2bcSJan Lentfer 			swap_stats[4] = pagetok(((vmm.v_swappgsin - swappgsin)));
4267af1b2bcSJan Lentfer 			swap_stats[5] = pagetok(((vmm.v_swappgsout - swappgsout)));
4277af1b2bcSJan Lentfer 		}
4287af1b2bcSJan Lentfer 
4297af1b2bcSJan Lentfer 		swappgsin = vmm.v_swappgsin;
4307af1b2bcSJan Lentfer 		swappgsout = vmm.v_swappgsout;
4317af1b2bcSJan Lentfer 
4327af1b2bcSJan Lentfer 		/* call CPU heavy swapmode() only for changes */
4337af1b2bcSJan Lentfer 		if (swap_stats[4] > 0 || swap_stats[5] > 0 || swap_delay == 0) {
4347af1b2bcSJan Lentfer 			swap_stats[3] = swapmode(&swapavail, &swapfree);
4357af1b2bcSJan Lentfer 			swap_stats[0] = swapavail;
4367af1b2bcSJan Lentfer 			swap_stats[1] = swapavail - swapfree;
4377af1b2bcSJan Lentfer 			swap_stats[2] = swapfree;
4387af1b2bcSJan Lentfer 		}
4397af1b2bcSJan Lentfer 		swap_delay = 1;
4407af1b2bcSJan Lentfer 		swap_stats[6] = -1;
4417af1b2bcSJan Lentfer 	}
4427af1b2bcSJan Lentfer 
4437af1b2bcSJan Lentfer 	/* set arrays and strings */
444edc735acSJavier Alcázar 	si->cpustates = combine_cpus == 1 ?
445edc735acSJavier Alcázar 	    cpu_averages : cpu_states;
4467af1b2bcSJan Lentfer 	si->memory = memory_stats;
4477af1b2bcSJan Lentfer 	si->swap = swap_stats;
4487af1b2bcSJan Lentfer 
4497af1b2bcSJan Lentfer 
4507af1b2bcSJan Lentfer 	if (lastpid > 0) {
4517af1b2bcSJan Lentfer 		si->last_pid = lastpid;
4527af1b2bcSJan Lentfer 	} else {
4537af1b2bcSJan Lentfer 		si->last_pid = -1;
4547af1b2bcSJan Lentfer 	}
4557af1b2bcSJan Lentfer }
4567af1b2bcSJan Lentfer 
4577af1b2bcSJan Lentfer 
4587af1b2bcSJan Lentfer static struct handle handle;
4597af1b2bcSJan Lentfer 
460b5121966SSepherosa Ziehau static void
46176ccf3d0SSepherosa Ziehau fixup_pctcpu(struct kinfo_proc *fixit, uint64_t d)
462b5121966SSepherosa Ziehau {
463b5121966SSepherosa Ziehau 	struct kinfo_proc *pp;
46476ccf3d0SSepherosa Ziehau 	uint64_t ticks;
465685dc2e1SSepherosa Ziehau 	int i;
466b5121966SSepherosa Ziehau 
46776ccf3d0SSepherosa Ziehau 	if (prev_nproc == 0 || d == 0)
468b5121966SSepherosa Ziehau 		return;
469b5121966SSepherosa Ziehau 
47076ccf3d0SSepherosa Ziehau 	if (LP(fixit, pid) == -1) {
47176ccf3d0SSepherosa Ziehau 		/* Skip kernel "idle" threads */
47276ccf3d0SSepherosa Ziehau 		if (PP(fixit, stat) == SIDL)
47376ccf3d0SSepherosa Ziehau 			return;
474b5121966SSepherosa Ziehau 		for (pp = prev_pbase, i = 0; i < prev_nproc; pp++, i++) {
47576ccf3d0SSepherosa Ziehau 			if (LP(pp, pid) == -1 &&
47676ccf3d0SSepherosa Ziehau 			    PP(pp, ktaddr) == PP(fixit, ktaddr))
47776ccf3d0SSepherosa Ziehau 				break;
47876ccf3d0SSepherosa Ziehau 		}
47976ccf3d0SSepherosa Ziehau 	} else {
48076ccf3d0SSepherosa Ziehau 		for (pp = prev_pbase, i = 0; i < prev_nproc; pp++, i++) {
48176ccf3d0SSepherosa Ziehau 			if (LP(pp, pid) == LP(fixit, pid) &&
48276ccf3d0SSepherosa Ziehau 			    LP(pp, tid) == LP(fixit, tid)) {
48376ccf3d0SSepherosa Ziehau 				if (PP(pp, paddr) != PP(fixit, paddr)) {
48476ccf3d0SSepherosa Ziehau 					/* pid/tid are reused */
48576ccf3d0SSepherosa Ziehau 					pp = NULL;
48676ccf3d0SSepherosa Ziehau 				}
487b5121966SSepherosa Ziehau 				break;
488b5121966SSepherosa Ziehau 			}
489b5121966SSepherosa Ziehau 		}
490b5121966SSepherosa Ziehau 	}
49176ccf3d0SSepherosa Ziehau 	if (i == prev_nproc || pp == NULL)
49276ccf3d0SSepherosa Ziehau 		return;
49376ccf3d0SSepherosa Ziehau 
49476ccf3d0SSepherosa Ziehau 	ticks = LP(fixit, iticks) - LP(pp, iticks);
49576ccf3d0SSepherosa Ziehau 	ticks += LP(fixit, sticks) - LP(pp, sticks);
49676ccf3d0SSepherosa Ziehau 	ticks += LP(fixit, uticks) - LP(pp, uticks);
497*5deae5c6SMatthew Dillon 	if (ticks > d * 1000)
498*5deae5c6SMatthew Dillon 		ticks = d * 1000;
49976ccf3d0SSepherosa Ziehau 	LP(fixit, pctcpu) = (ticks * (uint64_t)fscale) / d;
50076ccf3d0SSepherosa Ziehau }
501b5121966SSepherosa Ziehau 
502961f1f09SJan Lentfer caddr_t
503961f1f09SJan Lentfer get_process_info(struct system_info *si, struct process_select *sel,
5047af1b2bcSJan Lentfer     int compare_index)
5057af1b2bcSJan Lentfer {
50676ccf3d0SSepherosa Ziehau 	struct timespec tv;
50776ccf3d0SSepherosa Ziehau 	uint64_t t, d = 0;
50876ccf3d0SSepherosa Ziehau 
5097af1b2bcSJan Lentfer 	int i;
5107af1b2bcSJan Lentfer 	int total_procs;
5117af1b2bcSJan Lentfer 	int active_procs;
5127af1b2bcSJan Lentfer 	struct kinfo_proc **prefp;
5137af1b2bcSJan Lentfer 	struct kinfo_proc *pp;
5147af1b2bcSJan Lentfer 
5157af1b2bcSJan Lentfer 	/* these are copied out of sel for speed */
5167af1b2bcSJan Lentfer 	int show_idle;
5177af1b2bcSJan Lentfer 	int show_system;
5187af1b2bcSJan Lentfer 	int show_uid;
519b0b07bbbSAlex Hornung 	int show_threads;
520ea03a758SImre Vadász 	char *match_command;
521b0b07bbbSAlex Hornung 
522b0b07bbbSAlex Hornung 	show_threads = sel->threads;
5237af1b2bcSJan Lentfer 
524b0b07bbbSAlex Hornung 	pbase = kvm_getprocs(kd,
525b0b07bbbSAlex Hornung 	    KERN_PROC_ALL | (show_threads ? KERN_PROC_FLAG_LWP : 0), 0, &nproc);
5267af1b2bcSJan Lentfer 	if (nproc > onproc)
5277af1b2bcSJan Lentfer 		pref = (struct kinfo_proc **)realloc(pref, sizeof(struct kinfo_proc *)
5287af1b2bcSJan Lentfer 		    * (onproc = nproc));
5297af1b2bcSJan Lentfer 	if (pref == NULL || pbase == NULL) {
5307af1b2bcSJan Lentfer 		(void)fprintf(stderr, "top: Out of memory.\n");
5317af1b2bcSJan Lentfer 		quit(23);
5327af1b2bcSJan Lentfer 	}
53376ccf3d0SSepherosa Ziehau 
53476ccf3d0SSepherosa Ziehau 	clock_gettime(CLOCK_MONOTONIC_PRECISE, &tv);
53576ccf3d0SSepherosa Ziehau 	t = (tv.tv_sec * 1000000ULL) + (tv.tv_nsec / 1000ULL);
53676ccf3d0SSepherosa Ziehau 	if (prev_pbase_time > 0 && t > prev_pbase_time)
53776ccf3d0SSepherosa Ziehau 		d = t - prev_pbase_time;
53876ccf3d0SSepherosa Ziehau 
5397af1b2bcSJan Lentfer 	/* get a pointer to the states summary array */
5407af1b2bcSJan Lentfer 	si->procstates = process_states;
5417af1b2bcSJan Lentfer 
5427af1b2bcSJan Lentfer 	/* set up flags which define what we are going to select */
5437af1b2bcSJan Lentfer 	show_idle = sel->idle;
5447af1b2bcSJan Lentfer 	show_system = sel->system;
5457af1b2bcSJan Lentfer 	show_uid = sel->uid != -1;
546efde5811SJan Lentfer 	show_fullcmd = sel->fullcmd;
547ea03a758SImre Vadász 	match_command = sel->command;
5487af1b2bcSJan Lentfer 
5497af1b2bcSJan Lentfer 	/* count up process states and get pointers to interesting procs */
5507af1b2bcSJan Lentfer 	total_procs = 0;
5517af1b2bcSJan Lentfer 	active_procs = 0;
5527af1b2bcSJan Lentfer 	memset((char *)process_states, 0, sizeof(process_states));
5537af1b2bcSJan Lentfer 	prefp = pref;
554961f1f09SJan Lentfer 	for (pp = pbase, i = 0; i < nproc; pp++, i++) {
5557af1b2bcSJan Lentfer 		/*
5567af1b2bcSJan Lentfer 		 * Place pointers to each valid proc structure in pref[].
5577af1b2bcSJan Lentfer 		 * Process slots that are actually in use have a non-zero
5587af1b2bcSJan Lentfer 		 * status field.  Processes with P_SYSTEM set are system
5597af1b2bcSJan Lentfer 		 * processes---these get ignored unless show_sysprocs is set.
5607af1b2bcSJan Lentfer 		 */
561bfb09e3bSMatthew Dillon 		if ((show_system && (LP(pp, pid) == -1)) ||
562961f1f09SJan Lentfer 		    (show_system || ((PP(pp, flags) & P_SYSTEM) == 0))) {
5630ce28ef3SJoris Giovannangeli 			int lpstate = LP(pp, stat);
5640ce28ef3SJoris Giovannangeli 			int pstate = PP(pp, stat);
565d6eee517SMatthew Dillon 
5667af1b2bcSJan Lentfer 			total_procs++;
5670ce28ef3SJoris Giovannangeli 			if (lpstate == LSRUN)
568bc40e61dSStathis Kamperis 				process_states[0]++;
5690ce28ef3SJoris Giovannangeli 			if (pstate >= 0 && pstate < MAXPSTATES - 1)
570d6eee517SMatthew Dillon 				process_states[pstate]++;
57176ccf3d0SSepherosa Ziehau 
57276ccf3d0SSepherosa Ziehau 			if (match_command != NULL &&
57376ccf3d0SSepherosa Ziehau 			    strstr(PP(pp, comm), match_command) == NULL) {
57476ccf3d0SSepherosa Ziehau 				/* Command does not match */
57576ccf3d0SSepherosa Ziehau 				continue;
57676ccf3d0SSepherosa Ziehau 			}
57776ccf3d0SSepherosa Ziehau 
57876ccf3d0SSepherosa Ziehau 			if (show_uid && PP(pp, ruid) != (uid_t)sel->uid) {
57976ccf3d0SSepherosa Ziehau 				/* UID does not match */
58076ccf3d0SSepherosa Ziehau 				continue;
58176ccf3d0SSepherosa Ziehau 			}
58276ccf3d0SSepherosa Ziehau 
58376ccf3d0SSepherosa Ziehau 			if (!show_system && LP(pp, pid) == -1) {
58476ccf3d0SSepherosa Ziehau 				/* Don't show system processes */
58576ccf3d0SSepherosa Ziehau 				continue;
58676ccf3d0SSepherosa Ziehau 			}
58776ccf3d0SSepherosa Ziehau 
58876ccf3d0SSepherosa Ziehau 			/* Fix up pctcpu before show_idle test */
58976ccf3d0SSepherosa Ziehau 			fixup_pctcpu(pp, d);
59076ccf3d0SSepherosa Ziehau 
59176ccf3d0SSepherosa Ziehau 			if (!show_idle && LP(pp, pctcpu) == 0 &&
59276ccf3d0SSepherosa Ziehau 			    lpstate != LSRUN) {
59376ccf3d0SSepherosa Ziehau 				/* Don't show idle processes */
59476ccf3d0SSepherosa Ziehau 				continue;
59576ccf3d0SSepherosa Ziehau 			}
59676ccf3d0SSepherosa Ziehau 
5977af1b2bcSJan Lentfer 			*prefp++ = pp;
5987af1b2bcSJan Lentfer 			active_procs++;
5997af1b2bcSJan Lentfer 		}
6007af1b2bcSJan Lentfer 	}
6017af1b2bcSJan Lentfer 
60276ccf3d0SSepherosa Ziehau 	/*
60376ccf3d0SSepherosa Ziehau 	 * Save kinfo_procs for later pctcpu fixup.
60476ccf3d0SSepherosa Ziehau 	 */
60576ccf3d0SSepherosa Ziehau 	if (prev_pbase_alloc < nproc) {
60676ccf3d0SSepherosa Ziehau 		prev_pbase_alloc = nproc;
607b5121966SSepherosa Ziehau 		prev_pbase = realloc(prev_pbase,
60876ccf3d0SSepherosa Ziehau 		    prev_pbase_alloc * sizeof(struct kinfo_proc));
609b5121966SSepherosa Ziehau 		if (prev_pbase == NULL) {
610b5121966SSepherosa Ziehau 			fprintf(stderr, "top: Out of memory.\n");
611b5121966SSepherosa Ziehau 			quit(23);
612b5121966SSepherosa Ziehau 		}
613b5121966SSepherosa Ziehau 	}
61476ccf3d0SSepherosa Ziehau 	prev_nproc = nproc;
615b5121966SSepherosa Ziehau 	prev_pbase_time = t;
616b5121966SSepherosa Ziehau 	memcpy(prev_pbase, pbase, nproc * sizeof(struct kinfo_proc));
617b5121966SSepherosa Ziehau 
6187af1b2bcSJan Lentfer 	qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *),
6198b72b421SJan Lentfer 	    (int (*)(const void *, const void *))proc_compares[compare_index]);
6207af1b2bcSJan Lentfer 
6217af1b2bcSJan Lentfer 	/* remember active and total counts */
6227af1b2bcSJan Lentfer 	si->p_total = total_procs;
6237af1b2bcSJan Lentfer 	si->p_active = pref_len = active_procs;
6247af1b2bcSJan Lentfer 
6257af1b2bcSJan Lentfer 	/* pass back a handle */
6267af1b2bcSJan Lentfer 	handle.next_proc = pref;
6277af1b2bcSJan Lentfer 	handle.remaining = active_procs;
6280ca59c34SSepherosa Ziehau 	handle.show_threads = show_threads;
6297af1b2bcSJan Lentfer 	return ((caddr_t) & handle);
6307af1b2bcSJan Lentfer }
6317af1b2bcSJan Lentfer 
632cef6b642SMatthew Dillon char fmt[MAX_COLS];		/* static area where result is built */
6337af1b2bcSJan Lentfer 
6347af1b2bcSJan Lentfer char *
6357af1b2bcSJan Lentfer format_next_process(caddr_t xhandle, char *(*get_userid) (int))
6367af1b2bcSJan Lentfer {
6377af1b2bcSJan Lentfer 	struct kinfo_proc *pp;
6387af1b2bcSJan Lentfer 	long cputime;
639bcd4a7c1SJan Lentfer 	long ccputime;
6407af1b2bcSJan Lentfer 	double pct;
6417af1b2bcSJan Lentfer 	struct handle *hp;
6427af1b2bcSJan Lentfer 	char status[16];
6437af1b2bcSJan Lentfer 	int state;
6447af1b2bcSJan Lentfer 	int xnice;
645efde5811SJan Lentfer 	char *comm;
646bcd4a7c1SJan Lentfer 	char cputime_fmt[10], ccputime_fmt[10];
6477af1b2bcSJan Lentfer 
6487af1b2bcSJan Lentfer 	/* find and remember the next proc structure */
6497af1b2bcSJan Lentfer 	hp = (struct handle *)xhandle;
6507af1b2bcSJan Lentfer 	pp = *(hp->next_proc++);
6517af1b2bcSJan Lentfer 	hp->remaining--;
6527af1b2bcSJan Lentfer 
6537af1b2bcSJan Lentfer 	/* get the process's command name */
654efde5811SJan Lentfer 	if (show_fullcmd) {
655cb68a542SAntonio Nikishaev 		char **comm_full = kvm_getargv(kd, pp, 0);
656cb68a542SAntonio Nikishaev 		if (comm_full != 0)
657cb68a542SAntonio Nikishaev 			comm = *comm_full;
658cb68a542SAntonio Nikishaev 		else
659826597b5SJohn Marino 			comm = PP(pp, comm);
6607af1b2bcSJan Lentfer 	}
661efde5811SJan Lentfer 	else {
662efde5811SJan Lentfer 		comm = PP(pp, comm);
663efde5811SJan Lentfer 	}
664efde5811SJan Lentfer 
665cb68a542SAntonio Nikishaev 	/* the actual field to display */
666cb68a542SAntonio Nikishaev 	char cmdfield[MAX_COLS];
667cb68a542SAntonio Nikishaev 
668cb68a542SAntonio Nikishaev 	if (PP(pp, flags) & P_SYSTEM) {
669cb68a542SAntonio Nikishaev 		/* system process */
670cb68a542SAntonio Nikishaev 		snprintf(cmdfield, sizeof cmdfield, "[%s]", comm);
6710ca59c34SSepherosa Ziehau 	} else if (hp->show_threads && PP(pp, nthreads) > 1) {
672cb68a542SAntonio Nikishaev 		/* display it as a thread */
6730ca59c34SSepherosa Ziehau 		if (strcmp(PP(pp, comm), LP(pp, comm)) == 0) {
6740ca59c34SSepherosa Ziehau 			snprintf(cmdfield, sizeof cmdfield, "%s{%d}", comm,
6750ca59c34SSepherosa Ziehau 			    LP(pp, tid));
6760ca59c34SSepherosa Ziehau 		} else {
6770ca59c34SSepherosa Ziehau 			/* show thread name in addition to tid */
6780ca59c34SSepherosa Ziehau 			snprintf(cmdfield, sizeof cmdfield, "%s{%d/%s}", comm,
6790ca59c34SSepherosa Ziehau 			    LP(pp, tid), LP(pp, comm));
6800ca59c34SSepherosa Ziehau 		}
681cb68a542SAntonio Nikishaev 	} else {
682cb68a542SAntonio Nikishaev 		snprintf(cmdfield, sizeof cmdfield, "%s", comm);
683cb68a542SAntonio Nikishaev 	}
684cb68a542SAntonio Nikishaev 
6857af1b2bcSJan Lentfer 	/*
6867af1b2bcSJan Lentfer 	 * Convert the process's runtime from microseconds to seconds.  This
687bcd4a7c1SJan Lentfer 	 * time includes the interrupt time to be in compliance with ps output.
6887af1b2bcSJan Lentfer 	 */
689bcd4a7c1SJan Lentfer 	cputime = (LP(pp, uticks) + LP(pp, sticks) + LP(pp, iticks)) / 1000000;
690bcd4a7c1SJan Lentfer 	ccputime = cputime + PP(pp, cru).ru_stime.tv_sec + PP(pp, cru).ru_utime.tv_sec;
691bcd4a7c1SJan Lentfer 	format_time(cputime, cputime_fmt, sizeof(cputime_fmt));
692bcd4a7c1SJan Lentfer 	format_time(ccputime, ccputime_fmt, sizeof(ccputime_fmt));
6937af1b2bcSJan Lentfer 
6947af1b2bcSJan Lentfer 	/* calculate the base for cpu percentages */
6957af1b2bcSJan Lentfer 	pct = pctdouble(LP(pp, pctcpu));
6967af1b2bcSJan Lentfer 
6977af1b2bcSJan Lentfer 	/* generate "STATE" field */
6987af1b2bcSJan Lentfer 	switch (state = LP(pp, stat)) {
6997af1b2bcSJan Lentfer 	case LSRUN:
700975fc636SSascha Wildner 		if (LP(pp, tdflags) & TDF_RUNNING)
7017af1b2bcSJan Lentfer 			sprintf(status, "CPU%d", LP(pp, cpuid));
7027af1b2bcSJan Lentfer 		else
7037af1b2bcSJan Lentfer 			strcpy(status, "RUN");
7047af1b2bcSJan Lentfer 		break;
7057af1b2bcSJan Lentfer 	case LSSLEEP:
7067af1b2bcSJan Lentfer 		if (LP(pp, wmesg) != NULL) {
7078ddceaf5SSamuel J. Greear 			sprintf(status, "%.8s", LP(pp, wmesg)); /* WMESGLEN */
7087af1b2bcSJan Lentfer 			break;
7097af1b2bcSJan Lentfer 		}
7107af1b2bcSJan Lentfer 		/* fall through */
7117af1b2bcSJan Lentfer 	default:
7127af1b2bcSJan Lentfer 
713e62ef63cSSascha Wildner 		if (state >= 0 && (unsigned)state < NELEM(state_abbrev))
7147af1b2bcSJan Lentfer 			sprintf(status, "%.6s", state_abbrev[(unsigned char)state]);
7157af1b2bcSJan Lentfer 		else
7167af1b2bcSJan Lentfer 			sprintf(status, "?%5d", state);
7177af1b2bcSJan Lentfer 		break;
7187af1b2bcSJan Lentfer 	}
7197af1b2bcSJan Lentfer 
7207af1b2bcSJan Lentfer 	if (PP(pp, stat) == SZOMB)
7217af1b2bcSJan Lentfer 		strcpy(status, "ZOMB");
7227af1b2bcSJan Lentfer 
7237af1b2bcSJan Lentfer 	/*
724961f1f09SJan Lentfer 	 * idle time 0 - 31 -> nice value +21 - +52 normal time      -> nice
725961f1f09SJan Lentfer 	 * value -20 - +20 real time 0 - 31 -> nice value -52 - -21 thread
726961f1f09SJan Lentfer 	 * 0 - 31 -> nice value -53 -
7277af1b2bcSJan Lentfer 	 */
7287af1b2bcSJan Lentfer 	switch (LP(pp, rtprio.type)) {
7297af1b2bcSJan Lentfer 	case RTP_PRIO_REALTIME:
7307af1b2bcSJan Lentfer 		xnice = PRIO_MIN - 1 - RTP_PRIO_MAX + LP(pp, rtprio.prio);
7317af1b2bcSJan Lentfer 		break;
7327af1b2bcSJan Lentfer 	case RTP_PRIO_IDLE:
7337af1b2bcSJan Lentfer 		xnice = PRIO_MAX + 1 + LP(pp, rtprio.prio);
7347af1b2bcSJan Lentfer 		break;
7357af1b2bcSJan Lentfer 	case RTP_PRIO_THREAD:
7367af1b2bcSJan Lentfer 		xnice = PRIO_MIN - 1 - RTP_PRIO_MAX - LP(pp, rtprio.prio);
7377af1b2bcSJan Lentfer 		break;
7387af1b2bcSJan Lentfer 	default:
7397af1b2bcSJan Lentfer 		xnice = PP(pp, nice);
7407af1b2bcSJan Lentfer 		break;
7417af1b2bcSJan Lentfer 	}
7427af1b2bcSJan Lentfer 
7437af1b2bcSJan Lentfer 	/* format this entry */
7447af1b2bcSJan Lentfer 	snprintf(fmt, sizeof(fmt),
745975fc636SSascha Wildner 	    smp_Proc_format,
7467af1b2bcSJan Lentfer 	    (int)PP(pp, pid),
7477af1b2bcSJan Lentfer 	    namelength, namelength,
7487af1b2bcSJan Lentfer 	    get_userid(PP(pp, ruid)),
7497af1b2bcSJan Lentfer 	    (int)xnice,
7507af1b2bcSJan Lentfer 	    format_k(PROCSIZE(pp)),
75130277d08SMatthew Dillon 	    format_k(pagetok(VP(pp, rssize))),
7527af1b2bcSJan Lentfer 	    status,
753975fc636SSascha Wildner 	    LP(pp, cpuid),
754bcd4a7c1SJan Lentfer 	    cputime_fmt,
755bcd4a7c1SJan Lentfer 	    ccputime_fmt,
7567af1b2bcSJan Lentfer 	    100.0 * pct,
7577af1b2bcSJan Lentfer 	    cmdlength,
758cb68a542SAntonio Nikishaev 	    cmdfield);
7597af1b2bcSJan Lentfer 
7607af1b2bcSJan Lentfer 	/* return the result */
7617af1b2bcSJan Lentfer 	return (fmt);
7627af1b2bcSJan Lentfer }
7637af1b2bcSJan Lentfer 
7647af1b2bcSJan Lentfer /* comparison routines for qsort */
7657af1b2bcSJan Lentfer 
7667af1b2bcSJan Lentfer /*
7677af1b2bcSJan Lentfer  *  proc_compare - comparison function for "qsort"
7687af1b2bcSJan Lentfer  *	Compares the resource consumption of two processes using five
7697af1b2bcSJan Lentfer  *  	distinct keys.  The keys (in descending order of importance) are:
7707af1b2bcSJan Lentfer  *  	percent cpu, cpu ticks, state, resident set size, total virtual
7717af1b2bcSJan Lentfer  *  	memory usage.  The process states are ordered as follows (from least
7727af1b2bcSJan Lentfer  *  	to most important):  WAIT, zombie, sleep, stop, start, run.  The
7737af1b2bcSJan Lentfer  *  	array declaration below maps a process state index into a number
7747af1b2bcSJan Lentfer  *  	that reflects this ordering.
7757af1b2bcSJan Lentfer  */
7767af1b2bcSJan Lentfer 
7777af1b2bcSJan Lentfer static unsigned char sorted_state[] =
7787af1b2bcSJan Lentfer {
7797af1b2bcSJan Lentfer 	0,			/* not used		 */
7807af1b2bcSJan Lentfer 	3,			/* sleep		 */
7817af1b2bcSJan Lentfer 	1,			/* ABANDONED (WAIT)	 */
7827af1b2bcSJan Lentfer 	6,			/* run			 */
7837af1b2bcSJan Lentfer 	5,			/* start		 */
7847af1b2bcSJan Lentfer 	2,			/* zombie		 */
7857af1b2bcSJan Lentfer 	4			/* stop			 */
7867af1b2bcSJan Lentfer };
7877af1b2bcSJan Lentfer 
7887af1b2bcSJan Lentfer 
7897af1b2bcSJan Lentfer #define ORDERKEY_PCTCPU \
7907af1b2bcSJan Lentfer   if (lresult = (long) LP(p2, pctcpu) - (long) LP(p1, pctcpu), \
7917af1b2bcSJan Lentfer      (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
7927af1b2bcSJan Lentfer 
793bcd4a7c1SJan Lentfer #define CPTICKS(p)	(LP(p, uticks) + LP(p, sticks) + LP(p, iticks))
7947af1b2bcSJan Lentfer 
7957af1b2bcSJan Lentfer #define ORDERKEY_CPTICKS \
7967af1b2bcSJan Lentfer   if ((result = CPTICKS(p2) > CPTICKS(p1) ? 1 : \
7977af1b2bcSJan Lentfer 		CPTICKS(p2) < CPTICKS(p1) ? -1 : 0) == 0)
7987af1b2bcSJan Lentfer 
799bcd4a7c1SJan Lentfer #define CTIME(p)	(((LP(p, uticks) + LP(p, sticks) + LP(p, iticks))/1000000) + \
800bcd4a7c1SJan Lentfer   PP(p, cru).ru_stime.tv_sec + PP(p, cru).ru_utime.tv_sec)
801bcd4a7c1SJan Lentfer 
802bcd4a7c1SJan Lentfer #define ORDERKEY_CTIME \
803bcd4a7c1SJan Lentfer    if ((result = CTIME(p2) > CTIME(p1) ? 1 : \
804bcd4a7c1SJan Lentfer 		CTIME(p2) < CTIME(p1) ? -1 : 0) == 0)
805bcd4a7c1SJan Lentfer 
8067af1b2bcSJan Lentfer #define ORDERKEY_STATE \
8077af1b2bcSJan Lentfer   if ((result = sorted_state[(unsigned char) PP(p2, stat)] - \
8087af1b2bcSJan Lentfer                 sorted_state[(unsigned char) PP(p1, stat)]) == 0)
8097af1b2bcSJan Lentfer 
8107af1b2bcSJan Lentfer #define ORDERKEY_PRIO \
8117af1b2bcSJan Lentfer   if ((result = LP(p2, prio) - LP(p1, prio)) == 0)
8127af1b2bcSJan Lentfer 
8137af1b2bcSJan Lentfer #define ORDERKEY_KTHREADS \
8147af1b2bcSJan Lentfer   if ((result = (LP(p1, pid) == 0) - (LP(p2, pid) == 0)) == 0)
8157af1b2bcSJan Lentfer 
8167af1b2bcSJan Lentfer #define ORDERKEY_KTHREADS_PRIO \
8177af1b2bcSJan Lentfer   if ((result = LP(p2, tdprio) - LP(p1, tdprio)) == 0)
8187af1b2bcSJan Lentfer 
8197af1b2bcSJan Lentfer #define ORDERKEY_RSSIZE \
8207af1b2bcSJan Lentfer   if ((result = VP(p2, rssize) - VP(p1, rssize)) == 0)
8217af1b2bcSJan Lentfer 
8227af1b2bcSJan Lentfer #define ORDERKEY_MEM \
8237af1b2bcSJan Lentfer   if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 )
8247af1b2bcSJan Lentfer 
8258b72b421SJan Lentfer #define ORDERKEY_PID \
8268b72b421SJan Lentfer   if ( (result = PP(p1, pid) - PP(p2, pid)) == 0)
8278b72b421SJan Lentfer 
82850a55c46SMatthew Dillon #define ORDERKEY_PRSSIZE \
82950a55c46SMatthew Dillon   if((result = VP(p2, prssize) - VP(p1, prssize)) == 0)
83050a55c46SMatthew Dillon 
831bfbef474SSepherosa Ziehau static __inline int
832bfbef474SSepherosa Ziehau orderkey_kernidle(const struct kinfo_proc *p1, const struct kinfo_proc *p2)
833bfbef474SSepherosa Ziehau {
834bfbef474SSepherosa Ziehau 	int p1_kidle = 0, p2_kidle = 0;
835bfbef474SSepherosa Ziehau 
836bfbef474SSepherosa Ziehau 	if (LP(p1, pid) == -1 && PP(p1, stat) == SIDL)
837bfbef474SSepherosa Ziehau 		p1_kidle = 1;
838bfbef474SSepherosa Ziehau 	if (LP(p2, pid) == -1 && PP(p2, stat) == SIDL)
839bfbef474SSepherosa Ziehau 		p2_kidle = 1;
840bfbef474SSepherosa Ziehau 
841bfbef474SSepherosa Ziehau 	if (!p2_kidle && p1_kidle)
842bfbef474SSepherosa Ziehau 		return 1;
843bfbef474SSepherosa Ziehau 	if (p2_kidle && !p1_kidle)
844bfbef474SSepherosa Ziehau 		return -1;
845bfbef474SSepherosa Ziehau 	return 0;
846bfbef474SSepherosa Ziehau }
847bfbef474SSepherosa Ziehau 
848bfbef474SSepherosa Ziehau #define ORDERKEY_KIDLE	if ((result = orderkey_kernidle(p1, p2)) == 0)
849bfbef474SSepherosa Ziehau 
8507af1b2bcSJan Lentfer /* compare_cpu - the comparison function for sorting by cpu percentage */
8517af1b2bcSJan Lentfer 
8527af1b2bcSJan Lentfer int
8538b72b421SJan Lentfer proc_compare(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
8547af1b2bcSJan Lentfer {
8558b72b421SJan Lentfer 	struct kinfo_proc *p1;
8568b72b421SJan Lentfer 	struct kinfo_proc *p2;
8577af1b2bcSJan Lentfer 	int result;
8587af1b2bcSJan Lentfer 	pctcpu lresult;
8597af1b2bcSJan Lentfer 
8607af1b2bcSJan Lentfer 	/* remove one level of indirection */
8618b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
8628b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
8637af1b2bcSJan Lentfer 
864bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
8657af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
8667af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
8677af1b2bcSJan Lentfer 	ORDERKEY_STATE
8687af1b2bcSJan Lentfer 	ORDERKEY_PRIO
8697af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
8707af1b2bcSJan Lentfer 	ORDERKEY_MEM
8717af1b2bcSJan Lentfer 	{}
8727af1b2bcSJan Lentfer 
8737af1b2bcSJan Lentfer 	return (result);
8747af1b2bcSJan Lentfer }
8757af1b2bcSJan Lentfer 
8767af1b2bcSJan Lentfer /* compare_size - the comparison function for sorting by total memory usage */
8777af1b2bcSJan Lentfer 
8787af1b2bcSJan Lentfer int
8798b72b421SJan Lentfer compare_size(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
8807af1b2bcSJan Lentfer {
8817af1b2bcSJan Lentfer 	struct kinfo_proc *p1;
8827af1b2bcSJan Lentfer 	struct kinfo_proc *p2;
8837af1b2bcSJan Lentfer 	int result;
8847af1b2bcSJan Lentfer 	pctcpu lresult;
8857af1b2bcSJan Lentfer 
8867af1b2bcSJan Lentfer 	/* remove one level of indirection */
8878b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
8888b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
8897af1b2bcSJan Lentfer 
8907af1b2bcSJan Lentfer 	ORDERKEY_MEM
8917af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
892bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
8937af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
8947af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
8957af1b2bcSJan Lentfer 	ORDERKEY_STATE
8967af1b2bcSJan Lentfer 	ORDERKEY_PRIO
8977af1b2bcSJan Lentfer 	{}
8987af1b2bcSJan Lentfer 
8997af1b2bcSJan Lentfer 	return (result);
9007af1b2bcSJan Lentfer }
9017af1b2bcSJan Lentfer 
9027af1b2bcSJan Lentfer /* compare_res - the comparison function for sorting by resident set size */
9037af1b2bcSJan Lentfer 
9047af1b2bcSJan Lentfer int
9058b72b421SJan Lentfer compare_res(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
9067af1b2bcSJan Lentfer {
9077af1b2bcSJan Lentfer 	struct kinfo_proc *p1;
9087af1b2bcSJan Lentfer 	struct kinfo_proc *p2;
9097af1b2bcSJan Lentfer 	int result;
9107af1b2bcSJan Lentfer 	pctcpu lresult;
9117af1b2bcSJan Lentfer 
9127af1b2bcSJan Lentfer 	/* remove one level of indirection */
9138b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
9148b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
9157af1b2bcSJan Lentfer 
9167af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
9177af1b2bcSJan Lentfer 	ORDERKEY_MEM
918bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
9197af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
9207af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
9217af1b2bcSJan Lentfer 	ORDERKEY_STATE
9227af1b2bcSJan Lentfer 	ORDERKEY_PRIO
9237af1b2bcSJan Lentfer 	{}
9247af1b2bcSJan Lentfer 
9257af1b2bcSJan Lentfer 	return (result);
9267af1b2bcSJan Lentfer }
9277af1b2bcSJan Lentfer 
92850a55c46SMatthew Dillon /* compare_pres - the comparison function for sorting by proportional resident set size */
92950a55c46SMatthew Dillon 
93050a55c46SMatthew Dillon int
93150a55c46SMatthew Dillon compare_pres(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
93250a55c46SMatthew Dillon {
93350a55c46SMatthew Dillon 	struct kinfo_proc *p1;
93450a55c46SMatthew Dillon 	struct kinfo_proc *p2;
93550a55c46SMatthew Dillon 	int result;
93650a55c46SMatthew Dillon 	pctcpu lresult;
93750a55c46SMatthew Dillon 
93850a55c46SMatthew Dillon 	/* remove one level of indirection */
93950a55c46SMatthew Dillon 	p1 = *(struct kinfo_proc **) pp1;
94050a55c46SMatthew Dillon 	p2 = *(struct kinfo_proc **) pp2;
94150a55c46SMatthew Dillon 
94250a55c46SMatthew Dillon 	ORDERKEY_PRSSIZE
94350a55c46SMatthew Dillon 	ORDERKEY_RSSIZE
94450a55c46SMatthew Dillon 	ORDERKEY_MEM
945bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
94650a55c46SMatthew Dillon 	ORDERKEY_PCTCPU
94750a55c46SMatthew Dillon 	ORDERKEY_CPTICKS
94850a55c46SMatthew Dillon 	ORDERKEY_STATE
94950a55c46SMatthew Dillon 	ORDERKEY_PRIO
95050a55c46SMatthew Dillon 	{}
95150a55c46SMatthew Dillon 
95250a55c46SMatthew Dillon 	return (result);
95350a55c46SMatthew Dillon }
95450a55c46SMatthew Dillon 
9557af1b2bcSJan Lentfer /* compare_time - the comparison function for sorting by total cpu time */
9567af1b2bcSJan Lentfer 
9577af1b2bcSJan Lentfer int
9588b72b421SJan Lentfer compare_time(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
9597af1b2bcSJan Lentfer {
9608b72b421SJan Lentfer 	struct kinfo_proc *p1;
9618b72b421SJan Lentfer 	struct kinfo_proc *p2;
9627af1b2bcSJan Lentfer 	int result;
9637af1b2bcSJan Lentfer 	pctcpu lresult;
9647af1b2bcSJan Lentfer 
9657af1b2bcSJan Lentfer 	/* remove one level of indirection */
9668b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
9678b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
9687af1b2bcSJan Lentfer 
969bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
9707af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
9717af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
9727af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS
9737af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS_PRIO
9747af1b2bcSJan Lentfer 	ORDERKEY_STATE
9757af1b2bcSJan Lentfer 	ORDERKEY_PRIO
9767af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
9777af1b2bcSJan Lentfer 	ORDERKEY_MEM
9787af1b2bcSJan Lentfer 	{}
9797af1b2bcSJan Lentfer 
9807af1b2bcSJan Lentfer 	return (result);
9817af1b2bcSJan Lentfer }
9827af1b2bcSJan Lentfer 
983bcd4a7c1SJan Lentfer int
984bcd4a7c1SJan Lentfer compare_ctime(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
985bcd4a7c1SJan Lentfer {
986bcd4a7c1SJan Lentfer 	struct kinfo_proc *p1;
987bcd4a7c1SJan Lentfer 	struct kinfo_proc *p2;
988bcd4a7c1SJan Lentfer 	int result;
989bcd4a7c1SJan Lentfer 	pctcpu lresult;
990bcd4a7c1SJan Lentfer 
991bcd4a7c1SJan Lentfer 	/* remove one level of indirection */
992bcd4a7c1SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
993bcd4a7c1SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
994bcd4a7c1SJan Lentfer 
995bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
996bcd4a7c1SJan Lentfer 	ORDERKEY_CTIME
997bcd4a7c1SJan Lentfer 	ORDERKEY_PCTCPU
998bcd4a7c1SJan Lentfer 	ORDERKEY_KTHREADS
999bcd4a7c1SJan Lentfer 	ORDERKEY_KTHREADS_PRIO
1000bcd4a7c1SJan Lentfer 	ORDERKEY_STATE
1001bcd4a7c1SJan Lentfer 	ORDERKEY_PRIO
1002bcd4a7c1SJan Lentfer 	ORDERKEY_RSSIZE
1003bcd4a7c1SJan Lentfer 	ORDERKEY_MEM
1004bcd4a7c1SJan Lentfer 	{}
1005bcd4a7c1SJan Lentfer 
1006bcd4a7c1SJan Lentfer 	return (result);
1007bcd4a7c1SJan Lentfer }
1008bcd4a7c1SJan Lentfer 
10097af1b2bcSJan Lentfer /* compare_prio - the comparison function for sorting by cpu percentage */
10107af1b2bcSJan Lentfer 
10117af1b2bcSJan Lentfer int
10128b72b421SJan Lentfer compare_prio(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
10137af1b2bcSJan Lentfer {
10148b72b421SJan Lentfer 	struct kinfo_proc *p1;
10158b72b421SJan Lentfer 	struct kinfo_proc *p2;
10167af1b2bcSJan Lentfer 	int result;
10177af1b2bcSJan Lentfer 	pctcpu lresult;
10187af1b2bcSJan Lentfer 
10197af1b2bcSJan Lentfer 	/* remove one level of indirection */
10208b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
10218b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
10227af1b2bcSJan Lentfer 
10237af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS
10247af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS_PRIO
10257af1b2bcSJan Lentfer 	ORDERKEY_PRIO
1026bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
10277af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
10287af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
10297af1b2bcSJan Lentfer 	ORDERKEY_STATE
10307af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
10317af1b2bcSJan Lentfer 	ORDERKEY_MEM
10327af1b2bcSJan Lentfer 	{}
10337af1b2bcSJan Lentfer 
10347af1b2bcSJan Lentfer 	return (result);
10357af1b2bcSJan Lentfer }
10367af1b2bcSJan Lentfer 
10377af1b2bcSJan Lentfer int
10388b72b421SJan Lentfer compare_thr(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
10397af1b2bcSJan Lentfer {
10408b72b421SJan Lentfer 	struct kinfo_proc *p1;
10418b72b421SJan Lentfer 	struct kinfo_proc *p2;
10427af1b2bcSJan Lentfer 	int result;
10437af1b2bcSJan Lentfer 	pctcpu lresult;
10447af1b2bcSJan Lentfer 
10457af1b2bcSJan Lentfer 	/* remove one level of indirection */
10468b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **)pp1;
10478b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **)pp2;
10487af1b2bcSJan Lentfer 
10497af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS
10507af1b2bcSJan Lentfer 	ORDERKEY_KTHREADS_PRIO
1051bfbef474SSepherosa Ziehau 	ORDERKEY_KIDLE
10527af1b2bcSJan Lentfer 	ORDERKEY_CPTICKS
10537af1b2bcSJan Lentfer 	ORDERKEY_PCTCPU
10547af1b2bcSJan Lentfer 	ORDERKEY_STATE
10557af1b2bcSJan Lentfer 	ORDERKEY_RSSIZE
10567af1b2bcSJan Lentfer 	ORDERKEY_MEM
10577af1b2bcSJan Lentfer 	{}
10587af1b2bcSJan Lentfer 
10597af1b2bcSJan Lentfer 	return (result);
10607af1b2bcSJan Lentfer }
10617af1b2bcSJan Lentfer 
10628b72b421SJan Lentfer /* compare_pid - the comparison function for sorting by process id */
10638b72b421SJan Lentfer 
10648b72b421SJan Lentfer int
10658b72b421SJan Lentfer compare_pid(struct kinfo_proc **pp1, struct kinfo_proc **pp2)
10668b72b421SJan Lentfer {
10678b72b421SJan Lentfer 	struct kinfo_proc *p1;
10688b72b421SJan Lentfer 	struct kinfo_proc *p2;
10698b72b421SJan Lentfer 	int result;
10708b72b421SJan Lentfer 
10718b72b421SJan Lentfer 	/* remove one level of indirection */
10728b72b421SJan Lentfer 	p1 = *(struct kinfo_proc **) pp1;
10738b72b421SJan Lentfer 	p2 = *(struct kinfo_proc **) pp2;
10748b72b421SJan Lentfer 
10758b72b421SJan Lentfer 	ORDERKEY_PID
10768b72b421SJan Lentfer 	;
10778b72b421SJan Lentfer 
10788b72b421SJan Lentfer 	return(result);
10798b72b421SJan Lentfer }
10808b72b421SJan Lentfer 
10817af1b2bcSJan Lentfer /*
10827af1b2bcSJan Lentfer  * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
10837af1b2bcSJan Lentfer  *		the process does not exist.
10847af1b2bcSJan Lentfer  *		It is EXTREMLY IMPORTANT that this function work correctly.
10857af1b2bcSJan Lentfer  *		If top runs setuid root (as in SVR4), then this function
10867af1b2bcSJan Lentfer  *		is the only thing that stands in the way of a serious
10877af1b2bcSJan Lentfer  *		security problem.  It validates requests for the "kill"
10887af1b2bcSJan Lentfer  *		and "renice" commands.
10897af1b2bcSJan Lentfer  */
10907af1b2bcSJan Lentfer 
10917af1b2bcSJan Lentfer int
10927af1b2bcSJan Lentfer proc_owner(int pid)
10937af1b2bcSJan Lentfer {
10947af1b2bcSJan Lentfer 	int xcnt;
10957af1b2bcSJan Lentfer 	struct kinfo_proc **prefp;
10967af1b2bcSJan Lentfer 	struct kinfo_proc *pp;
10977af1b2bcSJan Lentfer 
10987af1b2bcSJan Lentfer 	prefp = pref;
10997af1b2bcSJan Lentfer 	xcnt = pref_len;
1100961f1f09SJan Lentfer 	while (--xcnt >= 0) {
11017af1b2bcSJan Lentfer 		pp = *prefp++;
1102961f1f09SJan Lentfer 		if (PP(pp, pid) == (pid_t) pid) {
11037af1b2bcSJan Lentfer 			return ((int)PP(pp, ruid));
11047af1b2bcSJan Lentfer 		}
11057af1b2bcSJan Lentfer 	}
11067af1b2bcSJan Lentfer 	return (-1);
11077af1b2bcSJan Lentfer }
11087af1b2bcSJan Lentfer 
11097af1b2bcSJan Lentfer 
11107af1b2bcSJan Lentfer /*
11117af1b2bcSJan Lentfer  * swapmode is based on a program called swapinfo written
11127af1b2bcSJan Lentfer  * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
11137af1b2bcSJan Lentfer  */
11147af1b2bcSJan Lentfer int
11157af1b2bcSJan Lentfer swapmode(int *retavail, int *retfree)
11167af1b2bcSJan Lentfer {
11177af1b2bcSJan Lentfer 	int n;
11187af1b2bcSJan Lentfer 	int pagesize = getpagesize();
11197af1b2bcSJan Lentfer 	struct kvm_swap swapary[1];
11207af1b2bcSJan Lentfer 
11217af1b2bcSJan Lentfer 	*retavail = 0;
11227af1b2bcSJan Lentfer 	*retfree = 0;
11237af1b2bcSJan Lentfer 
11247af1b2bcSJan Lentfer #define CONVERT(v)	((quad_t)(v) * pagesize / 1024)
11257af1b2bcSJan Lentfer 
11267af1b2bcSJan Lentfer 	n = kvm_getswapinfo(kd, swapary, 1, 0);
11277af1b2bcSJan Lentfer 	if (n < 0 || swapary[0].ksw_total == 0)
11287af1b2bcSJan Lentfer 		return (0);
11297af1b2bcSJan Lentfer 
11307af1b2bcSJan Lentfer 	*retavail = CONVERT(swapary[0].ksw_total);
11317af1b2bcSJan Lentfer 	*retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
11327af1b2bcSJan Lentfer 
11337af1b2bcSJan Lentfer 	n = (int)((double)swapary[0].ksw_used * 100.0 /
11347af1b2bcSJan Lentfer 	    (double)swapary[0].ksw_total);
11357af1b2bcSJan Lentfer 	return (n);
11367af1b2bcSJan Lentfer }
1137