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 * $DragonFly: src/usr.bin/top/machine.c,v 1.26 2008/10/16 01:52:33 swildner Exp $ 247af1b2bcSJan Lentfer */ 257af1b2bcSJan Lentfer 26e0ecab34SMatthew Dillon #include <sys/user.h> 277af1b2bcSJan Lentfer #include <sys/types.h> 28e0ecab34SMatthew Dillon #include <sys/time.h> 297af1b2bcSJan Lentfer #include <sys/signal.h> 307af1b2bcSJan Lentfer #include <sys/param.h> 317af1b2bcSJan Lentfer 327af1b2bcSJan Lentfer #include "os.h" 337af1b2bcSJan Lentfer #include <err.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/file.h> 427af1b2bcSJan Lentfer #include <sys/vmmeter.h> 437af1b2bcSJan Lentfer #include <sys/resource.h> 447af1b2bcSJan Lentfer #include <sys/rtprio.h> 457af1b2bcSJan Lentfer 467af1b2bcSJan Lentfer /* Swap */ 477af1b2bcSJan Lentfer #include <stdlib.h> 487af1b2bcSJan Lentfer #include <stdio.h> 497af1b2bcSJan Lentfer #include <sys/conf.h> 507af1b2bcSJan Lentfer 517af1b2bcSJan Lentfer #include <osreldate.h> /* for changes in kernel structures */ 527af1b2bcSJan Lentfer 537af1b2bcSJan Lentfer #include <sys/kinfo.h> 547af1b2bcSJan Lentfer #include <kinfo.h> 557af1b2bcSJan Lentfer #include "top.h" 567af1b2bcSJan Lentfer #include "display.h" 577af1b2bcSJan Lentfer #include "machine.h" 587af1b2bcSJan Lentfer #include "screen.h" 597af1b2bcSJan Lentfer #include "utils.h" 607af1b2bcSJan Lentfer 617af1b2bcSJan Lentfer int swapmode(int *retavail, int *retfree); 627af1b2bcSJan Lentfer static int smpmode; 637af1b2bcSJan Lentfer static int namelength; 647af1b2bcSJan Lentfer static int cmdlength; 65efde5811SJan Lentfer static int show_fullcmd; 667af1b2bcSJan Lentfer 677af1b2bcSJan Lentfer int n_cpus = 0; 687af1b2bcSJan Lentfer 697af1b2bcSJan Lentfer /* 70961f1f09SJan Lentfer * needs to be a global symbol, so wrapper can be modified accordingly. 717af1b2bcSJan Lentfer */ 727af1b2bcSJan Lentfer static int show_threads = 0; 737af1b2bcSJan Lentfer 747af1b2bcSJan Lentfer /* get_process_info passes back a handle. This is what it looks like: */ 757af1b2bcSJan Lentfer 76961f1f09SJan Lentfer struct handle { 777af1b2bcSJan Lentfer struct kinfo_proc **next_proc; /* points to next valid proc pointer */ 787af1b2bcSJan Lentfer int remaining; /* number of pointers remaining */ 797af1b2bcSJan Lentfer }; 807af1b2bcSJan Lentfer 817af1b2bcSJan Lentfer /* declarations for load_avg */ 827af1b2bcSJan Lentfer #include "loadavg.h" 837af1b2bcSJan Lentfer 847af1b2bcSJan Lentfer #define PP(pp, field) ((pp)->kp_ ## field) 857af1b2bcSJan Lentfer #define LP(pp, field) ((pp)->kp_lwp.kl_ ## field) 867af1b2bcSJan Lentfer #define VP(pp, field) ((pp)->kp_vm_ ## field) 877af1b2bcSJan Lentfer 887af1b2bcSJan Lentfer /* define what weighted cpu is. */ 897af1b2bcSJan Lentfer #define weighted_cpu(pct, pp) (PP((pp), swtime) == 0 ? 0.0 : \ 907af1b2bcSJan Lentfer ((pct) / (1.0 - exp(PP((pp), swtime) * logcpu)))) 917af1b2bcSJan Lentfer 927af1b2bcSJan Lentfer /* what we consider to be process size: */ 937af1b2bcSJan Lentfer #define PROCSIZE(pp) (VP((pp), map_size) / 1024) 947af1b2bcSJan Lentfer 957af1b2bcSJan Lentfer /* 967af1b2bcSJan Lentfer * These definitions control the format of the per-process area 977af1b2bcSJan Lentfer */ 987af1b2bcSJan Lentfer 997af1b2bcSJan Lentfer static char smp_header[] = 1009ac1ee6eSMatthew Dillon " PID %-*.*s NICE SIZE PRES STATE CPU TIME CTIME CPU COMMAND"; 1017af1b2bcSJan Lentfer 1027af1b2bcSJan Lentfer #define smp_Proc_format \ 1039ac1ee6eSMatthew Dillon "%5d %-*.*s %3d%7s %6s %7.7s %2d %6s %7s %5.2f%% %.*s" 1047af1b2bcSJan Lentfer 1057af1b2bcSJan Lentfer static char up_header[] = 10685512f7bSMatthew Dillon " PID %-*.*s NICE SIZE PRES STATE TIME CTIME CPU COMMAND"; 1077af1b2bcSJan Lentfer 1087af1b2bcSJan Lentfer #define up_Proc_format \ 10985512f7bSMatthew Dillon "%5d %-*.*s %3d%7s %6s %7.7s%.0d %7s %7s %5.2f%% %.*s" 1107af1b2bcSJan Lentfer 1117af1b2bcSJan Lentfer 1127af1b2bcSJan Lentfer /* process state names for the "STATE" column of the display */ 113961f1f09SJan Lentfer /* 114961f1f09SJan Lentfer * the extra nulls in the string "run" are for adding a slash and the 115961f1f09SJan Lentfer * processor number when needed 116961f1f09SJan Lentfer */ 1177af1b2bcSJan Lentfer 118961f1f09SJan Lentfer const char *state_abbrev[] = { 1197af1b2bcSJan Lentfer "", "RUN\0\0\0", "STOP", "SLEEP", 1207af1b2bcSJan Lentfer }; 1217af1b2bcSJan Lentfer 1227af1b2bcSJan Lentfer 1237af1b2bcSJan Lentfer static kvm_t *kd; 1247af1b2bcSJan Lentfer 1257af1b2bcSJan Lentfer /* values that we stash away in _init and use in later routines */ 1267af1b2bcSJan Lentfer 1277af1b2bcSJan Lentfer static double logcpu; 1287af1b2bcSJan Lentfer 1297af1b2bcSJan Lentfer static long lastpid; 1307af1b2bcSJan Lentfer static int ccpu; 1317af1b2bcSJan Lentfer 1327af1b2bcSJan Lentfer /* these are for calculating cpu state percentages */ 1337af1b2bcSJan Lentfer 1347af1b2bcSJan Lentfer static struct kinfo_cputime *cp_time, *cp_old; 1357af1b2bcSJan Lentfer 1367af1b2bcSJan Lentfer /* these are for detailing the process states */ 1377af1b2bcSJan Lentfer 1387af1b2bcSJan Lentfer int process_states[6]; 1397af1b2bcSJan Lentfer char *procstatenames[] = { 140bc40e61dSStathis Kamperis " running, ", " idle, ", " active, ", " stopped, ", " zombie, ", 1417af1b2bcSJan Lentfer NULL 1427af1b2bcSJan Lentfer }; 1437af1b2bcSJan Lentfer 1447af1b2bcSJan Lentfer /* these are for detailing the cpu states */ 1457af1b2bcSJan Lentfer #define CPU_STATES 5 1467af1b2bcSJan Lentfer int *cpu_states; 1477af1b2bcSJan Lentfer char *cpustatenames[CPU_STATES + 1] = { 1487af1b2bcSJan Lentfer "user", "nice", "system", "interrupt", "idle", NULL 1497af1b2bcSJan Lentfer }; 1507af1b2bcSJan Lentfer 1517af1b2bcSJan Lentfer /* these are for detailing the memory statistics */ 1527af1b2bcSJan Lentfer 1537af1b2bcSJan Lentfer long memory_stats[7]; 1547af1b2bcSJan Lentfer char *memorynames[] = { 1557af1b2bcSJan Lentfer "K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free", 1567af1b2bcSJan Lentfer NULL 1577af1b2bcSJan Lentfer }; 1587af1b2bcSJan Lentfer 1597af1b2bcSJan Lentfer long swap_stats[7]; 1607af1b2bcSJan Lentfer char *swapnames[] = { 1617af1b2bcSJan Lentfer /* 0 1 2 3 4 5 */ 1627af1b2bcSJan Lentfer "K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out", 1637af1b2bcSJan Lentfer NULL 1647af1b2bcSJan Lentfer }; 1657af1b2bcSJan Lentfer 1667af1b2bcSJan Lentfer 1677af1b2bcSJan Lentfer /* these are for keeping track of the proc array */ 1687af1b2bcSJan Lentfer 1697af1b2bcSJan Lentfer static int nproc; 1707af1b2bcSJan Lentfer static int onproc = -1; 1717af1b2bcSJan Lentfer static int pref_len; 1727af1b2bcSJan Lentfer static struct kinfo_proc *pbase; 1737af1b2bcSJan Lentfer static struct kinfo_proc **pref; 1747af1b2bcSJan Lentfer 1757af1b2bcSJan Lentfer /* these are for getting the memory statistics */ 1767af1b2bcSJan Lentfer 1777af1b2bcSJan Lentfer static int pageshift; /* log base 2 of the pagesize */ 1787af1b2bcSJan Lentfer 1797af1b2bcSJan Lentfer /* define pagetok in terms of pageshift */ 1807af1b2bcSJan Lentfer 1817af1b2bcSJan Lentfer #define pagetok(size) ((size) << pageshift) 1827af1b2bcSJan Lentfer 1837af1b2bcSJan Lentfer /* sorting orders. first is default */ 1847af1b2bcSJan Lentfer char *ordernames[] = { 18550a55c46SMatthew Dillon "cpu", "size", "res", "time", "pri", "thr", "pid", "ctime", "pres", NULL 1867af1b2bcSJan Lentfer }; 1877af1b2bcSJan Lentfer 1887af1b2bcSJan Lentfer /* compare routines */ 1898b72b421SJan Lentfer int proc_compare (struct kinfo_proc **, struct kinfo_proc **); 1908b72b421SJan Lentfer int compare_size (struct kinfo_proc **, struct kinfo_proc **); 1918b72b421SJan Lentfer int compare_res (struct kinfo_proc **, struct kinfo_proc **); 1928b72b421SJan Lentfer int compare_time (struct kinfo_proc **, struct kinfo_proc **); 193bcd4a7c1SJan Lentfer int compare_ctime (struct kinfo_proc **, struct kinfo_proc **); 1948b72b421SJan Lentfer int compare_prio(struct kinfo_proc **, struct kinfo_proc **); 1958b72b421SJan Lentfer int compare_thr (struct kinfo_proc **, struct kinfo_proc **); 1968b72b421SJan Lentfer int compare_pid (struct kinfo_proc **, struct kinfo_proc **); 19750a55c46SMatthew Dillon int compare_pres(struct kinfo_proc **, struct kinfo_proc **); 1987af1b2bcSJan Lentfer 1998b72b421SJan Lentfer int (*proc_compares[]) (struct kinfo_proc **,struct kinfo_proc **) = { 2007af1b2bcSJan Lentfer proc_compare, 2017af1b2bcSJan Lentfer compare_size, 2027af1b2bcSJan Lentfer compare_res, 2037af1b2bcSJan Lentfer compare_time, 2047af1b2bcSJan Lentfer compare_prio, 2058b72b421SJan Lentfer compare_thr, 2068b72b421SJan Lentfer compare_pid, 207bcd4a7c1SJan Lentfer compare_ctime, 20850a55c46SMatthew Dillon compare_pres, 2097af1b2bcSJan Lentfer NULL 2107af1b2bcSJan Lentfer }; 2117af1b2bcSJan Lentfer 2127af1b2bcSJan Lentfer static void 2137af1b2bcSJan Lentfer cputime_percentages(int out[CPU_STATES], struct kinfo_cputime *new, 2147af1b2bcSJan Lentfer struct kinfo_cputime *old) 2157af1b2bcSJan Lentfer { 2167af1b2bcSJan Lentfer struct kinfo_cputime diffs; 2177af1b2bcSJan Lentfer uint64_t total_change, half_total; 2187af1b2bcSJan Lentfer 2197af1b2bcSJan Lentfer /* initialization */ 2207af1b2bcSJan Lentfer total_change = 0; 2217af1b2bcSJan Lentfer 2227af1b2bcSJan Lentfer diffs.cp_user = new->cp_user - old->cp_user; 2237af1b2bcSJan Lentfer diffs.cp_nice = new->cp_nice - old->cp_nice; 2247af1b2bcSJan Lentfer diffs.cp_sys = new->cp_sys - old->cp_sys; 2257af1b2bcSJan Lentfer diffs.cp_intr = new->cp_intr - old->cp_intr; 2267af1b2bcSJan Lentfer diffs.cp_idle = new->cp_idle - old->cp_idle; 2277af1b2bcSJan Lentfer total_change = diffs.cp_user + diffs.cp_nice + diffs.cp_sys + 2287af1b2bcSJan Lentfer diffs.cp_intr + diffs.cp_idle; 2297af1b2bcSJan Lentfer old->cp_user = new->cp_user; 2307af1b2bcSJan Lentfer old->cp_nice = new->cp_nice; 2317af1b2bcSJan Lentfer old->cp_sys = new->cp_sys; 2327af1b2bcSJan Lentfer old->cp_intr = new->cp_intr; 2337af1b2bcSJan Lentfer old->cp_idle = new->cp_idle; 2347af1b2bcSJan Lentfer 2357af1b2bcSJan Lentfer /* avoid divide by zero potential */ 2367af1b2bcSJan Lentfer if (total_change == 0) 2377af1b2bcSJan Lentfer total_change = 1; 2387af1b2bcSJan Lentfer 2397af1b2bcSJan Lentfer /* calculate percentages based on overall change, rounding up */ 2407af1b2bcSJan Lentfer half_total = total_change >> 1; 2417af1b2bcSJan Lentfer 2427af1b2bcSJan Lentfer out[0] = ((diffs.cp_user * 1000LL + half_total) / total_change); 2437af1b2bcSJan Lentfer out[1] = ((diffs.cp_nice * 1000LL + half_total) / total_change); 2447af1b2bcSJan Lentfer out[2] = ((diffs.cp_sys * 1000LL + half_total) / total_change); 2457af1b2bcSJan Lentfer out[3] = ((diffs.cp_intr * 1000LL + half_total) / total_change); 2467af1b2bcSJan Lentfer out[4] = ((diffs.cp_idle * 1000LL + half_total) / total_change); 2477af1b2bcSJan Lentfer } 2487af1b2bcSJan Lentfer 2497af1b2bcSJan Lentfer int 2507af1b2bcSJan Lentfer machine_init(struct statics *statics) 2517af1b2bcSJan Lentfer { 2527af1b2bcSJan Lentfer int pagesize; 2537af1b2bcSJan Lentfer size_t modelen; 2547af1b2bcSJan Lentfer struct passwd *pw; 2557af1b2bcSJan Lentfer struct timeval boottime; 2567af1b2bcSJan Lentfer 2577af1b2bcSJan Lentfer if (n_cpus < 1) { 2587af1b2bcSJan Lentfer if (kinfo_get_cpus(&n_cpus)) 2597af1b2bcSJan Lentfer err(1, "kinfo_get_cpus failed"); 2607af1b2bcSJan Lentfer } 2617af1b2bcSJan Lentfer /* get boot time */ 2627af1b2bcSJan Lentfer modelen = sizeof(boottime); 2637af1b2bcSJan Lentfer if (sysctlbyname("kern.boottime", &boottime, &modelen, NULL, 0) == -1) { 2647af1b2bcSJan Lentfer /* we have no boottime to report */ 2657af1b2bcSJan Lentfer boottime.tv_sec = -1; 2667af1b2bcSJan Lentfer } 2677af1b2bcSJan Lentfer modelen = sizeof(smpmode); 2687af1b2bcSJan Lentfer if ((sysctlbyname("machdep.smp_active", &smpmode, &modelen, NULL, 0) < 0 && 2697af1b2bcSJan Lentfer sysctlbyname("smp.smp_active", &smpmode, &modelen, NULL, 0) < 0) || 2707af1b2bcSJan Lentfer modelen != sizeof(smpmode)) 2717af1b2bcSJan Lentfer smpmode = 0; 2727af1b2bcSJan Lentfer 2737af1b2bcSJan Lentfer while ((pw = getpwent()) != NULL) { 2747af1b2bcSJan Lentfer if ((int)strlen(pw->pw_name) > namelength) 2757af1b2bcSJan Lentfer namelength = strlen(pw->pw_name); 2767af1b2bcSJan Lentfer } 2777af1b2bcSJan Lentfer if (namelength < 8) 2787af1b2bcSJan Lentfer namelength = 8; 2797af1b2bcSJan Lentfer if (smpmode && namelength > 13) 2807af1b2bcSJan Lentfer namelength = 13; 2817af1b2bcSJan Lentfer else if (namelength > 15) 2827af1b2bcSJan Lentfer namelength = 15; 2837af1b2bcSJan Lentfer 284efde5811SJan Lentfer if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL) 2857af1b2bcSJan Lentfer return -1; 2867af1b2bcSJan Lentfer 2877af1b2bcSJan Lentfer if (kinfo_get_sched_ccpu(&ccpu)) { 2887af1b2bcSJan Lentfer fprintf(stderr, "top: kinfo_get_sched_ccpu failed\n"); 2897af1b2bcSJan Lentfer return (-1); 2907af1b2bcSJan Lentfer } 2917af1b2bcSJan Lentfer /* this is used in calculating WCPU -- calculate it ahead of time */ 2927af1b2bcSJan Lentfer logcpu = log(loaddouble(ccpu)); 2937af1b2bcSJan Lentfer 2947af1b2bcSJan Lentfer pbase = NULL; 2957af1b2bcSJan Lentfer pref = NULL; 2967af1b2bcSJan Lentfer nproc = 0; 2977af1b2bcSJan Lentfer onproc = -1; 298961f1f09SJan Lentfer /* 299961f1f09SJan Lentfer * get the page size with "getpagesize" and calculate pageshift from 300961f1f09SJan Lentfer * it 301961f1f09SJan Lentfer */ 3027af1b2bcSJan Lentfer pagesize = getpagesize(); 3037af1b2bcSJan Lentfer pageshift = 0; 304961f1f09SJan Lentfer while (pagesize > 1) { 3057af1b2bcSJan Lentfer pageshift++; 3067af1b2bcSJan Lentfer pagesize >>= 1; 3077af1b2bcSJan Lentfer } 3087af1b2bcSJan Lentfer 3097af1b2bcSJan Lentfer /* we only need the amount of log(2)1024 for our conversion */ 3107af1b2bcSJan Lentfer pageshift -= LOG1024; 3117af1b2bcSJan Lentfer 3127af1b2bcSJan Lentfer /* fill in the statics information */ 3137af1b2bcSJan Lentfer statics->procstate_names = procstatenames; 3147af1b2bcSJan Lentfer statics->cpustate_names = cpustatenames; 3157af1b2bcSJan Lentfer statics->memory_names = memorynames; 3167af1b2bcSJan Lentfer statics->boottime = boottime.tv_sec; 3177af1b2bcSJan Lentfer statics->swap_names = swapnames; 3187af1b2bcSJan Lentfer statics->order_names = ordernames; 319efde5811SJan Lentfer /* we need kvm descriptor in order to show full commands */ 320efde5811SJan Lentfer statics->flags.fullcmds = kd != NULL; 3217af1b2bcSJan Lentfer 3227af1b2bcSJan Lentfer /* all done! */ 3237af1b2bcSJan Lentfer return (0); 3247af1b2bcSJan Lentfer } 3257af1b2bcSJan Lentfer 3267af1b2bcSJan Lentfer char * 3277af1b2bcSJan Lentfer format_header(char *uname_field) 3287af1b2bcSJan Lentfer { 3297af1b2bcSJan Lentfer static char Header[128]; 3307af1b2bcSJan Lentfer 3317af1b2bcSJan Lentfer snprintf(Header, sizeof(Header), smpmode ? smp_header : up_header, 3327af1b2bcSJan Lentfer namelength, namelength, uname_field); 3337af1b2bcSJan Lentfer 3347af1b2bcSJan Lentfer if (screen_width <= 79) 3357af1b2bcSJan Lentfer cmdlength = 80; 3367af1b2bcSJan Lentfer else 3378b72b421SJan Lentfer cmdlength = screen_width; 3387af1b2bcSJan Lentfer 3397af1b2bcSJan Lentfer cmdlength = cmdlength - strlen(Header) + 6; 3407af1b2bcSJan Lentfer 3417af1b2bcSJan Lentfer return Header; 3427af1b2bcSJan Lentfer } 3437af1b2bcSJan Lentfer 3447af1b2bcSJan Lentfer static int swappgsin = -1; 3457af1b2bcSJan Lentfer static int swappgsout = -1; 3467af1b2bcSJan Lentfer extern struct timeval timeout; 3477af1b2bcSJan Lentfer 3487af1b2bcSJan Lentfer void 3497af1b2bcSJan Lentfer get_system_info(struct system_info *si) 3507af1b2bcSJan Lentfer { 3517af1b2bcSJan Lentfer size_t len; 3527af1b2bcSJan Lentfer int cpu; 3537af1b2bcSJan Lentfer 3547af1b2bcSJan Lentfer if (cpu_states == NULL) { 3557af1b2bcSJan Lentfer cpu_states = malloc(sizeof(*cpu_states) * CPU_STATES * n_cpus); 3567af1b2bcSJan Lentfer if (cpu_states == NULL) 3577af1b2bcSJan Lentfer err(1, "malloc"); 3587af1b2bcSJan Lentfer bzero(cpu_states, sizeof(*cpu_states) * CPU_STATES * n_cpus); 3597af1b2bcSJan Lentfer } 3607af1b2bcSJan Lentfer if (cp_time == NULL) { 3617af1b2bcSJan Lentfer cp_time = malloc(2 * n_cpus * sizeof(cp_time[0])); 3627af1b2bcSJan Lentfer if (cp_time == NULL) 3637af1b2bcSJan Lentfer err(1, "cp_time"); 3647af1b2bcSJan Lentfer cp_old = cp_time + n_cpus; 3657af1b2bcSJan Lentfer len = n_cpus * sizeof(cp_old[0]); 3667af1b2bcSJan Lentfer bzero(cp_time, len); 3677af1b2bcSJan Lentfer if (sysctlbyname("kern.cputime", cp_old, &len, NULL, 0)) 3687af1b2bcSJan Lentfer err(1, "kern.cputime"); 3697af1b2bcSJan Lentfer } 3707af1b2bcSJan Lentfer len = n_cpus * sizeof(cp_time[0]); 3717af1b2bcSJan Lentfer bzero(cp_time, len); 3727af1b2bcSJan Lentfer if (sysctlbyname("kern.cputime", cp_time, &len, NULL, 0)) 3737af1b2bcSJan Lentfer err(1, "kern.cputime"); 3747af1b2bcSJan Lentfer 3757af1b2bcSJan Lentfer getloadavg(si->load_avg, 3); 3767af1b2bcSJan Lentfer 3777af1b2bcSJan Lentfer lastpid = 0; 3787af1b2bcSJan Lentfer 3797af1b2bcSJan Lentfer /* convert cp_time counts to percentages */ 3807af1b2bcSJan Lentfer for (cpu = 0; cpu < n_cpus; ++cpu) { 3817af1b2bcSJan Lentfer cputime_percentages(cpu_states + cpu * CPU_STATES, 3827af1b2bcSJan Lentfer &cp_time[cpu], &cp_old[cpu]); 3837af1b2bcSJan Lentfer } 3847af1b2bcSJan Lentfer 3857af1b2bcSJan Lentfer /* sum memory & swap statistics */ 3867af1b2bcSJan Lentfer { 3877af1b2bcSJan Lentfer struct vmmeter vmm; 3887af1b2bcSJan Lentfer struct vmstats vms; 3897af1b2bcSJan Lentfer size_t vms_size = sizeof(vms); 3907af1b2bcSJan Lentfer size_t vmm_size = sizeof(vmm); 3917af1b2bcSJan Lentfer static unsigned int swap_delay = 0; 3927af1b2bcSJan Lentfer static int swapavail = 0; 3937af1b2bcSJan Lentfer static int swapfree = 0; 394*3583bbb4SMatthew Dillon static long bufspace = 0; 3957af1b2bcSJan Lentfer 3967af1b2bcSJan Lentfer if (sysctlbyname("vm.vmstats", &vms, &vms_size, NULL, 0)) 3977af1b2bcSJan Lentfer err(1, "sysctlbyname: vm.vmstats"); 3987af1b2bcSJan Lentfer 3997af1b2bcSJan Lentfer if (sysctlbyname("vm.vmmeter", &vmm, &vmm_size, NULL, 0)) 4007af1b2bcSJan Lentfer err(1, "sysctlbyname: vm.vmmeter"); 4017af1b2bcSJan Lentfer 4027af1b2bcSJan Lentfer if (kinfo_get_vfs_bufspace(&bufspace)) 4037af1b2bcSJan Lentfer err(1, "kinfo_get_vfs_bufspace"); 4047af1b2bcSJan Lentfer 4057af1b2bcSJan Lentfer /* convert memory stats to Kbytes */ 4067af1b2bcSJan Lentfer memory_stats[0] = pagetok(vms.v_active_count); 4077af1b2bcSJan Lentfer memory_stats[1] = pagetok(vms.v_inactive_count); 4087af1b2bcSJan Lentfer memory_stats[2] = pagetok(vms.v_wire_count); 4097af1b2bcSJan Lentfer memory_stats[3] = pagetok(vms.v_cache_count); 4107af1b2bcSJan Lentfer memory_stats[4] = bufspace / 1024; 4117af1b2bcSJan Lentfer memory_stats[5] = pagetok(vms.v_free_count); 4127af1b2bcSJan Lentfer memory_stats[6] = -1; 4137af1b2bcSJan Lentfer 4147af1b2bcSJan Lentfer /* first interval */ 4157af1b2bcSJan Lentfer if (swappgsin < 0) { 4167af1b2bcSJan Lentfer swap_stats[4] = 0; 4177af1b2bcSJan Lentfer swap_stats[5] = 0; 4187af1b2bcSJan Lentfer } 4197af1b2bcSJan Lentfer /* compute differences between old and new swap statistic */ 4207af1b2bcSJan Lentfer else { 4217af1b2bcSJan Lentfer swap_stats[4] = pagetok(((vmm.v_swappgsin - swappgsin))); 4227af1b2bcSJan Lentfer swap_stats[5] = pagetok(((vmm.v_swappgsout - swappgsout))); 4237af1b2bcSJan Lentfer } 4247af1b2bcSJan Lentfer 4257af1b2bcSJan Lentfer swappgsin = vmm.v_swappgsin; 4267af1b2bcSJan Lentfer swappgsout = vmm.v_swappgsout; 4277af1b2bcSJan Lentfer 4287af1b2bcSJan Lentfer /* call CPU heavy swapmode() only for changes */ 4297af1b2bcSJan Lentfer if (swap_stats[4] > 0 || swap_stats[5] > 0 || swap_delay == 0) { 4307af1b2bcSJan Lentfer swap_stats[3] = swapmode(&swapavail, &swapfree); 4317af1b2bcSJan Lentfer swap_stats[0] = swapavail; 4327af1b2bcSJan Lentfer swap_stats[1] = swapavail - swapfree; 4337af1b2bcSJan Lentfer swap_stats[2] = swapfree; 4347af1b2bcSJan Lentfer } 4357af1b2bcSJan Lentfer swap_delay = 1; 4367af1b2bcSJan Lentfer swap_stats[6] = -1; 4377af1b2bcSJan Lentfer } 4387af1b2bcSJan Lentfer 4397af1b2bcSJan Lentfer /* set arrays and strings */ 4407af1b2bcSJan Lentfer si->cpustates = cpu_states; 4417af1b2bcSJan Lentfer si->memory = memory_stats; 4427af1b2bcSJan Lentfer si->swap = swap_stats; 4437af1b2bcSJan Lentfer 4447af1b2bcSJan Lentfer 4457af1b2bcSJan Lentfer if (lastpid > 0) { 4467af1b2bcSJan Lentfer si->last_pid = lastpid; 4477af1b2bcSJan Lentfer } else { 4487af1b2bcSJan Lentfer si->last_pid = -1; 4497af1b2bcSJan Lentfer } 4507af1b2bcSJan Lentfer } 4517af1b2bcSJan Lentfer 4527af1b2bcSJan Lentfer 4537af1b2bcSJan Lentfer static struct handle handle; 4547af1b2bcSJan Lentfer 455961f1f09SJan Lentfer caddr_t 456961f1f09SJan Lentfer get_process_info(struct system_info *si, struct process_select *sel, 4577af1b2bcSJan Lentfer int compare_index) 4587af1b2bcSJan Lentfer { 4597af1b2bcSJan Lentfer int i; 4607af1b2bcSJan Lentfer int total_procs; 4617af1b2bcSJan Lentfer int active_procs; 4627af1b2bcSJan Lentfer struct kinfo_proc **prefp; 4637af1b2bcSJan Lentfer struct kinfo_proc *pp; 4647af1b2bcSJan Lentfer 4657af1b2bcSJan Lentfer /* these are copied out of sel for speed */ 4667af1b2bcSJan Lentfer int show_idle; 4677af1b2bcSJan Lentfer int show_system; 4687af1b2bcSJan Lentfer int show_uid; 4697af1b2bcSJan Lentfer 4707af1b2bcSJan Lentfer 4717af1b2bcSJan Lentfer pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc); 4727af1b2bcSJan Lentfer if (nproc > onproc) 4737af1b2bcSJan Lentfer pref = (struct kinfo_proc **)realloc(pref, sizeof(struct kinfo_proc *) 4747af1b2bcSJan Lentfer * (onproc = nproc)); 4757af1b2bcSJan Lentfer if (pref == NULL || pbase == NULL) { 4767af1b2bcSJan Lentfer (void)fprintf(stderr, "top: Out of memory.\n"); 4777af1b2bcSJan Lentfer quit(23); 4787af1b2bcSJan Lentfer } 4797af1b2bcSJan Lentfer /* get a pointer to the states summary array */ 4807af1b2bcSJan Lentfer si->procstates = process_states; 4817af1b2bcSJan Lentfer 4827af1b2bcSJan Lentfer /* set up flags which define what we are going to select */ 4837af1b2bcSJan Lentfer show_idle = sel->idle; 4847af1b2bcSJan Lentfer show_system = sel->system; 4857af1b2bcSJan Lentfer show_uid = sel->uid != -1; 486efde5811SJan Lentfer show_fullcmd = sel->fullcmd; 4877af1b2bcSJan Lentfer 4887af1b2bcSJan Lentfer /* count up process states and get pointers to interesting procs */ 4897af1b2bcSJan Lentfer total_procs = 0; 4907af1b2bcSJan Lentfer active_procs = 0; 4917af1b2bcSJan Lentfer memset((char *)process_states, 0, sizeof(process_states)); 4927af1b2bcSJan Lentfer prefp = pref; 493961f1f09SJan Lentfer for (pp = pbase, i = 0; i < nproc; pp++, i++) { 4947af1b2bcSJan Lentfer /* 4957af1b2bcSJan Lentfer * Place pointers to each valid proc structure in pref[]. 4967af1b2bcSJan Lentfer * Process slots that are actually in use have a non-zero 4977af1b2bcSJan Lentfer * status field. Processes with P_SYSTEM set are system 4987af1b2bcSJan Lentfer * processes---these get ignored unless show_sysprocs is set. 4997af1b2bcSJan Lentfer */ 5007af1b2bcSJan Lentfer if ((show_threads && (LP(pp, pid) == -1)) || 501961f1f09SJan Lentfer (show_system || ((PP(pp, flags) & P_SYSTEM) == 0))) { 5027af1b2bcSJan Lentfer total_procs++; 503bc40e61dSStathis Kamperis if (LP(pp, stat) == LSRUN) 504bc40e61dSStathis Kamperis process_states[0]++; 505bc40e61dSStathis Kamperis process_states[PP(pp, stat)]++; 5067af1b2bcSJan Lentfer if ((show_threads && (LP(pp, pid) == -1)) || 5077af1b2bcSJan Lentfer (show_idle || (LP(pp, pctcpu) != 0) || 5087af1b2bcSJan Lentfer (LP(pp, stat) == LSRUN)) && 509961f1f09SJan Lentfer (!show_uid || PP(pp, ruid) == (uid_t) sel->uid)) { 5107af1b2bcSJan Lentfer *prefp++ = pp; 5117af1b2bcSJan Lentfer active_procs++; 5127af1b2bcSJan Lentfer } 5137af1b2bcSJan Lentfer } 5147af1b2bcSJan Lentfer } 5157af1b2bcSJan Lentfer 5167af1b2bcSJan Lentfer qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *), 5178b72b421SJan Lentfer (int (*)(const void *, const void *))proc_compares[compare_index]); 5187af1b2bcSJan Lentfer 5197af1b2bcSJan Lentfer /* remember active and total counts */ 5207af1b2bcSJan Lentfer si->p_total = total_procs; 5217af1b2bcSJan Lentfer si->p_active = pref_len = active_procs; 5227af1b2bcSJan Lentfer 5237af1b2bcSJan Lentfer /* pass back a handle */ 5247af1b2bcSJan Lentfer handle.next_proc = pref; 5257af1b2bcSJan Lentfer handle.remaining = active_procs; 5267af1b2bcSJan Lentfer return ((caddr_t) & handle); 5277af1b2bcSJan Lentfer } 5287af1b2bcSJan Lentfer 529cef6b642SMatthew Dillon char fmt[MAX_COLS]; /* static area where result is built */ 5307af1b2bcSJan Lentfer 5317af1b2bcSJan Lentfer char * 5327af1b2bcSJan Lentfer format_next_process(caddr_t xhandle, char *(*get_userid) (int)) 5337af1b2bcSJan Lentfer { 5347af1b2bcSJan Lentfer struct kinfo_proc *pp; 5357af1b2bcSJan Lentfer long cputime; 536bcd4a7c1SJan Lentfer long ccputime; 5377af1b2bcSJan Lentfer double pct; 5387af1b2bcSJan Lentfer struct handle *hp; 5397af1b2bcSJan Lentfer char status[16]; 5407af1b2bcSJan Lentfer int state; 5417af1b2bcSJan Lentfer int xnice; 542efde5811SJan Lentfer char **comm_full; 543efde5811SJan Lentfer char *comm; 544bcd4a7c1SJan Lentfer char cputime_fmt[10], ccputime_fmt[10]; 5457af1b2bcSJan Lentfer 5467af1b2bcSJan Lentfer /* find and remember the next proc structure */ 5477af1b2bcSJan Lentfer hp = (struct handle *)xhandle; 5487af1b2bcSJan Lentfer pp = *(hp->next_proc++); 5497af1b2bcSJan Lentfer hp->remaining--; 5507af1b2bcSJan Lentfer 5517af1b2bcSJan Lentfer /* get the process's command name */ 552efde5811SJan Lentfer if (show_fullcmd) { 553efde5811SJan Lentfer if ((comm_full = kvm_getargv(kd, pp, 0)) == NULL) { 554efde5811SJan Lentfer return (fmt); 5557af1b2bcSJan Lentfer } 556efde5811SJan Lentfer } 557efde5811SJan Lentfer else { 558efde5811SJan Lentfer comm = PP(pp, comm); 559efde5811SJan Lentfer } 560efde5811SJan Lentfer 5617af1b2bcSJan Lentfer /* 5627af1b2bcSJan Lentfer * Convert the process's runtime from microseconds to seconds. This 563bcd4a7c1SJan Lentfer * time includes the interrupt time to be in compliance with ps output. 5647af1b2bcSJan Lentfer */ 565bcd4a7c1SJan Lentfer cputime = (LP(pp, uticks) + LP(pp, sticks) + LP(pp, iticks)) / 1000000; 566bcd4a7c1SJan Lentfer ccputime = cputime + PP(pp, cru).ru_stime.tv_sec + PP(pp, cru).ru_utime.tv_sec; 567bcd4a7c1SJan Lentfer format_time(cputime, cputime_fmt, sizeof(cputime_fmt)); 568bcd4a7c1SJan Lentfer format_time(ccputime, ccputime_fmt, sizeof(ccputime_fmt)); 5697af1b2bcSJan Lentfer 5707af1b2bcSJan Lentfer /* calculate the base for cpu percentages */ 5717af1b2bcSJan Lentfer pct = pctdouble(LP(pp, pctcpu)); 5727af1b2bcSJan Lentfer 5737af1b2bcSJan Lentfer /* generate "STATE" field */ 5747af1b2bcSJan Lentfer switch (state = LP(pp, stat)) { 5757af1b2bcSJan Lentfer case LSRUN: 5767af1b2bcSJan Lentfer if (smpmode && LP(pp, tdflags) & TDF_RUNNING) 5777af1b2bcSJan Lentfer sprintf(status, "CPU%d", LP(pp, cpuid)); 5787af1b2bcSJan Lentfer else 5797af1b2bcSJan Lentfer strcpy(status, "RUN"); 5807af1b2bcSJan Lentfer break; 5817af1b2bcSJan Lentfer case LSSLEEP: 5827af1b2bcSJan Lentfer if (LP(pp, wmesg) != NULL) { 5837af1b2bcSJan Lentfer sprintf(status, "%.6s", LP(pp, wmesg)); 5847af1b2bcSJan Lentfer break; 5857af1b2bcSJan Lentfer } 5867af1b2bcSJan Lentfer /* fall through */ 5877af1b2bcSJan Lentfer default: 5887af1b2bcSJan Lentfer 5897af1b2bcSJan Lentfer if (state >= 0 && 5907af1b2bcSJan Lentfer (unsigned)state < sizeof(state_abbrev) / sizeof(*state_abbrev)) 5917af1b2bcSJan Lentfer sprintf(status, "%.6s", state_abbrev[(unsigned char)state]); 5927af1b2bcSJan Lentfer else 5937af1b2bcSJan Lentfer sprintf(status, "?%5d", state); 5947af1b2bcSJan Lentfer break; 5957af1b2bcSJan Lentfer } 5967af1b2bcSJan Lentfer 5977af1b2bcSJan Lentfer if (PP(pp, stat) == SZOMB) 5987af1b2bcSJan Lentfer strcpy(status, "ZOMB"); 5997af1b2bcSJan Lentfer 6007af1b2bcSJan Lentfer /* 601961f1f09SJan Lentfer * idle time 0 - 31 -> nice value +21 - +52 normal time -> nice 602961f1f09SJan Lentfer * value -20 - +20 real time 0 - 31 -> nice value -52 - -21 thread 603961f1f09SJan Lentfer * 0 - 31 -> nice value -53 - 6047af1b2bcSJan Lentfer */ 6057af1b2bcSJan Lentfer switch (LP(pp, rtprio.type)) { 6067af1b2bcSJan Lentfer case RTP_PRIO_REALTIME: 6077af1b2bcSJan Lentfer xnice = PRIO_MIN - 1 - RTP_PRIO_MAX + LP(pp, rtprio.prio); 6087af1b2bcSJan Lentfer break; 6097af1b2bcSJan Lentfer case RTP_PRIO_IDLE: 6107af1b2bcSJan Lentfer xnice = PRIO_MAX + 1 + LP(pp, rtprio.prio); 6117af1b2bcSJan Lentfer break; 6127af1b2bcSJan Lentfer case RTP_PRIO_THREAD: 6137af1b2bcSJan Lentfer xnice = PRIO_MIN - 1 - RTP_PRIO_MAX - LP(pp, rtprio.prio); 6147af1b2bcSJan Lentfer break; 6157af1b2bcSJan Lentfer default: 6167af1b2bcSJan Lentfer xnice = PP(pp, nice); 6177af1b2bcSJan Lentfer break; 6187af1b2bcSJan Lentfer } 6197af1b2bcSJan Lentfer 6207af1b2bcSJan Lentfer /* format this entry */ 6217af1b2bcSJan Lentfer snprintf(fmt, sizeof(fmt), 6227af1b2bcSJan Lentfer smpmode ? smp_Proc_format : up_Proc_format, 6237af1b2bcSJan Lentfer (int)PP(pp, pid), 6247af1b2bcSJan Lentfer namelength, namelength, 6257af1b2bcSJan Lentfer get_userid(PP(pp, ruid)), 6267af1b2bcSJan Lentfer (int)xnice, 6277af1b2bcSJan Lentfer format_k(PROCSIZE(pp)), 62850a55c46SMatthew Dillon format_k(pagetok(VP(pp, prssize))), 6297af1b2bcSJan Lentfer status, 6307af1b2bcSJan Lentfer (int)(smpmode ? LP(pp, cpuid) : 0), 631bcd4a7c1SJan Lentfer cputime_fmt, 632bcd4a7c1SJan Lentfer ccputime_fmt, 6337af1b2bcSJan Lentfer 100.0 * pct, 6347af1b2bcSJan Lentfer cmdlength, 635efde5811SJan Lentfer show_fullcmd ? *comm_full : comm); 6367af1b2bcSJan Lentfer 6377af1b2bcSJan Lentfer /* return the result */ 6387af1b2bcSJan Lentfer return (fmt); 6397af1b2bcSJan Lentfer } 6407af1b2bcSJan Lentfer 6417af1b2bcSJan Lentfer /* comparison routines for qsort */ 6427af1b2bcSJan Lentfer 6437af1b2bcSJan Lentfer /* 6447af1b2bcSJan Lentfer * proc_compare - comparison function for "qsort" 6457af1b2bcSJan Lentfer * Compares the resource consumption of two processes using five 6467af1b2bcSJan Lentfer * distinct keys. The keys (in descending order of importance) are: 6477af1b2bcSJan Lentfer * percent cpu, cpu ticks, state, resident set size, total virtual 6487af1b2bcSJan Lentfer * memory usage. The process states are ordered as follows (from least 6497af1b2bcSJan Lentfer * to most important): WAIT, zombie, sleep, stop, start, run. The 6507af1b2bcSJan Lentfer * array declaration below maps a process state index into a number 6517af1b2bcSJan Lentfer * that reflects this ordering. 6527af1b2bcSJan Lentfer */ 6537af1b2bcSJan Lentfer 6547af1b2bcSJan Lentfer static unsigned char sorted_state[] = 6557af1b2bcSJan Lentfer { 6567af1b2bcSJan Lentfer 0, /* not used */ 6577af1b2bcSJan Lentfer 3, /* sleep */ 6587af1b2bcSJan Lentfer 1, /* ABANDONED (WAIT) */ 6597af1b2bcSJan Lentfer 6, /* run */ 6607af1b2bcSJan Lentfer 5, /* start */ 6617af1b2bcSJan Lentfer 2, /* zombie */ 6627af1b2bcSJan Lentfer 4 /* stop */ 6637af1b2bcSJan Lentfer }; 6647af1b2bcSJan Lentfer 6657af1b2bcSJan Lentfer 6667af1b2bcSJan Lentfer #define ORDERKEY_PCTCPU \ 6677af1b2bcSJan Lentfer if (lresult = (long) LP(p2, pctcpu) - (long) LP(p1, pctcpu), \ 6687af1b2bcSJan Lentfer (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) 6697af1b2bcSJan Lentfer 670bcd4a7c1SJan Lentfer #define CPTICKS(p) (LP(p, uticks) + LP(p, sticks) + LP(p, iticks)) 6717af1b2bcSJan Lentfer 6727af1b2bcSJan Lentfer #define ORDERKEY_CPTICKS \ 6737af1b2bcSJan Lentfer if ((result = CPTICKS(p2) > CPTICKS(p1) ? 1 : \ 6747af1b2bcSJan Lentfer CPTICKS(p2) < CPTICKS(p1) ? -1 : 0) == 0) 6757af1b2bcSJan Lentfer 676bcd4a7c1SJan Lentfer #define CTIME(p) (((LP(p, uticks) + LP(p, sticks) + LP(p, iticks))/1000000) + \ 677bcd4a7c1SJan Lentfer PP(p, cru).ru_stime.tv_sec + PP(p, cru).ru_utime.tv_sec) 678bcd4a7c1SJan Lentfer 679bcd4a7c1SJan Lentfer #define ORDERKEY_CTIME \ 680bcd4a7c1SJan Lentfer if ((result = CTIME(p2) > CTIME(p1) ? 1 : \ 681bcd4a7c1SJan Lentfer CTIME(p2) < CTIME(p1) ? -1 : 0) == 0) 682bcd4a7c1SJan Lentfer 6837af1b2bcSJan Lentfer #define ORDERKEY_STATE \ 6847af1b2bcSJan Lentfer if ((result = sorted_state[(unsigned char) PP(p2, stat)] - \ 6857af1b2bcSJan Lentfer sorted_state[(unsigned char) PP(p1, stat)]) == 0) 6867af1b2bcSJan Lentfer 6877af1b2bcSJan Lentfer #define ORDERKEY_PRIO \ 6887af1b2bcSJan Lentfer if ((result = LP(p2, prio) - LP(p1, prio)) == 0) 6897af1b2bcSJan Lentfer 6907af1b2bcSJan Lentfer #define ORDERKEY_KTHREADS \ 6917af1b2bcSJan Lentfer if ((result = (LP(p1, pid) == 0) - (LP(p2, pid) == 0)) == 0) 6927af1b2bcSJan Lentfer 6937af1b2bcSJan Lentfer #define ORDERKEY_KTHREADS_PRIO \ 6947af1b2bcSJan Lentfer if ((result = LP(p2, tdprio) - LP(p1, tdprio)) == 0) 6957af1b2bcSJan Lentfer 6967af1b2bcSJan Lentfer #define ORDERKEY_RSSIZE \ 6977af1b2bcSJan Lentfer if ((result = VP(p2, rssize) - VP(p1, rssize)) == 0) 6987af1b2bcSJan Lentfer 6997af1b2bcSJan Lentfer #define ORDERKEY_MEM \ 7007af1b2bcSJan Lentfer if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 ) 7017af1b2bcSJan Lentfer 7028b72b421SJan Lentfer #define ORDERKEY_PID \ 7038b72b421SJan Lentfer if ( (result = PP(p1, pid) - PP(p2, pid)) == 0) 7048b72b421SJan Lentfer 70550a55c46SMatthew Dillon #define ORDERKEY_PRSSIZE \ 70650a55c46SMatthew Dillon if((result = VP(p2, prssize) - VP(p1, prssize)) == 0) 70750a55c46SMatthew Dillon 7087af1b2bcSJan Lentfer /* compare_cpu - the comparison function for sorting by cpu percentage */ 7097af1b2bcSJan Lentfer 7107af1b2bcSJan Lentfer int 7118b72b421SJan Lentfer proc_compare(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 7127af1b2bcSJan Lentfer { 7138b72b421SJan Lentfer struct kinfo_proc *p1; 7148b72b421SJan Lentfer struct kinfo_proc *p2; 7157af1b2bcSJan Lentfer int result; 7167af1b2bcSJan Lentfer pctcpu lresult; 7177af1b2bcSJan Lentfer 7187af1b2bcSJan Lentfer /* remove one level of indirection */ 7198b72b421SJan Lentfer p1 = *(struct kinfo_proc **) pp1; 7208b72b421SJan Lentfer p2 = *(struct kinfo_proc **) pp2; 7217af1b2bcSJan Lentfer 7227af1b2bcSJan Lentfer ORDERKEY_PCTCPU 7237af1b2bcSJan Lentfer ORDERKEY_CPTICKS 7247af1b2bcSJan Lentfer ORDERKEY_STATE 7257af1b2bcSJan Lentfer ORDERKEY_PRIO 7267af1b2bcSJan Lentfer ORDERKEY_RSSIZE 7277af1b2bcSJan Lentfer ORDERKEY_MEM 7287af1b2bcSJan Lentfer {} 7297af1b2bcSJan Lentfer 7307af1b2bcSJan Lentfer return (result); 7317af1b2bcSJan Lentfer } 7327af1b2bcSJan Lentfer 7337af1b2bcSJan Lentfer /* compare_size - the comparison function for sorting by total memory usage */ 7347af1b2bcSJan Lentfer 7357af1b2bcSJan Lentfer int 7368b72b421SJan Lentfer compare_size(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 7377af1b2bcSJan Lentfer { 7387af1b2bcSJan Lentfer struct kinfo_proc *p1; 7397af1b2bcSJan Lentfer struct kinfo_proc *p2; 7407af1b2bcSJan Lentfer int result; 7417af1b2bcSJan Lentfer pctcpu lresult; 7427af1b2bcSJan Lentfer 7437af1b2bcSJan Lentfer /* remove one level of indirection */ 7448b72b421SJan Lentfer p1 = *(struct kinfo_proc **) pp1; 7458b72b421SJan Lentfer p2 = *(struct kinfo_proc **) pp2; 7467af1b2bcSJan Lentfer 7477af1b2bcSJan Lentfer ORDERKEY_MEM 7487af1b2bcSJan Lentfer ORDERKEY_RSSIZE 7497af1b2bcSJan Lentfer ORDERKEY_PCTCPU 7507af1b2bcSJan Lentfer ORDERKEY_CPTICKS 7517af1b2bcSJan Lentfer ORDERKEY_STATE 7527af1b2bcSJan Lentfer ORDERKEY_PRIO 7537af1b2bcSJan Lentfer {} 7547af1b2bcSJan Lentfer 7557af1b2bcSJan Lentfer return (result); 7567af1b2bcSJan Lentfer } 7577af1b2bcSJan Lentfer 7587af1b2bcSJan Lentfer /* compare_res - the comparison function for sorting by resident set size */ 7597af1b2bcSJan Lentfer 7607af1b2bcSJan Lentfer int 7618b72b421SJan Lentfer compare_res(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 7627af1b2bcSJan Lentfer { 7637af1b2bcSJan Lentfer struct kinfo_proc *p1; 7647af1b2bcSJan Lentfer struct kinfo_proc *p2; 7657af1b2bcSJan Lentfer int result; 7667af1b2bcSJan Lentfer pctcpu lresult; 7677af1b2bcSJan Lentfer 7687af1b2bcSJan Lentfer /* remove one level of indirection */ 7698b72b421SJan Lentfer p1 = *(struct kinfo_proc **) pp1; 7708b72b421SJan Lentfer p2 = *(struct kinfo_proc **) pp2; 7717af1b2bcSJan Lentfer 7727af1b2bcSJan Lentfer ORDERKEY_RSSIZE 7737af1b2bcSJan Lentfer ORDERKEY_MEM 7747af1b2bcSJan Lentfer ORDERKEY_PCTCPU 7757af1b2bcSJan Lentfer ORDERKEY_CPTICKS 7767af1b2bcSJan Lentfer ORDERKEY_STATE 7777af1b2bcSJan Lentfer ORDERKEY_PRIO 7787af1b2bcSJan Lentfer {} 7797af1b2bcSJan Lentfer 7807af1b2bcSJan Lentfer return (result); 7817af1b2bcSJan Lentfer } 7827af1b2bcSJan Lentfer 78350a55c46SMatthew Dillon /* compare_pres - the comparison function for sorting by proportional resident set size */ 78450a55c46SMatthew Dillon 78550a55c46SMatthew Dillon int 78650a55c46SMatthew Dillon compare_pres(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 78750a55c46SMatthew Dillon { 78850a55c46SMatthew Dillon struct kinfo_proc *p1; 78950a55c46SMatthew Dillon struct kinfo_proc *p2; 79050a55c46SMatthew Dillon int result; 79150a55c46SMatthew Dillon pctcpu lresult; 79250a55c46SMatthew Dillon 79350a55c46SMatthew Dillon /* remove one level of indirection */ 79450a55c46SMatthew Dillon p1 = *(struct kinfo_proc **) pp1; 79550a55c46SMatthew Dillon p2 = *(struct kinfo_proc **) pp2; 79650a55c46SMatthew Dillon 79750a55c46SMatthew Dillon ORDERKEY_PRSSIZE 79850a55c46SMatthew Dillon ORDERKEY_RSSIZE 79950a55c46SMatthew Dillon ORDERKEY_MEM 80050a55c46SMatthew Dillon ORDERKEY_PCTCPU 80150a55c46SMatthew Dillon ORDERKEY_CPTICKS 80250a55c46SMatthew Dillon ORDERKEY_STATE 80350a55c46SMatthew Dillon ORDERKEY_PRIO 80450a55c46SMatthew Dillon {} 80550a55c46SMatthew Dillon 80650a55c46SMatthew Dillon return (result); 80750a55c46SMatthew Dillon } 80850a55c46SMatthew Dillon 8097af1b2bcSJan Lentfer /* compare_time - the comparison function for sorting by total cpu time */ 8107af1b2bcSJan Lentfer 8117af1b2bcSJan Lentfer int 8128b72b421SJan Lentfer compare_time(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 8137af1b2bcSJan Lentfer { 8148b72b421SJan Lentfer struct kinfo_proc *p1; 8158b72b421SJan Lentfer struct kinfo_proc *p2; 8167af1b2bcSJan Lentfer int result; 8177af1b2bcSJan Lentfer pctcpu lresult; 8187af1b2bcSJan Lentfer 8197af1b2bcSJan Lentfer /* remove one level of indirection */ 8208b72b421SJan Lentfer p1 = *(struct kinfo_proc **) pp1; 8218b72b421SJan Lentfer p2 = *(struct kinfo_proc **) pp2; 8227af1b2bcSJan Lentfer 8237af1b2bcSJan Lentfer ORDERKEY_CPTICKS 8247af1b2bcSJan Lentfer ORDERKEY_PCTCPU 8257af1b2bcSJan Lentfer ORDERKEY_KTHREADS 8267af1b2bcSJan Lentfer ORDERKEY_KTHREADS_PRIO 8277af1b2bcSJan Lentfer ORDERKEY_STATE 8287af1b2bcSJan Lentfer ORDERKEY_PRIO 8297af1b2bcSJan Lentfer ORDERKEY_RSSIZE 8307af1b2bcSJan Lentfer ORDERKEY_MEM 8317af1b2bcSJan Lentfer {} 8327af1b2bcSJan Lentfer 8337af1b2bcSJan Lentfer return (result); 8347af1b2bcSJan Lentfer } 8357af1b2bcSJan Lentfer 836bcd4a7c1SJan Lentfer int 837bcd4a7c1SJan Lentfer compare_ctime(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 838bcd4a7c1SJan Lentfer { 839bcd4a7c1SJan Lentfer struct kinfo_proc *p1; 840bcd4a7c1SJan Lentfer struct kinfo_proc *p2; 841bcd4a7c1SJan Lentfer int result; 842bcd4a7c1SJan Lentfer pctcpu lresult; 843bcd4a7c1SJan Lentfer 844bcd4a7c1SJan Lentfer /* remove one level of indirection */ 845bcd4a7c1SJan Lentfer p1 = *(struct kinfo_proc **) pp1; 846bcd4a7c1SJan Lentfer p2 = *(struct kinfo_proc **) pp2; 847bcd4a7c1SJan Lentfer 848bcd4a7c1SJan Lentfer ORDERKEY_CTIME 849bcd4a7c1SJan Lentfer ORDERKEY_PCTCPU 850bcd4a7c1SJan Lentfer ORDERKEY_KTHREADS 851bcd4a7c1SJan Lentfer ORDERKEY_KTHREADS_PRIO 852bcd4a7c1SJan Lentfer ORDERKEY_STATE 853bcd4a7c1SJan Lentfer ORDERKEY_PRIO 854bcd4a7c1SJan Lentfer ORDERKEY_RSSIZE 855bcd4a7c1SJan Lentfer ORDERKEY_MEM 856bcd4a7c1SJan Lentfer {} 857bcd4a7c1SJan Lentfer 858bcd4a7c1SJan Lentfer return (result); 859bcd4a7c1SJan Lentfer } 860bcd4a7c1SJan Lentfer 8617af1b2bcSJan Lentfer /* compare_prio - the comparison function for sorting by cpu percentage */ 8627af1b2bcSJan Lentfer 8637af1b2bcSJan Lentfer int 8648b72b421SJan Lentfer compare_prio(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 8657af1b2bcSJan Lentfer { 8668b72b421SJan Lentfer struct kinfo_proc *p1; 8678b72b421SJan Lentfer struct kinfo_proc *p2; 8687af1b2bcSJan Lentfer int result; 8697af1b2bcSJan Lentfer pctcpu lresult; 8707af1b2bcSJan Lentfer 8717af1b2bcSJan Lentfer /* remove one level of indirection */ 8728b72b421SJan Lentfer p1 = *(struct kinfo_proc **) pp1; 8738b72b421SJan Lentfer p2 = *(struct kinfo_proc **) pp2; 8747af1b2bcSJan Lentfer 8757af1b2bcSJan Lentfer ORDERKEY_KTHREADS 8767af1b2bcSJan Lentfer ORDERKEY_KTHREADS_PRIO 8777af1b2bcSJan Lentfer ORDERKEY_PRIO 8787af1b2bcSJan Lentfer ORDERKEY_CPTICKS 8797af1b2bcSJan Lentfer ORDERKEY_PCTCPU 8807af1b2bcSJan Lentfer ORDERKEY_STATE 8817af1b2bcSJan Lentfer ORDERKEY_RSSIZE 8827af1b2bcSJan Lentfer ORDERKEY_MEM 8837af1b2bcSJan Lentfer {} 8847af1b2bcSJan Lentfer 8857af1b2bcSJan Lentfer return (result); 8867af1b2bcSJan Lentfer } 8877af1b2bcSJan Lentfer 8887af1b2bcSJan Lentfer int 8898b72b421SJan Lentfer compare_thr(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 8907af1b2bcSJan Lentfer { 8918b72b421SJan Lentfer struct kinfo_proc *p1; 8928b72b421SJan Lentfer struct kinfo_proc *p2; 8937af1b2bcSJan Lentfer int result; 8947af1b2bcSJan Lentfer pctcpu lresult; 8957af1b2bcSJan Lentfer 8967af1b2bcSJan Lentfer /* remove one level of indirection */ 8978b72b421SJan Lentfer p1 = *(struct kinfo_proc **)pp1; 8988b72b421SJan Lentfer p2 = *(struct kinfo_proc **)pp2; 8997af1b2bcSJan Lentfer 9007af1b2bcSJan Lentfer ORDERKEY_KTHREADS 9017af1b2bcSJan Lentfer ORDERKEY_KTHREADS_PRIO 9027af1b2bcSJan Lentfer ORDERKEY_CPTICKS 9037af1b2bcSJan Lentfer ORDERKEY_PCTCPU 9047af1b2bcSJan Lentfer ORDERKEY_STATE 9057af1b2bcSJan Lentfer ORDERKEY_RSSIZE 9067af1b2bcSJan Lentfer ORDERKEY_MEM 9077af1b2bcSJan Lentfer {} 9087af1b2bcSJan Lentfer 9097af1b2bcSJan Lentfer return (result); 9107af1b2bcSJan Lentfer } 9117af1b2bcSJan Lentfer 9128b72b421SJan Lentfer /* compare_pid - the comparison function for sorting by process id */ 9138b72b421SJan Lentfer 9148b72b421SJan Lentfer int 9158b72b421SJan Lentfer compare_pid(struct kinfo_proc **pp1, struct kinfo_proc **pp2) 9168b72b421SJan Lentfer { 9178b72b421SJan Lentfer struct kinfo_proc *p1; 9188b72b421SJan Lentfer struct kinfo_proc *p2; 9198b72b421SJan Lentfer int result; 9208b72b421SJan Lentfer 9218b72b421SJan Lentfer /* remove one level of indirection */ 9228b72b421SJan Lentfer p1 = *(struct kinfo_proc **) pp1; 9238b72b421SJan Lentfer p2 = *(struct kinfo_proc **) pp2; 9248b72b421SJan Lentfer 9258b72b421SJan Lentfer ORDERKEY_PID 9268b72b421SJan Lentfer ; 9278b72b421SJan Lentfer 9288b72b421SJan Lentfer return(result); 9298b72b421SJan Lentfer } 9308b72b421SJan Lentfer 9317af1b2bcSJan Lentfer /* 9327af1b2bcSJan Lentfer * proc_owner(pid) - returns the uid that owns process "pid", or -1 if 9337af1b2bcSJan Lentfer * the process does not exist. 9347af1b2bcSJan Lentfer * It is EXTREMLY IMPORTANT that this function work correctly. 9357af1b2bcSJan Lentfer * If top runs setuid root (as in SVR4), then this function 9367af1b2bcSJan Lentfer * is the only thing that stands in the way of a serious 9377af1b2bcSJan Lentfer * security problem. It validates requests for the "kill" 9387af1b2bcSJan Lentfer * and "renice" commands. 9397af1b2bcSJan Lentfer */ 9407af1b2bcSJan Lentfer 9417af1b2bcSJan Lentfer int 9427af1b2bcSJan Lentfer proc_owner(int pid) 9437af1b2bcSJan Lentfer { 9447af1b2bcSJan Lentfer int xcnt; 9457af1b2bcSJan Lentfer struct kinfo_proc **prefp; 9467af1b2bcSJan Lentfer struct kinfo_proc *pp; 9477af1b2bcSJan Lentfer 9487af1b2bcSJan Lentfer prefp = pref; 9497af1b2bcSJan Lentfer xcnt = pref_len; 950961f1f09SJan Lentfer while (--xcnt >= 0) { 9517af1b2bcSJan Lentfer pp = *prefp++; 952961f1f09SJan Lentfer if (PP(pp, pid) == (pid_t) pid) { 9537af1b2bcSJan Lentfer return ((int)PP(pp, ruid)); 9547af1b2bcSJan Lentfer } 9557af1b2bcSJan Lentfer } 9567af1b2bcSJan Lentfer return (-1); 9577af1b2bcSJan Lentfer } 9587af1b2bcSJan Lentfer 9597af1b2bcSJan Lentfer 9607af1b2bcSJan Lentfer /* 9617af1b2bcSJan Lentfer * swapmode is based on a program called swapinfo written 9627af1b2bcSJan Lentfer * by Kevin Lahey <kml@rokkaku.atl.ga.us>. 9637af1b2bcSJan Lentfer */ 9647af1b2bcSJan Lentfer int 9657af1b2bcSJan Lentfer swapmode(int *retavail, int *retfree) 9667af1b2bcSJan Lentfer { 9677af1b2bcSJan Lentfer int n; 9687af1b2bcSJan Lentfer int pagesize = getpagesize(); 9697af1b2bcSJan Lentfer struct kvm_swap swapary[1]; 9707af1b2bcSJan Lentfer 9717af1b2bcSJan Lentfer *retavail = 0; 9727af1b2bcSJan Lentfer *retfree = 0; 9737af1b2bcSJan Lentfer 9747af1b2bcSJan Lentfer #define CONVERT(v) ((quad_t)(v) * pagesize / 1024) 9757af1b2bcSJan Lentfer 9767af1b2bcSJan Lentfer n = kvm_getswapinfo(kd, swapary, 1, 0); 9777af1b2bcSJan Lentfer if (n < 0 || swapary[0].ksw_total == 0) 9787af1b2bcSJan Lentfer return (0); 9797af1b2bcSJan Lentfer 9807af1b2bcSJan Lentfer *retavail = CONVERT(swapary[0].ksw_total); 9817af1b2bcSJan Lentfer *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used); 9827af1b2bcSJan Lentfer 9837af1b2bcSJan Lentfer n = (int)((double)swapary[0].ksw_used * 100.0 / 9847af1b2bcSJan Lentfer (double)swapary[0].ksw_total); 9857af1b2bcSJan Lentfer return (n); 9867af1b2bcSJan Lentfer } 987