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