]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/top/machine.c
top(1): actually make change for tid vs pid
[FreeBSD/FreeBSD.git] / usr.bin / top / machine.c
1 /*
2  * top - a top users display for Unix
3  *
4  * DESCRIPTION:
5  * Originally written for BSD4.4 system by Christos Zoulas.
6  * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider
7  * Order support hacked in from top-3.5beta6/machine/m_aix41.c
8  *   by Monte Mitzelfelt (for latest top see http://www.groupsys.com/topinfo/)
9  *
10  * AUTHOR:  Christos Zoulas <christos@ee.cornell.edu>
11  *          Steven Wallace  <swallace@FreeBSD.org>
12  *          Wolfram Schneider <wosch@FreeBSD.org>
13  *          Thomas Moestl <tmoestl@gmx.net>
14  *          Eitan Adler <eadler@FreeBSD.org>
15  *
16  * $FreeBSD$
17  */
18
19 #include <sys/errno.h>
20 #include <sys/fcntl.h>
21 #include <sys/param.h>
22 #include <sys/priority.h>
23 #include <sys/proc.h>
24 #include <sys/resource.h>
25 #include <sys/sysctl.h>
26 #include <sys/time.h>
27 #include <sys/user.h>
28
29 #include <assert.h>
30 #include <err.h>
31 #include <kvm.h>
32 #include <math.h>
33 #include <paths.h>
34 #include <stdio.h>
35 #include <stdbool.h>
36 #include <stdint.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <time.h>
40 #include <unistd.h>
41 #include <vis.h>
42
43 #include "top.h"
44 #include "display.h"
45 #include "machine.h"
46 #include "loadavg.h"
47 #include "screen.h"
48 #include "utils.h"
49 #include "layout.h"
50
51 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
52 #define SMPUNAMELEN     13
53 #define UPUNAMELEN      15
54
55 extern struct timeval timeout;
56 static int smpmode;
57 enum displaymodes displaymode;
58 static int namelength = 8;
59 /* TOP_JID_LEN based on max of 999999 */
60 #define TOP_JID_LEN 7
61 #define TOP_SWAP_LEN 6
62 static int jidlength;
63 static int swaplength;
64 static int cmdlengthdelta;
65
66 /* get_process_info passes back a handle.  This is what it looks like: */
67
68 struct handle {
69         struct kinfo_proc **next_proc;  /* points to next valid proc pointer */
70         int remaining;                  /* number of pointers remaining */
71 };
72
73
74 /* define what weighted cpu is.  */
75 #define weighted_cpu(pct, pp) ((pp)->ki_swtime == 0 ? 0.0 : \
76                          ((pct) / (1.0 - exp((pp)->ki_swtime * logcpu))))
77
78 /* what we consider to be process size: */
79 #define PROCSIZE(pp) ((pp)->ki_size / 1024)
80
81 #define RU(pp)  (&(pp)->ki_rusage)
82 #define RUTOT(pp) \
83         (RU(pp)->ru_inblock + RU(pp)->ru_oublock + RU(pp)->ru_majflt)
84
85 #define PCTCPU(pp) (pcpu[pp - pbase])
86
87 /*
88  *  These definitions control the format of the per-process area
89  */
90
91 static const char io_header[] =
92     "  PID%*s %-*.*s   VCSW  IVCSW   READ  WRITE  FAULT  TOTAL PERCENT COMMAND";
93
94 static const char io_Proc_format[] =
95     "%5d%*s %-*.*s %6ld %6ld %6ld %6ld %6ld %6ld %6.2f%% %.*s";
96
97 static const char smp_header_thr_and_pid[] =
98     "  PID%*s %-*.*s  THR PRI NICE   SIZE    RES%*s STATE   C   TIME %7s COMMAND";
99 static const char smp_header_tid_only[] =
100     "  THR%*s %-*.*s "   "PRI NICE   SIZE    RES%*s STATE   C   TIME %7s COMMAND";
101 static const char smp_Proc_format[] =
102     "%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s %2d%7s %6.2f%% %.*s";
103
104 static char up_header_thr_and_pid[] =
105     "  PID%*s %-*.*s  THR PRI NICE   SIZE    RES%*s STATE    TIME %7s COMMAND";
106 static char up_header_tid_only[] =
107     "  THR%*s %-*.*s "   "PRI NICE   SIZE    RES%*s STATE    TIME %7s COMMAND";
108 static char up_Proc_format[] =
109     "%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s%.0d%7s %6.2f%% %.*s";
110
111
112 /* process state names for the "STATE" column of the display */
113 /* the extra nulls in the string "run" are for adding a slash and
114    the processor number when needed */
115
116 static const char *state_abbrev[] = {
117         "", "START", "RUN\0\0\0", "SLEEP", "STOP", "ZOMB", "WAIT", "LOCK"
118 };
119
120
121 static kvm_t *kd;
122
123 /* values that we stash away in _init and use in later routines */
124
125 static double logcpu;
126
127 /* these are retrieved from the kernel in _init */
128
129 static load_avg  ccpu;
130
131 /* these are used in the get_ functions */
132
133 static int lastpid;
134
135 /* these are for calculating cpu state percentages */
136
137 static long cp_time[CPUSTATES];
138 static long cp_old[CPUSTATES];
139 static long cp_diff[CPUSTATES];
140
141 /* these are for detailing the process states */
142
143 static const char *procstatenames[] = {
144         "", " starting, ", " running, ", " sleeping, ", " stopped, ",
145         " zombie, ", " waiting, ", " lock, ",
146         NULL
147 };
148 static int process_states[nitems(procstatenames)];
149
150 /* these are for detailing the cpu states */
151
152 static int cpu_states[CPUSTATES];
153 static const char *cpustatenames[] = {
154         "user", "nice", "system", "interrupt", "idle", NULL
155 };
156
157 /* these are for detailing the memory statistics */
158
159 static const char *memorynames[] = {
160         "K Active, ", "K Inact, ", "K Laundry, ", "K Wired, ", "K Buf, ",
161         "K Free", NULL
162 };
163 static int memory_stats[nitems(memorynames)];
164
165 static const char *arcnames[] = {
166         "K Total, ", "K MFU, ", "K MRU, ", "K Anon, ", "K Header, ", "K Other",
167         NULL
168 };
169 static int arc_stats[nitems(arcnames)];
170
171 static const char *carcnames[] = {
172         "K Compressed, ", "K Uncompressed, ", ":1 Ratio, ",
173         NULL
174 };
175 static int carc_stats[nitems(carcnames)];
176
177 static const char *swapnames[] = {
178         "K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out",
179         NULL
180 };
181 static int swap_stats[nitems(swapnames)];
182
183
184 /* these are for keeping track of the proc array */
185
186 static int nproc;
187 static int onproc = -1;
188 static int pref_len;
189 static struct kinfo_proc *pbase;
190 static struct kinfo_proc **pref;
191 static struct kinfo_proc *previous_procs;
192 static struct kinfo_proc **previous_pref;
193 static int previous_proc_count = 0;
194 static int previous_proc_count_max = 0;
195 static int previous_thread;
196
197 /* data used for recalculating pctcpu */
198 static double *pcpu;
199 static struct timespec proc_uptime;
200 static struct timeval proc_wall_time;
201 static struct timeval previous_wall_time;
202 static uint64_t previous_interval = 0;
203
204 /* total number of io operations */
205 static long total_inblock;
206 static long total_oublock;
207 static long total_majflt;
208
209 /* these are for getting the memory statistics */
210
211 static int arc_enabled;
212 static int carc_enabled;
213 static int pageshift;           /* log base 2 of the pagesize */
214
215 /* define pagetok in terms of pageshift */
216
217 #define pagetok(size) ((size) << pageshift)
218
219 /* swap usage */
220 #define ki_swap(kip) \
221     ((kip)->ki_swrss > (kip)->ki_rssize ? (kip)->ki_swrss - (kip)->ki_rssize : 0)
222
223 /*
224  * Sorting orders.  The first element is the default.
225  */
226 static const char *ordernames[] = {
227         "cpu", "size", "res", "time", "pri", "threads",
228         "total", "read", "write", "fault", "vcsw", "ivcsw",
229         "jid", "swap", "pid", NULL
230 };
231
232 /* Per-cpu time states */
233 static int maxcpu;
234 static int maxid;
235 static int ncpus;
236 static unsigned long cpumask;
237 static long *times;
238 static long *pcpu_cp_time;
239 static long *pcpu_cp_old;
240 static long *pcpu_cp_diff;
241 static int *pcpu_cpu_states;
242
243 static int compare_swap(const void *a, const void *b);
244 static int compare_jid(const void *a, const void *b);
245 static int compare_pid(const void *a, const void *b);
246 static int compare_tid(const void *a, const void *b);
247 static const char *format_nice(const struct kinfo_proc *pp);
248 static void getsysctl(const char *name, void *ptr, size_t len);
249 static int swapmode(int *retavail, int *retfree);
250 static void update_layout(void);
251 static int find_uid(uid_t needle, int *haystack);
252
253 static int
254 find_uid(uid_t needle, int *haystack)
255 {
256         size_t i = 0;
257
258         for (; i < TOP_MAX_UIDS; ++i)
259                 if ((uid_t)haystack[i] == needle)
260                         return 1;
261         return (0);
262 }
263
264 void
265 toggle_pcpustats(void)
266 {
267
268         if (ncpus == 1)
269                 return;
270         update_layout();
271 }
272
273 /* Adjust display based on ncpus and the ARC state. */
274 static void
275 update_layout(void)
276 {
277
278         y_mem = 3;
279         y_arc = 4;
280         y_carc = 5;
281         y_swap = 4 + arc_enabled + carc_enabled;
282         y_idlecursor = 5 + arc_enabled + carc_enabled;
283         y_message = 5 + arc_enabled + carc_enabled;
284         y_header = 6 + arc_enabled + carc_enabled;
285         y_procs = 7 + arc_enabled + carc_enabled;
286         Header_lines = 7 + arc_enabled + carc_enabled;
287
288         if (pcpu_stats) {
289                 y_mem += ncpus - 1;
290                 y_arc += ncpus - 1;
291                 y_carc += ncpus - 1;
292                 y_swap += ncpus - 1;
293                 y_idlecursor += ncpus - 1;
294                 y_message += ncpus - 1;
295                 y_header += ncpus - 1;
296                 y_procs += ncpus - 1;
297                 Header_lines += ncpus - 1;
298         }
299 }
300
301 int
302 machine_init(struct statics *statics)
303 {
304         int i, j, empty, pagesize;
305         uint64_t arc_size;
306         bool carc_en;
307         size_t size;
308
309         size = sizeof(smpmode);
310         if ((sysctlbyname("machdep.smp_active", &smpmode, &size,
311             NULL, 0) != 0 &&
312             sysctlbyname("kern.smp.active", &smpmode, &size,
313             NULL, 0) != 0) ||
314             size != sizeof(smpmode))
315                 smpmode = 0;
316
317         size = sizeof(arc_size);
318         if (sysctlbyname("kstat.zfs.misc.arcstats.size", &arc_size, &size,
319             NULL, 0) == 0 && arc_size != 0)
320                 arc_enabled = 1;
321         size = sizeof(carc_en);
322         if (arc_enabled &&
323             sysctlbyname("vfs.zfs.compressed_arc_enabled", &carc_en, &size,
324             NULL, 0) == 0 && carc_en == 1)
325                 carc_enabled = 1;
326
327         namelength = MAXLOGNAME;
328         if (smpmode && namelength > SMPUNAMELEN)
329                 namelength = SMPUNAMELEN;
330         else if (namelength > UPUNAMELEN)
331                 namelength = UPUNAMELEN;
332
333         kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
334         if (kd == NULL)
335                 return (-1);
336
337         GETSYSCTL("kern.ccpu", ccpu);
338
339         /* this is used in calculating WCPU -- calculate it ahead of time */
340         logcpu = log(loaddouble(ccpu));
341
342         pbase = NULL;
343         pref = NULL;
344         pcpu = NULL;
345         nproc = 0;
346         onproc = -1;
347
348         /* get the page size and calculate pageshift from it */
349         pagesize = getpagesize();
350         pageshift = 0;
351         while (pagesize > 1) {
352                 pageshift++;
353                 pagesize >>= 1;
354         }
355
356         /* we only need the amount of log(2)1024 for our conversion */
357         pageshift -= LOG1024;
358
359         /* fill in the statics information */
360         statics->procstate_names = procstatenames;
361         statics->cpustate_names = cpustatenames;
362         statics->memory_names = memorynames;
363         if (arc_enabled)
364                 statics->arc_names = arcnames;
365         else
366                 statics->arc_names = NULL;
367         if (carc_enabled)
368                 statics->carc_names = carcnames;
369         else
370                 statics->carc_names = NULL;
371         statics->swap_names = swapnames;
372         statics->order_names = ordernames;
373
374         /* Allocate state for per-CPU stats. */
375         cpumask = 0;
376         ncpus = 0;
377         GETSYSCTL("kern.smp.maxcpus", maxcpu);
378         times = calloc(maxcpu * CPUSTATES, sizeof(long));
379         if (times == NULL)
380                 err(1, "calloc for kern.smp.maxcpus");
381         size = sizeof(long) * maxcpu * CPUSTATES;
382         if (sysctlbyname("kern.cp_times", times, &size, NULL, 0) == -1)
383                 err(1, "sysctlbyname kern.cp_times");
384         pcpu_cp_time = calloc(1, size);
385         maxid = (size / CPUSTATES / sizeof(long)) - 1;
386         for (i = 0; i <= maxid; i++) {
387                 empty = 1;
388                 for (j = 0; empty && j < CPUSTATES; j++) {
389                         if (times[i * CPUSTATES + j] != 0)
390                                 empty = 0;
391                 }
392                 if (!empty) {
393                         cpumask |= (1ul << i);
394                         ncpus++;
395                 }
396         }
397         assert(ncpus > 0);
398         pcpu_cp_old = calloc(ncpus * CPUSTATES, sizeof(long));
399         pcpu_cp_diff = calloc(ncpus * CPUSTATES, sizeof(long));
400         pcpu_cpu_states = calloc(ncpus * CPUSTATES, sizeof(int));
401         statics->ncpus = ncpus;
402
403         update_layout();
404
405         /* all done! */
406         return (0);
407 }
408
409 const char *
410 format_header(const char *uname_field)
411 {
412         static char Header[128];
413         const char *prehead;
414
415         if (ps.jail)
416                 jidlength = TOP_JID_LEN + 1;    /* +1 for extra left space. */
417         else
418                 jidlength = 0;
419
420         if (ps.swap)
421                 swaplength = TOP_SWAP_LEN + 1;  /* +1 for extra left space */
422         else
423                 swaplength = 0;
424
425         switch (displaymode) {
426         case DISP_CPU:
427                 /*
428                  * The logic of picking the right header format seems reverse
429                  * here because we only want to display a THR column when
430                  * "thread mode" is off (and threads are not listed as
431                  * separate lines).
432                  */
433                 prehead = smpmode ?
434                     (ps.thread_id ? smp_header_tid_only : smp_header_thr_and_pid) :
435                     (ps.thread_id ? up_header_tid_only : up_header_thr_and_pid);
436                 snprintf(Header, sizeof(Header), prehead,
437                     jidlength, ps.jail ? " JID" : "",
438                     namelength, namelength, uname_field,
439                     swaplength, ps.swap ? " SWAP" : "",
440                     ps.wcpu ? "WCPU" : "CPU");
441                 break;
442         case DISP_IO:
443                 prehead = io_header;
444                 snprintf(Header, sizeof(Header), prehead,
445                     jidlength, ps.jail ? " JID" : "",
446                     namelength, namelength, uname_field);
447                 break;
448         case DISP_MAX:
449                 assert("displaymode must not be set to DISP_MAX");
450         }
451         cmdlengthdelta = strlen(Header) - 7;
452         return (Header);
453 }
454
455 static int swappgsin = -1;
456 static int swappgsout = -1;
457
458
459 void
460 get_system_info(struct system_info *si)
461 {
462         struct loadavg sysload;
463         int mib[2];
464         struct timeval boottime;
465         uint64_t arc_stat, arc_stat2;
466         int i, j;
467         size_t size;
468
469         /* get the CPU stats */
470         size = (maxid + 1) * CPUSTATES * sizeof(long);
471         if (sysctlbyname("kern.cp_times", pcpu_cp_time, &size, NULL, 0) == -1)
472                 err(1, "sysctlbyname kern.cp_times");
473         GETSYSCTL("kern.cp_time", cp_time);
474         GETSYSCTL("vm.loadavg", sysload);
475         GETSYSCTL("kern.lastpid", lastpid);
476
477         /* convert load averages to doubles */
478         for (i = 0; i < 3; i++)
479                 si->load_avg[i] = (double)sysload.ldavg[i] / sysload.fscale;
480
481         /* convert cp_time counts to percentages */
482         for (i = j = 0; i <= maxid; i++) {
483                 if ((cpumask & (1ul << i)) == 0)
484                         continue;
485                 percentages(CPUSTATES, &pcpu_cpu_states[j * CPUSTATES],
486                     &pcpu_cp_time[j * CPUSTATES],
487                     &pcpu_cp_old[j * CPUSTATES],
488                     &pcpu_cp_diff[j * CPUSTATES]);
489                 j++;
490         }
491         percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);
492
493         /* sum memory & swap statistics */
494         {
495                 static unsigned int swap_delay = 0;
496                 static int swapavail = 0;
497                 static int swapfree = 0;
498                 static long bufspace = 0;
499                 static uint64_t nspgsin, nspgsout;
500
501                 GETSYSCTL("vfs.bufspace", bufspace);
502                 GETSYSCTL("vm.stats.vm.v_active_count", memory_stats[0]);
503                 GETSYSCTL("vm.stats.vm.v_inactive_count", memory_stats[1]);
504                 GETSYSCTL("vm.stats.vm.v_laundry_count", memory_stats[2]);
505                 GETSYSCTL("vm.stats.vm.v_wire_count", memory_stats[3]);
506                 GETSYSCTL("vm.stats.vm.v_free_count", memory_stats[5]);
507                 GETSYSCTL("vm.stats.vm.v_swappgsin", nspgsin);
508                 GETSYSCTL("vm.stats.vm.v_swappgsout", nspgsout);
509                 /* convert memory stats to Kbytes */
510                 memory_stats[0] = pagetok(memory_stats[0]);
511                 memory_stats[1] = pagetok(memory_stats[1]);
512                 memory_stats[2] = pagetok(memory_stats[2]);
513                 memory_stats[3] = pagetok(memory_stats[3]);
514                 memory_stats[4] = bufspace / 1024;
515                 memory_stats[5] = pagetok(memory_stats[5]);
516                 memory_stats[6] = -1;
517
518                 /* first interval */
519                 if (swappgsin < 0) {
520                         swap_stats[4] = 0;
521                         swap_stats[5] = 0;
522                 }
523
524                 /* compute differences between old and new swap statistic */
525                 else {
526                         swap_stats[4] = pagetok(((nspgsin - swappgsin)));
527                         swap_stats[5] = pagetok(((nspgsout - swappgsout)));
528                 }
529
530                 swappgsin = nspgsin;
531                 swappgsout = nspgsout;
532
533                 /* call CPU heavy swapmode() only for changes */
534                 if (swap_stats[4] > 0 || swap_stats[5] > 0 || swap_delay == 0) {
535                         swap_stats[3] = swapmode(&swapavail, &swapfree);
536                         swap_stats[0] = swapavail;
537                         swap_stats[1] = swapavail - swapfree;
538                         swap_stats[2] = swapfree;
539                 }
540                 swap_delay = 1;
541                 swap_stats[6] = -1;
542         }
543
544         if (arc_enabled) {
545                 GETSYSCTL("kstat.zfs.misc.arcstats.size", arc_stat);
546                 arc_stats[0] = arc_stat >> 10;
547                 GETSYSCTL("vfs.zfs.mfu_size", arc_stat);
548                 arc_stats[1] = arc_stat >> 10;
549                 GETSYSCTL("vfs.zfs.mru_size", arc_stat);
550                 arc_stats[2] = arc_stat >> 10;
551                 GETSYSCTL("vfs.zfs.anon_size", arc_stat);
552                 arc_stats[3] = arc_stat >> 10;
553                 GETSYSCTL("kstat.zfs.misc.arcstats.hdr_size", arc_stat);
554                 GETSYSCTL("kstat.zfs.misc.arcstats.l2_hdr_size", arc_stat2);
555                 arc_stats[4] = (arc_stat + arc_stat2) >> 10;
556                 GETSYSCTL("kstat.zfs.misc.arcstats.other_size", arc_stat);
557                 arc_stats[5] = arc_stat >> 10;
558                 si->arc = arc_stats;
559         }
560         if (carc_enabled) {
561                 GETSYSCTL("kstat.zfs.misc.arcstats.compressed_size", arc_stat);
562                 carc_stats[0] = arc_stat >> 10;
563                 carc_stats[2] = arc_stat >> 10; /* For ratio */
564                 GETSYSCTL("kstat.zfs.misc.arcstats.uncompressed_size", arc_stat);
565                 carc_stats[1] = arc_stat >> 10;
566                 si->carc = carc_stats;
567         }
568
569         /* set arrays and strings */
570         if (pcpu_stats) {
571                 si->cpustates = pcpu_cpu_states;
572                 si->ncpus = ncpus;
573         } else {
574                 si->cpustates = cpu_states;
575                 si->ncpus = 1;
576         }
577         si->memory = memory_stats;
578         si->swap = swap_stats;
579
580
581         if (lastpid > 0) {
582                 si->last_pid = lastpid;
583         } else {
584                 si->last_pid = -1;
585         }
586
587         /*
588          * Print how long system has been up.
589          * (Found by looking getting "boottime" from the kernel)
590          */
591         mib[0] = CTL_KERN;
592         mib[1] = KERN_BOOTTIME;
593         size = sizeof(boottime);
594         if (sysctl(mib, nitems(mib), &boottime, &size, NULL, 0) != -1 &&
595             boottime.tv_sec != 0) {
596                 si->boottime = boottime;
597         } else {
598                 si->boottime.tv_sec = -1;
599         }
600 }
601
602 #define NOPROC  ((void *)-1)
603
604 /*
605  * We need to compare data from the old process entry with the new
606  * process entry.
607  * To facilitate doing this quickly we stash a pointer in the kinfo_proc
608  * structure to cache the mapping.  We also use a negative cache pointer
609  * of NOPROC to avoid duplicate lookups.
610  * XXX: this could be done when the actual processes are fetched, we do
611  * it here out of laziness.
612  */
613 static const struct kinfo_proc *
614 get_old_proc(struct kinfo_proc *pp)
615 {
616         const struct kinfo_proc * const *oldpp, *oldp;
617
618         /*
619          * If this is the first fetch of the kinfo_procs then we don't have
620          * any previous entries.
621          */
622         if (previous_proc_count == 0)
623                 return (NULL);
624         /* negative cache? */
625         if (pp->ki_udata == NOPROC)
626                 return (NULL);
627         /* cached? */
628         if (pp->ki_udata != NULL)
629                 return (pp->ki_udata);
630         /*
631          * Not cached,
632          * 1) look up based on pid.
633          * 2) compare process start.
634          * If we fail here, then setup a negative cache entry, otherwise
635          * cache it.
636          */
637         oldpp = bsearch(&pp, previous_pref, previous_proc_count,
638             sizeof(*previous_pref), ps.thread ? compare_tid : compare_pid);
639         if (oldpp == NULL) {
640                 pp->ki_udata = NOPROC;
641                 return (NULL);
642         }
643         oldp = *oldpp;
644         if (memcmp(&oldp->ki_start, &pp->ki_start, sizeof(pp->ki_start)) != 0) {
645                 pp->ki_udata = NOPROC;
646                 return (NULL);
647         }
648         pp->ki_udata = oldp;
649         return (oldp);
650 }
651
652 /*
653  * Return the total amount of IO done in blocks in/out and faults.
654  * store the values individually in the pointers passed in.
655  */
656 static long
657 get_io_stats(const struct kinfo_proc *pp, long *inp, long *oup, long *flp,
658     long *vcsw, long *ivcsw)
659 {
660         const struct kinfo_proc *oldp;
661         static struct kinfo_proc dummy;
662         long ret;
663
664         oldp = get_old_proc(pp);
665         if (oldp == NULL) {
666                 memset(&dummy, 0, sizeof(dummy));
667                 oldp = &dummy;
668         }
669         *inp = RU(pp)->ru_inblock - RU(oldp)->ru_inblock;
670         *oup = RU(pp)->ru_oublock - RU(oldp)->ru_oublock;
671         *flp = RU(pp)->ru_majflt - RU(oldp)->ru_majflt;
672         *vcsw = RU(pp)->ru_nvcsw - RU(oldp)->ru_nvcsw;
673         *ivcsw = RU(pp)->ru_nivcsw - RU(oldp)->ru_nivcsw;
674         ret =
675             (RU(pp)->ru_inblock - RU(oldp)->ru_inblock) +
676             (RU(pp)->ru_oublock - RU(oldp)->ru_oublock) +
677             (RU(pp)->ru_majflt - RU(oldp)->ru_majflt);
678         return (ret);
679 }
680
681 /*
682  * If there was a previous update, use the delta in ki_runtime over
683  * the previous interval to calculate pctcpu.  Otherwise, fall back
684  * to using the kernel's ki_pctcpu.
685  */
686 static double
687 proc_calc_pctcpu(struct kinfo_proc *pp)
688 {
689         const struct kinfo_proc *oldp;
690
691         if (previous_interval != 0) {
692                 oldp = get_old_proc(pp);
693                 if (oldp != NULL)
694                         return ((double)(pp->ki_runtime - oldp->ki_runtime)
695                             / previous_interval);
696
697                 /*
698                  * If this process/thread was created during the previous
699                  * interval, charge it's total runtime to the previous
700                  * interval.
701                  */
702                 else if (pp->ki_start.tv_sec > previous_wall_time.tv_sec ||
703                     (pp->ki_start.tv_sec == previous_wall_time.tv_sec &&
704                     pp->ki_start.tv_usec >= previous_wall_time.tv_usec))
705                         return ((double)pp->ki_runtime / previous_interval);
706         }
707         return (pctdouble(pp->ki_pctcpu));
708 }
709
710 /*
711  * Return true if this process has used any CPU time since the
712  * previous update.
713  */
714 static int
715 proc_used_cpu(struct kinfo_proc *pp)
716 {
717         const struct kinfo_proc *oldp;
718
719         oldp = get_old_proc(pp);
720         if (oldp == NULL)
721                 return (PCTCPU(pp) != 0);
722         return (pp->ki_runtime != oldp->ki_runtime ||
723             RU(pp)->ru_nvcsw != RU(oldp)->ru_nvcsw ||
724             RU(pp)->ru_nivcsw != RU(oldp)->ru_nivcsw);
725 }
726
727 /*
728  * Return the total number of block in/out and faults by a process.
729  */
730 static long
731 get_io_total(const struct kinfo_proc *pp)
732 {
733         long dummy;
734
735         return (get_io_stats(pp, &dummy, &dummy, &dummy, &dummy, &dummy));
736 }
737
738 static struct handle handle;
739
740 void *
741 get_process_info(struct system_info *si, struct process_select *sel,
742     int (*compare)(const void *, const void *))
743 {
744         int i;
745         int total_procs;
746         long p_io;
747         long p_inblock, p_oublock, p_majflt, p_vcsw, p_ivcsw;
748         long nsec;
749         int active_procs;
750         struct kinfo_proc **prefp;
751         struct kinfo_proc *pp;
752         struct timespec previous_proc_uptime;
753
754         /*
755          * If thread state was toggled, don't cache the previous processes.
756          */
757         if (previous_thread != sel->thread)
758                 nproc = 0;
759         previous_thread = sel->thread;
760
761         /*
762          * Save the previous process info.
763          */
764         if (previous_proc_count_max < nproc) {
765                 free(previous_procs);
766                 previous_procs = calloc(nproc, sizeof(*previous_procs));
767                 free(previous_pref);
768                 previous_pref = calloc(nproc, sizeof(*previous_pref));
769                 if (previous_procs == NULL || previous_pref == NULL) {
770                         fprintf(stderr, "top: Out of memory.\n");
771                         quit(TOP_EX_SYS_ERROR);
772                 }
773                 previous_proc_count_max = nproc;
774         }
775         if (nproc) {
776                 for (i = 0; i < nproc; i++)
777                         previous_pref[i] = &previous_procs[i];
778                 memcpy(previous_procs, pbase, nproc * sizeof(*previous_procs));
779                 qsort(previous_pref, nproc, sizeof(*previous_pref),
780                     ps.thread ? compare_tid : compare_pid);
781         }
782         previous_proc_count = nproc;
783         previous_proc_uptime = proc_uptime;
784         previous_wall_time = proc_wall_time;
785         previous_interval = 0;
786
787         pbase = kvm_getprocs(kd, sel->thread ? KERN_PROC_ALL : KERN_PROC_PROC,
788             0, &nproc);
789         gettimeofday(&proc_wall_time, NULL);
790         if (clock_gettime(CLOCK_UPTIME, &proc_uptime) != 0)
791                 memset(&proc_uptime, 0, sizeof(proc_uptime));
792         else if (previous_proc_uptime.tv_sec != 0 &&
793             previous_proc_uptime.tv_nsec != 0) {
794                 previous_interval = (proc_uptime.tv_sec -
795                     previous_proc_uptime.tv_sec) * 1000000;
796                 nsec = proc_uptime.tv_nsec - previous_proc_uptime.tv_nsec;
797                 if (nsec < 0) {
798                         previous_interval -= 1000000;
799                         nsec += 1000000000;
800                 }
801                 previous_interval += nsec / 1000;
802         }
803         if (nproc > onproc) {
804                 pref = realloc(pref, sizeof(*pref) * nproc);
805                 pcpu = realloc(pcpu, sizeof(*pcpu) * nproc);
806                 onproc = nproc;
807         }
808         if (pref == NULL || pbase == NULL || pcpu == NULL) {
809                 fprintf(stderr, "top: Out of memory.\n");
810                 quit(TOP_EX_SYS_ERROR);
811         }
812         /* get a pointer to the states summary array */
813         si->procstates = process_states;
814
815         /* count up process states and get pointers to interesting procs */
816         total_procs = 0;
817         active_procs = 0;
818         total_inblock = 0;
819         total_oublock = 0;
820         total_majflt = 0;
821         memset(process_states, 0, sizeof(process_states));
822         prefp = pref;
823         for (pp = pbase, i = 0; i < nproc; pp++, i++) {
824
825                 if (pp->ki_stat == 0)
826                         /* not in use */
827                         continue;
828
829                 if (!sel->self && pp->ki_pid == mypid)
830                         /* skip self */
831                         continue;
832
833                 if (!sel->system && (pp->ki_flag & P_SYSTEM))
834                         /* skip system process */
835                         continue;
836
837                 p_io = get_io_stats(pp, &p_inblock, &p_oublock, &p_majflt,
838                     &p_vcsw, &p_ivcsw);
839                 total_inblock += p_inblock;
840                 total_oublock += p_oublock;
841                 total_majflt += p_majflt;
842                 total_procs++;
843                 process_states[(unsigned char)pp->ki_stat]++;
844
845                 if (pp->ki_stat == SZOMB)
846                         /* skip zombies */
847                         continue;
848
849                 if (!sel->kidle && pp->ki_tdflags & TDF_IDLETD)
850                         /* skip kernel idle process */
851                         continue;
852
853                 PCTCPU(pp) = proc_calc_pctcpu(pp);
854                 if (sel->thread && PCTCPU(pp) > 1.0)
855                         PCTCPU(pp) = 1.0;
856                 if (displaymode == DISP_CPU && !sel->idle &&
857                     (!proc_used_cpu(pp) ||
858                      pp->ki_stat == SSTOP || pp->ki_stat == SIDL))
859                         /* skip idle or non-running processes */
860                         continue;
861
862                 if (displaymode == DISP_IO && !sel->idle && p_io == 0)
863                         /* skip processes that aren't doing I/O */
864                         continue;
865
866                 if (sel->jid != -1 && pp->ki_jid != sel->jid)
867                         /* skip proc. that don't belong to the selected JID */
868                         continue;
869
870                 if (sel->uid[0] != -1 && !find_uid(pp->ki_ruid, sel->uid))
871                         /* skip proc. that don't belong to the selected UID */
872                         continue;
873
874                 if (sel->pid != -1 && pp->ki_pid != sel->pid)
875                         continue;
876
877                 *prefp++ = pp;
878                 active_procs++;
879         }
880
881         /* if requested, sort the "interesting" processes */
882         if (compare != NULL)
883                 qsort(pref, active_procs, sizeof(*pref), compare);
884
885         /* remember active and total counts */
886         si->p_total = total_procs;
887         si->p_pactive = pref_len = active_procs;
888
889         /* pass back a handle */
890         handle.next_proc = pref;
891         handle.remaining = active_procs;
892         return (&handle);
893 }
894
895 static char fmt[512];   /* static area where result is built */
896
897 char *
898 format_next_process(void* xhandle, char *(*get_userid)(int), int flags)
899 {
900         struct kinfo_proc *pp;
901         const struct kinfo_proc *oldp;
902         long cputime;
903         double pct;
904         struct handle *hp;
905         char status[22];
906         int cpu;
907         size_t state;
908         struct rusage ru, *rup;
909         long p_tot, s_tot;
910         const char *proc_fmt;
911         char thr_buf[6];
912         char jid_buf[TOP_JID_LEN + 1], swap_buf[TOP_SWAP_LEN + 1];
913         char *cmdbuf = NULL;
914         char **args;
915         const int cmdlen = 128;
916
917         /* find and remember the next proc structure */
918         hp = (struct handle *)xhandle;
919         pp = *(hp->next_proc++);
920         hp->remaining--;
921
922         /* get the process's command name */
923         if ((pp->ki_flag & P_INMEM) == 0) {
924                 /*
925                  * Print swapped processes as <pname>
926                  */
927                 size_t len;
928
929                 len = strlen(pp->ki_comm);
930                 if (len > sizeof(pp->ki_comm) - 3)
931                         len = sizeof(pp->ki_comm) - 3;
932                 memmove(pp->ki_comm + 1, pp->ki_comm, len);
933                 pp->ki_comm[0] = '<';
934                 pp->ki_comm[len + 1] = '>';
935                 pp->ki_comm[len + 2] = '\0';
936         }
937
938         /*
939          * Convert the process's runtime from microseconds to seconds.  This
940          * time includes the interrupt time although that is not wanted here.
941          * ps(1) is similarly sloppy.
942          */
943         cputime = (pp->ki_runtime + 500000) / 1000000;
944
945         /* calculate the base for cpu percentages */
946         pct = PCTCPU(pp);
947
948         /* generate "STATE" field */
949         switch (state = pp->ki_stat) {
950         case SRUN:
951                 if (smpmode && pp->ki_oncpu != NOCPU)
952                         sprintf(status, "CPU%d", pp->ki_oncpu);
953                 else
954                         strcpy(status, "RUN");
955                 break;
956         case SLOCK:
957                 if (pp->ki_kiflag & KI_LOCKBLOCK) {
958                         sprintf(status, "*%.6s", pp->ki_lockname);
959                         break;
960                 }
961                 /* fall through */
962         case SSLEEP:
963                 sprintf(status, "%.6s", pp->ki_wmesg);
964                 break;
965         default:
966
967                 if (state < nitems(state_abbrev)) {
968                         sprintf(status, "%.6s", state_abbrev[state]);
969                 } else {
970                         sprintf(status, "?%5zu", state);
971                 }
972                 break;
973         }
974
975         cmdbuf = calloc(cmdlen + 1, 1);
976         if (cmdbuf == NULL) {
977                 warn("calloc(%d)", cmdlen + 1);
978                 return NULL;
979         }
980
981         if (!(flags & FMT_SHOWARGS)) {
982                 if (ps.thread && pp->ki_flag & P_HADTHREADS &&
983                     pp->ki_tdname[0]) {
984                         snprintf(cmdbuf, cmdlen, "%s{%s%s}", pp->ki_comm,
985                             pp->ki_tdname, pp->ki_moretdname);
986                 } else {
987                         snprintf(cmdbuf, cmdlen, "%s", pp->ki_comm);
988                 }
989         } else {
990                 if (pp->ki_flag & P_SYSTEM ||
991                     pp->ki_args == NULL ||
992                     (args = kvm_getargv(kd, pp, cmdlen)) == NULL ||
993                     !(*args)) {
994                         if (ps.thread && pp->ki_flag & P_HADTHREADS &&
995                             pp->ki_tdname[0]) {
996                                 snprintf(cmdbuf, cmdlen,
997                                     "[%s{%s%s}]", pp->ki_comm, pp->ki_tdname,
998                                     pp->ki_moretdname);
999                         } else {
1000                                 snprintf(cmdbuf, cmdlen,
1001                                     "[%s]", pp->ki_comm);
1002                         }
1003                 } else {
1004                         const char *src;
1005                         char *dst, *argbuf;
1006                         const char *cmd;
1007                         size_t argbuflen;
1008                         size_t len;
1009
1010                         argbuflen = cmdlen * 4;
1011                         argbuf = calloc(argbuflen + 1, 1);
1012                         if (argbuf == NULL) {
1013                                 warn("calloc(%zu)", argbuflen + 1);
1014                                 free(cmdbuf);
1015                                 return NULL;
1016                         }
1017
1018                         dst = argbuf;
1019
1020                         /* Extract cmd name from argv */
1021                         cmd = strrchr(*args, '/');
1022                         if (cmd == NULL)
1023                                 cmd = *args;
1024                         else
1025                                 cmd++;
1026
1027                         for (; (src = *args++) != NULL; ) {
1028                                 if (*src == '\0')
1029                                         continue;
1030                                 len = (argbuflen - (dst - argbuf) - 1) / 4;
1031                                 strvisx(dst, src,
1032                                     MIN(strlen(src), len),
1033                                     VIS_NL | VIS_CSTYLE);
1034                                 while (*dst != '\0')
1035                                         dst++;
1036                                 if ((argbuflen - (dst - argbuf) - 1) / 4 > 0)
1037                                         *dst++ = ' '; /* add delimiting space */
1038                         }
1039                         if (dst != argbuf && dst[-1] == ' ')
1040                                 dst--;
1041                         *dst = '\0';
1042
1043                         if (strcmp(cmd, pp->ki_comm) != 0) {
1044                                 if (ps.thread && pp->ki_flag & P_HADTHREADS &&
1045                                     pp->ki_tdname[0])
1046                                         snprintf(cmdbuf, cmdlen,
1047                                             "%s (%s){%s%s}", argbuf,
1048                                             pp->ki_comm, pp->ki_tdname,
1049                                             pp->ki_moretdname);
1050                                 else
1051                                         snprintf(cmdbuf, cmdlen,
1052                                             "%s (%s)", argbuf, pp->ki_comm);
1053                         } else {
1054                                 if (ps.thread && pp->ki_flag & P_HADTHREADS &&
1055                                     pp->ki_tdname[0])
1056                                         snprintf(cmdbuf, cmdlen,
1057                                             "%s{%s%s}", argbuf, pp->ki_tdname,
1058                                             pp->ki_moretdname);
1059                                 else
1060                                         strlcpy(cmdbuf, argbuf, cmdlen);
1061                         }
1062                         free(argbuf);
1063                 }
1064         }
1065
1066         if (ps.jail == 0)
1067                 jid_buf[0] = '\0';
1068         else
1069                 snprintf(jid_buf, sizeof(jid_buf), "%*d",
1070                     jidlength - 1, pp->ki_jid);
1071
1072         if (ps.swap == 0)
1073                 swap_buf[0] = '\0';
1074         else
1075                 snprintf(swap_buf, sizeof(swap_buf), "%*s",
1076                     swaplength - 1,
1077                     format_k2(pagetok(ki_swap(pp)))); /* XXX */
1078
1079         if (displaymode == DISP_IO) {
1080                 oldp = get_old_proc(pp);
1081                 if (oldp != NULL) {
1082                         ru.ru_inblock = RU(pp)->ru_inblock -
1083                             RU(oldp)->ru_inblock;
1084                         ru.ru_oublock = RU(pp)->ru_oublock -
1085                             RU(oldp)->ru_oublock;
1086                         ru.ru_majflt = RU(pp)->ru_majflt - RU(oldp)->ru_majflt;
1087                         ru.ru_nvcsw = RU(pp)->ru_nvcsw - RU(oldp)->ru_nvcsw;
1088                         ru.ru_nivcsw = RU(pp)->ru_nivcsw - RU(oldp)->ru_nivcsw;
1089                         rup = &ru;
1090                 } else {
1091                         rup = RU(pp);
1092                 }
1093                 p_tot = rup->ru_inblock + rup->ru_oublock + rup->ru_majflt;
1094                 s_tot = total_inblock + total_oublock + total_majflt;
1095
1096                 snprintf(fmt, sizeof(fmt), io_Proc_format,
1097                     pp->ki_pid,
1098                     jidlength, jid_buf,
1099                     namelength, namelength, (*get_userid)(pp->ki_ruid),
1100                     rup->ru_nvcsw,
1101                     rup->ru_nivcsw,
1102                     rup->ru_inblock,
1103                     rup->ru_oublock,
1104                     rup->ru_majflt,
1105                     p_tot,
1106                     s_tot == 0 ? 0.0 : (p_tot * 100.0 / s_tot),
1107                     screen_width > cmdlengthdelta ?
1108                     screen_width - cmdlengthdelta : 0,
1109                     printable(cmdbuf));
1110
1111                 free(cmdbuf);
1112
1113                 return (fmt);
1114         }
1115
1116         /* format this entry */
1117         if (smpmode) {
1118                 if (state == SRUN && pp->ki_oncpu != NOCPU)
1119                         cpu = pp->ki_oncpu;
1120                 else
1121                         cpu = pp->ki_lastcpu;
1122         } else
1123                 cpu = 0;
1124         proc_fmt = smpmode ? smp_Proc_format : up_Proc_format;
1125         if (ps.thread != 0)
1126                 thr_buf[0] = '\0';
1127         else
1128                 snprintf(thr_buf, sizeof(thr_buf), "%*d ",
1129                     (int)(sizeof(thr_buf) - 2), pp->ki_numthreads);
1130
1131         snprintf(fmt, sizeof(fmt), proc_fmt,
1132             (ps.thread_id) ? pp->ki_tid : pp->ki_pid,
1133             jidlength, jid_buf,
1134             namelength, namelength, (*get_userid)(pp->ki_ruid),
1135             thr_buf,
1136             pp->ki_pri.pri_level - PZERO,
1137             format_nice(pp),
1138             format_k2(PROCSIZE(pp)),
1139             format_k2(pagetok(pp->ki_rssize)),
1140             swaplength, swaplength, swap_buf,
1141             status,
1142             cpu,
1143             format_time(cputime),
1144             ps.wcpu ? 100.0 * weighted_cpu(pct, pp) : 100.0 * pct,
1145             screen_width > cmdlengthdelta ? screen_width - cmdlengthdelta : 0,
1146             printable(cmdbuf));
1147
1148         free(cmdbuf);
1149
1150         /* return the result */
1151         return (fmt);
1152 }
1153
1154 static void
1155 getsysctl(const char *name, void *ptr, size_t len)
1156 {
1157         size_t nlen = len;
1158
1159         if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
1160                 fprintf(stderr, "top: sysctl(%s...) failed: %s\n", name,
1161                     strerror(errno));
1162                 quit(TOP_EX_SYS_ERROR);
1163         }
1164         if (nlen != len) {
1165                 fprintf(stderr, "top: sysctl(%s...) expected %lu, got %lu\n",
1166                     name, (unsigned long)len, (unsigned long)nlen);
1167                 quit(TOP_EX_SYS_ERROR);
1168         }
1169 }
1170
1171 static const char *
1172 format_nice(const struct kinfo_proc *pp)
1173 {
1174         const char *fifo, *kproc;
1175         int rtpri;
1176         static char nicebuf[4 + 1];
1177
1178         fifo = PRI_NEED_RR(pp->ki_pri.pri_class) ? "" : "F";
1179         kproc = (pp->ki_flag & P_KPROC) ? "k" : "";
1180         switch (PRI_BASE(pp->ki_pri.pri_class)) {
1181         case PRI_ITHD:
1182                 return ("-");
1183         case PRI_REALTIME:
1184                 /*
1185                  * XXX: the kernel doesn't tell us the original rtprio and
1186                  * doesn't really know what it was, so to recover it we
1187                  * must be more chummy with the implementation than the
1188                  * implementation is with itself.  pri_user gives a
1189                  * constant "base" priority, but is only initialized
1190                  * properly for user threads.  pri_native gives what the
1191                  * kernel calls the "base" priority, but it isn't constant
1192                  * since it is changed by priority propagation.  pri_native
1193                  * also isn't properly initialized for all threads, but it
1194                  * is properly initialized for kernel realtime and idletime
1195                  * threads.  Thus we use pri_user for the base priority of
1196                  * user threads (it is always correct) and pri_native for
1197                  * the base priority of kernel realtime and idletime threads
1198                  * (there is nothing better, and it is usually correct).
1199                  *
1200                  * The field width and thus the buffer are too small for
1201                  * values like "kr31F", but such values shouldn't occur,
1202                  * and if they do then the tailing "F" is not displayed.
1203                  */
1204                 rtpri = ((pp->ki_flag & P_KPROC) ? pp->ki_pri.pri_native :
1205                     pp->ki_pri.pri_user) - PRI_MIN_REALTIME;
1206                 snprintf(nicebuf, sizeof(nicebuf), "%sr%d%s",
1207                     kproc, rtpri, fifo);
1208                 break;
1209         case PRI_TIMESHARE:
1210                 if (pp->ki_flag & P_KPROC)
1211                         return ("-");
1212                 snprintf(nicebuf, sizeof(nicebuf), "%d", pp->ki_nice - NZERO);
1213                 break;
1214         case PRI_IDLE:
1215                 /* XXX: as above. */
1216                 rtpri = ((pp->ki_flag & P_KPROC) ? pp->ki_pri.pri_native :
1217                     pp->ki_pri.pri_user) - PRI_MIN_IDLE;
1218                 snprintf(nicebuf, sizeof(nicebuf), "%si%d%s",
1219                     kproc, rtpri, fifo);
1220                 break;
1221         default:
1222                 return ("?");
1223         }
1224         return (nicebuf);
1225 }
1226
1227 /* comparison routines for qsort */
1228
1229 static int
1230 compare_pid(const void *p1, const void *p2)
1231 {
1232         const struct kinfo_proc * const *pp1 = p1;
1233         const struct kinfo_proc * const *pp2 = p2;
1234
1235         assert((*pp2)->ki_pid >= 0 && (*pp1)->ki_pid >= 0);
1236
1237         return ((*pp1)->ki_pid - (*pp2)->ki_pid);
1238 }
1239
1240 static int
1241 compare_tid(const void *p1, const void *p2)
1242 {
1243         const struct kinfo_proc * const *pp1 = p1;
1244         const struct kinfo_proc * const *pp2 = p2;
1245
1246         assert((*pp2)->ki_tid >= 0 && (*pp1)->ki_tid >= 0);
1247
1248         return ((*pp1)->ki_tid - (*pp2)->ki_tid);
1249 }
1250
1251 /*
1252  *  proc_compare - comparison function for "qsort"
1253  *      Compares the resource consumption of two processes using five
1254  *      distinct keys.  The keys (in descending order of importance) are:
1255  *      percent cpu, cpu ticks, state, resident set size, total virtual
1256  *      memory usage.  The process states are ordered as follows (from least
1257  *      to most important):  WAIT, zombie, sleep, stop, start, run.  The
1258  *      array declaration below maps a process state index into a number
1259  *      that reflects this ordering.
1260  */
1261
1262 static int sorted_state[] = {
1263         0,      /* not used             */
1264         3,      /* sleep                */
1265         1,      /* ABANDONED (WAIT)     */
1266         6,      /* run                  */
1267         5,      /* start                */
1268         2,      /* zombie               */
1269         4       /* stop                 */
1270 };
1271
1272
1273 #define ORDERKEY_PCTCPU(a, b) do { \
1274         double diff; \
1275         if (ps.wcpu) \
1276                 diff = weighted_cpu(PCTCPU((b)), (b)) - \
1277                     weighted_cpu(PCTCPU((a)), (a)); \
1278         else \
1279                 diff = PCTCPU((b)) - PCTCPU((a)); \
1280         if (diff != 0) \
1281                 return (diff > 0 ? 1 : -1); \
1282 } while (0)
1283
1284 #define ORDERKEY_CPTICKS(a, b) do { \
1285         int64_t diff = (int64_t)(b)->ki_runtime - (int64_t)(a)->ki_runtime; \
1286         if (diff != 0) \
1287                 return (diff > 0 ? 1 : -1); \
1288 } while (0)
1289
1290 #define ORDERKEY_STATE(a, b) do { \
1291         int diff = sorted_state[(unsigned char)(b)->ki_stat] - sorted_state[(unsigned char)(a)->ki_stat]; \
1292         if (diff != 0) \
1293                 return (diff > 0 ? 1 : -1); \
1294 } while (0)
1295
1296 #define ORDERKEY_PRIO(a, b) do { \
1297         int diff = (int)(b)->ki_pri.pri_level - (int)(a)->ki_pri.pri_level; \
1298         if (diff != 0) \
1299                 return (diff > 0 ? 1 : -1); \
1300 } while (0)
1301
1302 #define ORDERKEY_THREADS(a, b) do { \
1303         int diff = (int)(b)->ki_numthreads - (int)(a)->ki_numthreads; \
1304         if (diff != 0) \
1305                 return (diff > 0 ? 1 : -1); \
1306 } while (0)
1307
1308 #define ORDERKEY_RSSIZE(a, b) do { \
1309         long diff = (long)(b)->ki_rssize - (long)(a)->ki_rssize; \
1310         if (diff != 0) \
1311                 return (diff > 0 ? 1 : -1); \
1312 } while (0)
1313
1314 #define ORDERKEY_MEM(a, b) do { \
1315         long diff = (long)PROCSIZE((b)) - (long)PROCSIZE((a)); \
1316         if (diff != 0) \
1317                 return (diff > 0 ? 1 : -1); \
1318 } while (0)
1319
1320 #define ORDERKEY_JID(a, b) do { \
1321         int diff = (int)(b)->ki_jid - (int)(a)->ki_jid; \
1322         if (diff != 0) \
1323                 return (diff > 0 ? 1 : -1); \
1324 } while (0)
1325
1326 #define ORDERKEY_SWAP(a, b) do { \
1327         int diff = (int)ki_swap(b) - (int)ki_swap(a); \
1328         if (diff != 0) \
1329                 return (diff > 0 ? 1 : -1); \
1330 } while (0)
1331
1332 /* compare_cpu - the comparison function for sorting by cpu percentage */
1333
1334 static int
1335 compare_cpu(const void *arg1, const void *arg2)
1336 {
1337         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1338         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1339
1340         ORDERKEY_PCTCPU(p1, p2);
1341         ORDERKEY_CPTICKS(p1, p2);
1342         ORDERKEY_STATE(p1, p2);
1343         ORDERKEY_PRIO(p1, p2);
1344         ORDERKEY_RSSIZE(p1, p2);
1345         ORDERKEY_MEM(p1, p2);
1346
1347         return (0);
1348 }
1349
1350 /* compare_size - the comparison function for sorting by total memory usage */
1351
1352 static int
1353 compare_size(const void *arg1, const void *arg2)
1354 {
1355         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1356         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1357
1358         ORDERKEY_MEM(p1, p2);
1359         ORDERKEY_RSSIZE(p1, p2);
1360         ORDERKEY_PCTCPU(p1, p2);
1361         ORDERKEY_CPTICKS(p1, p2);
1362         ORDERKEY_STATE(p1, p2);
1363         ORDERKEY_PRIO(p1, p2);
1364
1365         return (0);
1366 }
1367
1368 /* compare_res - the comparison function for sorting by resident set size */
1369
1370 static int
1371 compare_res(const void *arg1, const void *arg2)
1372 {
1373         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1374         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1375
1376         ORDERKEY_RSSIZE(p1, p2);
1377         ORDERKEY_MEM(p1, p2);
1378         ORDERKEY_PCTCPU(p1, p2);
1379         ORDERKEY_CPTICKS(p1, p2);
1380         ORDERKEY_STATE(p1, p2);
1381         ORDERKEY_PRIO(p1, p2);
1382
1383         return (0);
1384 }
1385
1386 /* compare_time - the comparison function for sorting by total cpu time */
1387
1388 static int
1389 compare_time(const void *arg1, const void *arg2)
1390 {
1391         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const  *)arg1;
1392         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *) arg2;
1393
1394         ORDERKEY_CPTICKS(p1, p2);
1395         ORDERKEY_PCTCPU(p1, p2);
1396         ORDERKEY_STATE(p1, p2);
1397         ORDERKEY_PRIO(p1, p2);
1398         ORDERKEY_RSSIZE(p1, p2);
1399         ORDERKEY_MEM(p1, p2);
1400
1401         return (0);
1402 }
1403
1404 /* compare_prio - the comparison function for sorting by priority */
1405
1406 static int
1407 compare_prio(const void *arg1, const void *arg2)
1408 {
1409         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1410         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1411
1412         ORDERKEY_PRIO(p1, p2);
1413         ORDERKEY_CPTICKS(p1, p2);
1414         ORDERKEY_PCTCPU(p1, p2);
1415         ORDERKEY_STATE(p1, p2);
1416         ORDERKEY_RSSIZE(p1, p2);
1417         ORDERKEY_MEM(p1, p2);
1418
1419         return (0);
1420 }
1421
1422 /* compare_threads - the comparison function for sorting by threads */
1423 static int
1424 compare_threads(const void *arg1, const void *arg2)
1425 {
1426         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1427         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1428
1429         ORDERKEY_THREADS(p1, p2);
1430         ORDERKEY_PCTCPU(p1, p2);
1431         ORDERKEY_CPTICKS(p1, p2);
1432         ORDERKEY_STATE(p1, p2);
1433         ORDERKEY_PRIO(p1, p2);
1434         ORDERKEY_RSSIZE(p1, p2);
1435         ORDERKEY_MEM(p1, p2);
1436
1437         return (0);
1438 }
1439
1440 /* compare_jid - the comparison function for sorting by jid */
1441 static int
1442 compare_jid(const void *arg1, const void *arg2)
1443 {
1444         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1445         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1446
1447         ORDERKEY_JID(p1, p2);
1448         ORDERKEY_PCTCPU(p1, p2);
1449         ORDERKEY_CPTICKS(p1, p2);
1450         ORDERKEY_STATE(p1, p2);
1451         ORDERKEY_PRIO(p1, p2);
1452         ORDERKEY_RSSIZE(p1, p2);
1453         ORDERKEY_MEM(p1, p2);
1454
1455         return (0);
1456 }
1457
1458 /* compare_swap - the comparison function for sorting by swap */
1459 static int
1460 compare_swap(const void *arg1, const void *arg2)
1461 {
1462         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1463         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1464
1465         ORDERKEY_SWAP(p1, p2);
1466         ORDERKEY_PCTCPU(p1, p2);
1467         ORDERKEY_CPTICKS(p1, p2);
1468         ORDERKEY_STATE(p1, p2);
1469         ORDERKEY_PRIO(p1, p2);
1470         ORDERKEY_RSSIZE(p1, p2);
1471         ORDERKEY_MEM(p1, p2);
1472
1473         return (0);
1474 }
1475
1476 /* assorted comparison functions for sorting by i/o */
1477
1478 static int
1479 compare_iototal(const void *arg1, const void *arg2)
1480 {
1481         const struct kinfo_proc * const p1 = *(const struct kinfo_proc * const *)arg1;
1482         const struct kinfo_proc * const p2 = *(const struct kinfo_proc * const *)arg2;
1483
1484         return (get_io_total(p2) - get_io_total(p1));
1485 }
1486
1487 static int
1488 compare_ioread(const void *arg1, const void *arg2)
1489 {
1490         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1491         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1492         long dummy, inp1, inp2;
1493
1494         (void) get_io_stats(p1, &inp1, &dummy, &dummy, &dummy, &dummy);
1495         (void) get_io_stats(p2, &inp2, &dummy, &dummy, &dummy, &dummy);
1496
1497         return (inp2 - inp1);
1498 }
1499
1500 static int
1501 compare_iowrite(const void *arg1, const void *arg2)
1502 {
1503         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1504         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1505         long dummy, oup1, oup2;
1506
1507         (void) get_io_stats(p1, &dummy, &oup1, &dummy, &dummy, &dummy);
1508         (void) get_io_stats(p2, &dummy, &oup2, &dummy, &dummy, &dummy);
1509
1510         return (oup2 - oup1);
1511 }
1512
1513 static int
1514 compare_iofault(const void *arg1, const void *arg2)
1515 {
1516         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1517         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1518         long dummy, flp1, flp2;
1519
1520         (void) get_io_stats(p1, &dummy, &dummy, &flp1, &dummy, &dummy);
1521         (void) get_io_stats(p2, &dummy, &dummy, &flp2, &dummy, &dummy);
1522
1523         return (flp2 - flp1);
1524 }
1525
1526 static int
1527 compare_vcsw(const void *arg1, const void *arg2)
1528 {
1529         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1530         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1531         long dummy, flp1, flp2;
1532
1533         (void) get_io_stats(p1, &dummy, &dummy, &dummy, &flp1, &dummy);
1534         (void) get_io_stats(p2, &dummy, &dummy, &dummy, &flp2, &dummy);
1535
1536         return (flp2 - flp1);
1537 }
1538
1539 static int
1540 compare_ivcsw(const void *arg1, const void *arg2)
1541 {
1542         const struct kinfo_proc *p1 = *(const struct kinfo_proc * const *)arg1;
1543         const struct kinfo_proc *p2 = *(const struct kinfo_proc * const *)arg2;
1544         long dummy, flp1, flp2;
1545
1546         (void) get_io_stats(p1, &dummy, &dummy, &dummy, &dummy, &flp1);
1547         (void) get_io_stats(p2, &dummy, &dummy, &dummy, &dummy, &flp2);
1548
1549         return (flp2 - flp1);
1550 }
1551
1552 int (*compares[])(const void *arg1, const void *arg2) = {
1553         compare_cpu,
1554         compare_size,
1555         compare_res,
1556         compare_time,
1557         compare_prio,
1558         compare_threads,
1559         compare_iototal,
1560         compare_ioread,
1561         compare_iowrite,
1562         compare_iofault,
1563         compare_vcsw,
1564         compare_ivcsw,
1565         compare_jid,
1566         compare_swap,
1567         NULL
1568 };
1569
1570
1571 /*
1572  * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
1573  *              the process does not exist.
1574  */
1575
1576 int
1577 proc_owner(int pid)
1578 {
1579         int cnt;
1580         struct kinfo_proc **prefp;
1581         struct kinfo_proc *pp;
1582
1583         prefp = pref;
1584         cnt = pref_len;
1585         while (--cnt >= 0) {
1586                 pp = *prefp++;
1587                 if (pp->ki_pid == (pid_t)pid)
1588                         return ((int)pp->ki_ruid);
1589         }
1590         return (-1);
1591 }
1592
1593 static int
1594 swapmode(int *retavail, int *retfree)
1595 {
1596         int n;
1597         struct kvm_swap swapary[1];
1598         static int pagesize = 0;
1599         static unsigned long swap_maxpages = 0;
1600
1601         *retavail = 0;
1602         *retfree = 0;
1603
1604 #define CONVERT(v)      ((quad_t)(v) * pagesize / 1024)
1605
1606         n = kvm_getswapinfo(kd, swapary, 1, 0);
1607         if (n < 0 || swapary[0].ksw_total == 0)
1608                 return (0);
1609
1610         if (pagesize == 0)
1611                 pagesize = getpagesize();
1612         if (swap_maxpages == 0)
1613                 GETSYSCTL("vm.swap_maxpages", swap_maxpages);
1614
1615         /* ksw_total contains the total size of swap all devices which may
1616            exceed the maximum swap size allocatable in the system */
1617         if ( swapary[0].ksw_total > swap_maxpages )
1618                 swapary[0].ksw_total = swap_maxpages;
1619
1620         *retavail = CONVERT(swapary[0].ksw_total);
1621         *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
1622
1623         n = (int)(swapary[0].ksw_used * 100.0 / swapary[0].ksw_total);
1624         return (n);
1625 }