xref: /netbsd-src/external/bsd/top/dist/machine/m_netbsd.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /*	$NetBSD: m_netbsd.c,v 1.5 2008/08/02 23:20:16 cube Exp $	*/
2 
3 /*
4  * top - a top users display for Unix
5  *
6  * SYNOPSIS:  For a NetBSD-1.5 (or later) system
7  *
8  * DESCRIPTION:
9  * Originally written for BSD4.4 system by Christos Zoulas.
10  * Based on the FreeBSD 2.0 version by Steven Wallace and Wolfram Schneider.
11  * NetBSD-1.0 port by Arne Helme. Process ordering by Luke Mewburn.
12  * NetBSD-1.3 port by Luke Mewburn, based on code by Matthew Green.
13  * NetBSD-1.4/UVM port by matthew green.
14  * NetBSD-1.5 port by Simon Burge.
15  * NetBSD-1.6/UBC port by Tomas Svensson.
16  * -
17  * This is the machine-dependent module for NetBSD-1.5 and later
18  * works for:
19  *	NetBSD-1.6ZC
20  * and should work for:
21  *	NetBSD-2.0	(when released)
22  * -
23  * top does not need to be installed setuid or setgid with this module.
24  *
25  * LIBS: -lkvm
26  *
27  * CFLAGS: -DHAVE_GETOPT -DORDER -DHAVE_STRERROR
28  *
29  * AUTHORS:	Christos Zoulas <christos@ee.cornell.edu>
30  *		Steven Wallace <swallace@freebsd.org>
31  *		Wolfram Schneider <wosch@cs.tu-berlin.de>
32  *		Arne Helme <arne@acm.org>
33  *		Luke Mewburn <lukem@NetBSD.org>
34  *		matthew green <mrg@eterna.com.au>
35  *		Simon Burge <simonb@NetBSD.org>
36  *		Tomas Svensson <ts@unix1.net>
37  *		Andrew Doran <ad@NetBSD.org>
38  *
39  *
40  * $Id: m_netbsd.c,v 1.5 2008/08/02 23:20:16 cube Exp $
41  */
42 #include <sys/cdefs.h>
43 
44 #ifndef lint
45 __RCSID("$NetBSD: m_netbsd.c,v 1.5 2008/08/02 23:20:16 cube Exp $");
46 #endif
47 
48 #include <sys/param.h>
49 #include <sys/sysctl.h>
50 #include <sys/sched.h>
51 #include <sys/swap.h>
52 
53 #include <uvm/uvm_extern.h>
54 
55 #include <err.h>
56 #include <errno.h>
57 #include <kvm.h>
58 #include <math.h>
59 #include <nlist.h>
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <unistd.h>
64 
65 #include "os.h"
66 #include "top.h"
67 #include "machine.h"
68 #include "utils.h"
69 #include "display.h"
70 #include "loadavg.h"
71 #include "username.h"
72 
73 static void percentages64 __P((int, int *, u_int64_t *, u_int64_t *,
74     u_int64_t *));
75 static int get_cpunum __P((u_int64_t));
76 
77 
78 /* get_process_info passes back a handle.  This is what it looks like: */
79 
80 struct handle {
81 	struct kinfo_proc2 **next_proc;	/* points to next valid proc pointer */
82 	int remaining;		/* number of pointers remaining */
83 };
84 
85 /* define what weighted CPU is. */
86 #define weighted_cpu(pfx, pct, pp) ((pp)->pfx ## swtime == 0 ? 0.0 : \
87 			 ((pct) / (1.0 - exp((pp)->pfx ## swtime * logcpu))))
88 
89 /* what we consider to be process size: */
90 #define PROCSIZE(pp) \
91 	((pp)->p_vm_tsize + (pp)->p_vm_dsize + (pp)->p_vm_ssize)
92 
93 
94 /*
95  * These definitions control the format of the per-process area
96  */
97 
98 static char Proc_header[] =
99   "  PID X        PRI NICE   SIZE   RES STATE      TIME   WCPU    CPU COMMAND";
100 /* 0123456   -- field to fill in starts at header+6 */
101 #define PROC_UNAME_START 6
102 #define Proc_format \
103 	"%5d %-8.8s %3d %4d%7s %5s %-8.8s%7s %5.2f%% %5.2f%% %.12s"
104 
105 static char Thread_header[] =
106   "  PID   LID X        PRI STATE      TIME   WCPU    CPU COMMAND      NAME";
107 /* 0123456   -- field to fill in starts at header+6 */
108 #define THREAD_UNAME_START 12
109 #define Thread_format \
110         "%5d %5d %-8.8s %3d %-8.8s%7s %5.2f%% %5.2f%% %-12.12s %.12s"
111 
112 /*
113  * Process state names for the "STATE" column of the display.
114  */
115 
116 const char *state_abbrev[] = {
117 	"", "IDLE", "RUN", "SLEEP", "STOP", "ZOMB", "DEAD", "CPU"
118 };
119 
120 static kvm_t *kd;
121 
122 static char *(*userprint)(int);
123 
124 /* these are retrieved from the kernel in _init */
125 
126 static double logcpu;
127 static int hz;
128 static int ccpu;
129 
130 /* these are for calculating CPU state percentages */
131 
132 static int ncpu = 0;
133 static u_int64_t *cp_time;
134 static u_int64_t *cp_id;
135 static u_int64_t *cp_old;
136 static u_int64_t *cp_diff;
137 
138 /* these are for detailing the process states */
139 
140 int process_states[8];
141 char *procstatenames[] = {
142 	"", " idle, ", " runnable, ", " sleeping, ", " stopped, ",
143 	" zombie, ", " dead, ", " on CPU, ",
144 	NULL
145 };
146 
147 /* these are for detailing the CPU states */
148 
149 int *cpu_states;
150 char *cpustatenames[] = {
151 	"user", "nice", "system", "interrupt", "idle", NULL
152 };
153 
154 /* these are for detailing the memory statistics */
155 
156 long memory_stats[7];
157 char *memorynames[] = {
158 	"K Act, ", "K Inact, ", "K Wired, ", "K Exec, ", "K File, ",
159 	"K Free, ",
160 	NULL
161 };
162 
163 long swap_stats[4];
164 char *swapnames[] = {
165 	"K Total, ", "K Used, ", "K Free, ",
166 	NULL
167 };
168 
169 
170 /* these are names given to allowed sorting orders -- first is default */
171 char *ordernames[] = {
172 	"cpu",
173 	"pri",
174 	"res",
175 	"size",
176 	"state",
177 	"time",
178 	"pid",
179 	"command",
180 	"username",
181 	NULL
182 };
183 
184 /* forward definitions for comparison functions */
185 static int compare_cpu __P((struct proc **, struct proc **));
186 static int compare_prio __P((struct proc **, struct proc **));
187 static int compare_res __P((struct proc **, struct proc **));
188 static int compare_size __P((struct proc **, struct proc **));
189 static int compare_state __P((struct proc **, struct proc **));
190 static int compare_time __P((struct proc **, struct proc **));
191 static int compare_pid __P((struct proc **, struct proc **));
192 static int compare_command __P((struct proc **, struct proc **));
193 static int compare_username __P((struct proc **, struct proc **));
194 
195 int (*proc_compares[]) __P((struct proc **, struct proc **)) = {
196 	compare_cpu,
197 	compare_prio,
198 	compare_res,
199 	compare_size,
200 	compare_state,
201 	compare_time,
202 	compare_pid,
203 	compare_command,
204 	compare_username,
205 	NULL
206 };
207 
208 static char *format_next_lwp(caddr_t, char *(*)(int));
209 static char *format_next_proc(caddr_t, char *(*)(int));
210 
211 static caddr_t get_proc_info(struct system_info *, struct process_select *,
212 			     int (*)(struct proc **, struct proc **));
213 static caddr_t get_lwp_info(struct system_info *, struct process_select *,
214 			    int (*)(struct proc **, struct proc **));
215 
216 /* these are for keeping track of the proc array */
217 
218 static int nproc;
219 static int onproc = -1;
220 static int nlwp;
221 static int onlwp = -1;
222 static int pref_len;
223 static int lref_len;
224 static struct kinfo_proc2 *pbase;
225 static struct kinfo_lwp *lbase;
226 static struct kinfo_proc2 **pref;
227 static struct kinfo_lwp **lref;
228 static int maxswap;
229 static void *swapp;
230 static int procgen;
231 static int thread_nproc;
232 static int thread_onproc = -1;
233 static struct kinfo_proc2 *thread_pbase;
234 
235 /* these are for getting the memory statistics */
236 
237 static int pageshift;		/* log base 2 of the pagesize */
238 
239 int threadmode;
240 
241 /* define pagetok in terms of pageshift */
242 
243 #define pagetok(size) ((size) << pageshift)
244 
245 static int
246 get_cpunum(id)
247 	u_int64_t id;
248 {
249 	int i = 0;
250 	for (i = 0; i < ncpu; i++)
251 		if (id == cp_id[i])
252 			return i;
253 	return -1;
254 }
255 
256 int
257 machine_init(statics)
258 	struct statics *statics;
259 {
260 	int pagesize;
261 	int mib[2];
262 	size_t size;
263 	struct clockinfo clockinfo;
264 	struct timeval boottime;
265 
266 	if ((kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open")) == NULL)
267 		return -1;
268 
269 	mib[0] = CTL_HW;
270 	mib[1] = HW_NCPU;
271 	size = sizeof(ncpu);
272 	if (sysctl(mib, 2, &ncpu, &size, NULL, 0) == -1) {
273 		fprintf(stderr, "top: sysctl hw.ncpu failed: %s\n",
274 		    strerror(errno));
275 		return(-1);
276 	}
277 	statics->ncpu = ncpu;
278 	cp_time = malloc(sizeof(cp_time[0]) * CPUSTATES * ncpu);
279 	mib[0] = CTL_KERN;
280 	mib[1] = KERN_CP_TIME;
281 	size = sizeof(cp_time[0]) * CPUSTATES * ncpu;
282 	if (sysctl(mib, 2, cp_time, &size, NULL, 0) < 0) {
283 		fprintf(stderr, "top: sysctl kern.cp_time failed: %s\n",
284 		    strerror(errno));
285 		return(-1);
286 	}
287 
288 	/* Handle old call that returned only aggregate */
289 	if (size == sizeof(cp_time[0]) * CPUSTATES)
290 		ncpu = 1;
291 
292 	cp_id = malloc(sizeof(cp_id[0]) * ncpu);
293 	mib[0] = CTL_KERN;
294 	mib[1] = KERN_CP_ID;
295 	size = sizeof(cp_id[0]) * ncpu;
296 	if (sysctl(mib, 2, cp_id, &size, NULL, 0) < 0) {
297 		fprintf(stderr, "top: sysctl kern.cp_id failed: %s\n",
298 		    strerror(errno));
299 		return(-1);
300 	}
301 	cpu_states = malloc(sizeof(cpu_states[0]) * CPUSTATES * ncpu);
302 	cp_old = malloc(sizeof(cp_old[0]) * CPUSTATES * ncpu);
303 	cp_diff = malloc(sizeof(cp_diff[0]) * CPUSTATES * ncpu);
304 	if (cpu_states == NULL || cp_time == NULL || cp_old == NULL ||
305 	    cp_diff == NULL) {
306 		fprintf(stderr, "top: machine_init: %s\n",
307 		    strerror(errno));
308 		return(-1);
309 	}
310 
311 	mib[0] = CTL_KERN;
312 	mib[1] = KERN_CCPU;
313 	size = sizeof(ccpu);
314 	if (sysctl(mib, 2, &ccpu, &size, NULL, 0) == -1) {
315 		fprintf(stderr, "top: sysctl kern.ccpu failed: %s\n",
316 		    strerror(errno));
317 		return(-1);
318 	}
319 
320 	mib[0] = CTL_KERN;
321 	mib[1] = KERN_CLOCKRATE;
322 	size = sizeof(clockinfo);
323 	if (sysctl(mib, 2, &clockinfo, &size, NULL, 0) == -1) {
324 		fprintf(stderr, "top: sysctl kern.clockrate failed: %s\n",
325 		    strerror(errno));
326 		return(-1);
327 	}
328 	hz = clockinfo.stathz;
329 
330 	/* this is used in calculating WCPU -- calculate it ahead of time */
331 	logcpu = log(loaddouble(ccpu));
332 
333 	pbase = NULL;
334 	lbase = NULL;
335 	pref = NULL;
336 	nproc = 0;
337 	onproc = -1;
338 	nlwp = 0;
339 	onlwp = -1;
340 	/* get the page size with "getpagesize" and calculate pageshift from it */
341 	pagesize = getpagesize();
342 	pageshift = 0;
343 	while (pagesize > 1) {
344 		pageshift++;
345 		pagesize >>= 1;
346 	}
347 
348 	/* we only need the amount of log(2)1024 for our conversion */
349 	pageshift -= LOG1024;
350 
351 	/* fill in the statics information */
352 #ifdef notyet
353 	statics->ncpu = ncpu;
354 #endif
355 	statics->procstate_names = procstatenames;
356 	statics->cpustate_names = cpustatenames;
357 	statics->memory_names = memorynames;
358 	statics->swap_names = swapnames;
359 	statics->order_names = ordernames;
360 	statics->flags.threads = 1;
361 
362 	mib[0] = CTL_KERN;
363 	mib[1] = KERN_BOOTTIME;
364 	size = sizeof(boottime);
365 	if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
366     	    boottime.tv_sec != 0)
367 		statics->boottime = boottime.tv_sec;
368 	else
369 		statics->boottime = 0;
370 	/* all done! */
371 	return(0);
372 }
373 
374 char *
375 format_process_header(struct process_select *sel, caddr_t handle, int count)
376 
377 {
378 	char *header;
379 	char *ptr;
380 	const char *uname_field = sel->usernames ? "USERNAME" : "   UID  ";
381 
382 	if (sel->threads) {
383 		header = Thread_header;
384 		ptr = header + THREAD_UNAME_START;
385 	} else {
386 		header = Proc_header;
387 		ptr = header + PROC_UNAME_START;
388 	}
389 
390 	while (*uname_field != '\0') {
391 		*ptr++ = *uname_field++;
392 	}
393 
394 	return(header);
395 }
396 
397 char *
398 format_header(char *uname_field)
399 {
400 	char *header = Proc_header;
401 	char *ptr = header + PROC_UNAME_START;
402 
403 	while (*uname_field != '\0') {
404 		*ptr++ = *uname_field++;
405 	}
406 
407 	return(header);
408 }
409 
410 void
411 get_system_info(si)
412 	struct system_info *si;
413 {
414 	size_t ssize;
415 	int mib[2];
416 	struct uvmexp_sysctl uvmexp;
417 	struct swapent *sep;
418 	u_int64_t totalsize, totalinuse;
419 	int size, inuse, ncounted, i;
420 	int rnswap, nswap;
421 
422 	mib[0] = CTL_KERN;
423 	mib[1] = KERN_CP_TIME;
424 	ssize = sizeof(cp_time[0]) * CPUSTATES * ncpu;
425 	if (sysctl(mib, 2, cp_time, &ssize, NULL, 0) < 0) {
426 		fprintf(stderr, "top: sysctl kern.cp_time failed: %s\n",
427 		    strerror(errno));
428 		quit(23);
429 	}
430 
431 	if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) {
432 		int i;
433 
434 		warn("can't getloadavg");
435 		for (i = 0; i < NUM_AVERAGES; i++)
436 			si->load_avg[i] = 0.0;
437 	}
438 
439 	/* convert cp_time counts to percentages */
440 	for (i = 0; i < ncpu; i++) {
441 	    int j = i * CPUSTATES;
442 	    percentages64(CPUSTATES, cpu_states + j, cp_time + j, cp_old + j,
443 		cp_diff + j);
444 	}
445 
446 	mib[0] = CTL_VM;
447 	mib[1] = VM_UVMEXP2;
448 	ssize = sizeof(uvmexp);
449 	if (sysctl(mib, 2, &uvmexp, &ssize, NULL, 0) < 0) {
450 		fprintf(stderr, "top: sysctl vm.uvmexp2 failed: %s\n",
451 		    strerror(errno));
452 		quit(23);
453 	}
454 
455 	/* convert memory stats to Kbytes */
456 	memory_stats[0] = pagetok(uvmexp.active);
457 	memory_stats[1] = pagetok(uvmexp.inactive);
458 	memory_stats[2] = pagetok(uvmexp.wired);
459 	memory_stats[3] = pagetok(uvmexp.execpages);
460 	memory_stats[4] = pagetok(uvmexp.filepages);
461 	memory_stats[5] = pagetok(uvmexp.free);
462 
463 	swap_stats[0] = swap_stats[1] = swap_stats[2] = 0;
464 
465 	do {
466 		nswap = swapctl(SWAP_NSWAP, 0, 0);
467 		if (nswap < 1)
468 			break;
469 		if (nswap > maxswap) {
470 			if (swapp)
471 				free(swapp);
472 			swapp = sep = malloc(nswap * sizeof(*sep));
473 			if (sep == NULL)
474 				break;
475 			maxswap = nswap;
476 		} else
477 			sep = swapp;
478 		rnswap = swapctl(SWAP_STATS, (void *)sep, nswap);
479 		if (nswap != rnswap)
480 			break;
481 
482 		totalsize = totalinuse = ncounted = 0;
483 		for (; rnswap-- > 0; sep++) {
484 			ncounted++;
485 			size = sep->se_nblks;
486 			inuse = sep->se_inuse;
487 			totalsize += size;
488 			totalinuse += inuse;
489 		}
490 		swap_stats[0] = dbtob(totalsize) / 1024;
491 		swap_stats[1] = dbtob(totalinuse) / 1024;
492 		swap_stats[2] = dbtob(totalsize) / 1024 - swap_stats[1];
493 	} while (0);
494 
495 	memory_stats[6] = -1;
496 	swap_stats[3] = -1;
497 
498 	/* set arrays and strings */
499 	si->cpustates = cpu_states;
500 	si->memory = memory_stats;
501 	si->swap = swap_stats;
502 	si->last_pid = -1;
503 
504 }
505 
506 static struct kinfo_proc2 *
507 proc_from_thread(struct kinfo_lwp *pl)
508 {
509 	struct kinfo_proc2 *pp = thread_pbase;
510 	int i;
511 
512 	for (i = 0; i < thread_nproc; i++, pp++)
513 		if (pp->p_pid == pl->l_pid)
514 			return pp;
515 	return NULL;
516 }
517 
518 static int
519 uid_from_thread(struct kinfo_lwp *pl)
520 {
521 	struct kinfo_proc2 *pp;
522 
523 	if ((pp = proc_from_thread(pl)) == NULL)
524 		return -1;
525 	return pp->p_ruid;
526 }
527 
528 caddr_t
529 get_process_info(struct system_info *si, struct process_select *sel, int c)
530 {
531 	userprint = sel->usernames ? username : itoa7;
532 
533 	if ((threadmode = sel->threads) != 0)
534 		return get_lwp_info(si, sel, proc_compares[c]);
535 	else
536 		return get_proc_info(si, sel, proc_compares[c]);
537 }
538 
539 static caddr_t
540 get_proc_info(struct system_info *si, struct process_select *sel,
541 	      int (*compare)(struct proc **, struct proc **))
542 {
543 	int i;
544 	int total_procs;
545 	int active_procs;
546 	struct kinfo_proc2 **prefp, **n;
547 	struct kinfo_proc2 *pp;
548 	int op, arg;
549 
550 	/* these are copied out of sel for speed */
551 	int show_idle;
552 	int show_system;
553 	int show_uid;
554 	int show_command;
555 
556 	static struct handle handle;
557 
558 	procgen++;
559 
560 	if (sel->pid == -1) {
561 		op = KERN_PROC_ALL;
562 		arg = 0;
563 	} else {
564 		op = KERN_PROC_PID;
565 		arg = sel->pid;
566 	}
567 
568 	pbase = kvm_getproc2(kd, op, arg, sizeof(struct kinfo_proc2), &nproc);
569 	if (pbase == NULL) {
570 		if (sel->pid != -1) {
571 			nproc = 0;
572 		} else {
573 			(void) fprintf(stderr, "top: Out of memory.\n");
574 			quit(23);
575 		}
576 	}
577 	if (nproc > onproc) {
578 		n = (struct kinfo_proc2 **) realloc(pref,
579 		    sizeof(struct kinfo_proc2 *) * nproc);
580 		if (n == NULL) {
581 			(void) fprintf(stderr, "top: Out of memory.\n");
582 			quit(23);
583 		}
584 		pref = n;
585 		onproc = nproc;
586 	}
587 	/* get a pointer to the states summary array */
588 	si->procstates = process_states;
589 
590 	/* set up flags which define what we are going to select */
591 	show_idle = sel->idle;
592 	show_system = sel->system;
593 	show_uid = sel->uid != -1;
594 	show_command = sel->command != NULL;
595 
596 	/* count up process states and get pointers to interesting procs */
597 	total_procs = 0;
598 	active_procs = 0;
599 	memset((char *)process_states, 0, sizeof(process_states));
600 	prefp = pref;
601 	for (pp = pbase, i = 0; i < nproc; pp++, i++) {
602 
603 		/*
604 		 * Place pointers to each valid proc structure in pref[].
605 		 * Process slots that are actually in use have a non-zero
606 		 * status field.  Processes with P_SYSTEM set are system
607 		 * processes---these get ignored unless show_sysprocs is set.
608 		 */
609 		if (pp->p_stat != 0 && (show_system || ((pp->p_flag & P_SYSTEM) == 0))) {
610 			total_procs++;
611 			process_states[(unsigned char) pp->p_stat]++;
612 			if (pp->p_stat != LSZOMB &&
613 			    (show_idle || (pp->p_pctcpu != 0) ||
614 			    (pp->p_stat == LSRUN || pp->p_stat == LSONPROC)) &&
615 			    (!show_uid || pp->p_ruid == (uid_t)sel->uid)) {
616 				*prefp++ = pp;
617 				active_procs++;
618 			}
619 		}
620 	}
621 
622 	/* if requested, sort the "interesting" processes */
623 	if (compare != NULL) {
624 		qsort((char *)pref, active_procs, sizeof(struct kinfo_proc2 *),
625 		    (int (*)(const void *, const void *))compare);
626 	}
627 
628 	/* remember active and total counts */
629 	si->p_total = total_procs;
630 	si->p_active = pref_len = active_procs;
631 
632 	/* pass back a handle */
633 	handle.next_proc = pref;
634 	handle.remaining = active_procs;
635 	return((caddr_t)&handle);
636 }
637 
638 static caddr_t
639 get_lwp_info(struct system_info *si, struct process_select *sel,
640 	     int (*compare)(struct proc **, struct proc **))
641 {
642 	int i;
643 	int total_lwps;
644 	int active_lwps;
645 	struct kinfo_lwp **lrefp, **n;
646 	struct kinfo_lwp *lp;
647 	struct kinfo_proc2 *pp;
648 
649 	/* these are copied out of sel for speed */
650 	int show_idle;
651 	int show_system;
652 	int show_uid;
653 	int show_command;
654 
655 	static struct handle handle;
656 
657 	pp = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2),
658 	    &thread_nproc);
659 	if (pp == NULL) {
660 		(void) fprintf(stderr, "top: Out of memory.\n");
661 		quit(23);
662 	}
663 	if (thread_pbase == NULL || thread_nproc != thread_onproc) {
664 		free(thread_pbase);
665 		thread_onproc = thread_nproc;
666 		thread_pbase = calloc(sizeof(struct kinfo_proc2), thread_nproc);
667 		if (thread_pbase == NULL) {
668 			(void) fprintf(stderr, "top: Out of memory.\n");
669 			quit(23);
670 		}
671 	}
672 	memcpy(thread_pbase, pp, sizeof(struct kinfo_proc2) * thread_nproc);
673 
674 	lbase = kvm_getlwps(kd, -1, 0, sizeof(struct kinfo_lwp), &nlwp);
675 	if (lbase == NULL) {
676 #ifdef notyet
677 		if (sel->pid != -1) {
678 			nproc = 0;
679 			nlwp = 0;
680 		}
681 		else
682 #endif
683 		{
684 			(void) fprintf(stderr, "top: Out of memory.\n");
685 			quit(23);
686 		}
687 	}
688 	if (nlwp > onlwp) {
689 		n = (struct kinfo_lwp **) realloc(lref,
690 		    sizeof(struct kinfo_lwp *) * nlwp);
691 		if (n == NULL) {
692 			(void) fprintf(stderr, "top: Out of memory.\n");
693 			quit(23);
694 		}
695 		lref = n;
696 		onlwp = nlwp;
697 	}
698 	/* get a pointer to the states summary array */
699 	si->procstates = process_states;
700 
701 	/* set up flags which define what we are going to select */
702 	show_idle = sel->idle;
703 	show_system = sel->system;
704 	show_uid = sel->uid != -1;
705 	show_command = sel->command != NULL;
706 
707 	/* count up thread states and get pointers to interesting threads */
708 	total_lwps = 0;
709 	active_lwps = 0;
710 	memset((char *)process_states, 0, sizeof(process_states));
711 	lrefp = lref;
712 	for (lp = lbase, i = 0; i < nlwp; lp++, i++) {
713 		if (sel->pid != -1 && sel->pid != lp->l_pid)
714 			continue;
715 
716 		/*
717 		 * Place pointers to each valid lwp structure in lref[].
718 		 * thread slots that are actually in use have a non-zero
719 		 * status field.  threads with L_SYSTEM set are system
720 		 * threads---these get ignored unless show_sysprocs is set.
721 		 */
722 		if (lp->l_stat != 0 && (show_system || ((lp->l_flag & LW_SYSTEM) == 0))) {
723 			total_lwps++;
724 			process_states[(unsigned char) lp->l_stat]++;
725 			if (lp->l_stat != LSZOMB &&
726 			    (show_idle || (lp->l_pctcpu != 0) ||
727 			    (lp->l_stat == LSRUN || lp->l_stat == LSONPROC)) &&
728 			    (!show_uid || uid_from_thread(lp) == (uid_t)sel->uid)) {
729 				*lrefp++ = lp;
730 				active_lwps++;
731 			}
732 		}
733 	}
734 
735 	/* if requested, sort the "interesting" threads */
736 	if (compare != NULL) {
737 		qsort((char *)lref, active_lwps, sizeof(struct kinfo_lwp *),
738 		    (int (*)(const void *, const void *))compare);
739 	}
740 
741 	/* remember active and total counts */
742 	si->p_total = total_lwps;
743 	si->p_active = lref_len = active_lwps;
744 
745 	/* pass back a handle */
746 	handle.next_proc = (struct kinfo_proc2 **)lref;
747 	handle.remaining = active_lwps;
748 
749 	return((caddr_t)&handle);
750 }
751 
752 char *
753 format_next_process(caddr_t handle, char *(*get_userid)(int))
754 {
755 
756 	if (threadmode)
757 		return format_next_lwp(handle, get_userid);
758 	else
759 		return format_next_proc(handle, get_userid);
760 }
761 
762 
763 char *
764 format_next_proc(caddr_t handle, char *(*get_userid)(int))
765 {
766 	struct kinfo_proc2 *pp;
767 	long cputime;
768 	double pct;
769 	struct handle *hp;
770 	const char *statep;
771 #ifdef KI_NOCPU
772 	char state[10];
773 #endif
774 	char wmesg[KI_WMESGLEN + 1];
775 	static char fmt[MAX_COLS];		/* static area where result is built */
776 	char *pretty = "";
777 
778 	/* find and remember the next proc structure */
779 	hp = (struct handle *)handle;
780 	pp = *(hp->next_proc++);
781 	hp->remaining--;
782 
783 	/* get the process's user struct and set cputime */
784 	if ((pp->p_flag & L_INMEM) == 0)
785 		pretty = "<>";
786 	else if ((pp->p_flag & P_SYSTEM) != 0)
787 		pretty = "[]";
788 
789 	if (pretty[0] != '\0') {
790 		/*
791 		 * Print swapped processes as <pname> and
792 		 * system processes as [pname]
793 		 */
794 		char *comm = pp->p_comm;
795 #define COMSIZ sizeof(pp->p_comm)
796 		char buf[COMSIZ];
797 		(void) strncpy(buf, comm, COMSIZ);
798 		comm[0] = pretty[0];
799 		(void) strncpy(&comm[1], buf, COMSIZ - 2);
800 		comm[COMSIZ - 2] = '\0';
801 		(void) strncat(comm, &pretty[1], COMSIZ - 1);
802 		comm[COMSIZ - 1] = '\0';
803 	}
804 
805 #if 0
806 	/* This does not produce the correct results */
807 	cputime = pp->p_uticks + pp->p_sticks + pp->p_iticks;
808 #else
809 	cputime = pp->p_rtime_sec;	/* This does not count interrupts */
810 #endif
811 
812 	/* calculate the base for CPU percentages */
813 	pct = pctdouble(pp->p_pctcpu);
814 
815 	if (pp->p_stat == LSSLEEP) {
816 		strlcpy(wmesg, pp->p_wmesg, sizeof(wmesg));
817 		statep = wmesg;
818 	} else
819 		statep = state_abbrev[(unsigned)pp->p_stat];
820 
821 #ifdef KI_NOCPU
822 	/* Post-1.5 change: add CPU number if appropriate */
823 	if (pp->p_cpuid != KI_NOCPU && ncpu > 1) {
824 		switch (pp->p_stat) {
825 		case LSONPROC:
826 		case LSRUN:
827 		case LSSLEEP:
828 		case LSIDL:
829 			(void)snprintf(state, sizeof(state), "%.6s/%d",
830 			     statep, get_cpunum(pp->p_cpuid));
831 			statep = state;
832 			break;
833 		}
834 	}
835 #endif
836 	/* format this entry */
837 	sprintf(fmt,
838 	    Proc_format,
839 	    pp->p_pid,
840 	    (*userprint)(pp->p_ruid),
841 	    pp->p_priority,
842 	    pp->p_nice - NZERO,
843 	    format_k(pagetok(PROCSIZE(pp))),
844 	    format_k(pagetok(pp->p_vm_rssize)),
845 	    statep,
846 	    format_time(cputime),
847 	    100.0 * weighted_cpu(p_, pct, pp),
848 	    100.0 * pct,
849 	    printable(pp->p_comm));
850 
851 	/* return the result */
852 	return(fmt);
853 }
854 
855 static char *
856 format_next_lwp(caddr_t handle, char *(*get_userid)(int))
857 {
858 	struct kinfo_proc2 *pp;
859 	struct kinfo_lwp *pl;
860 	long cputime;
861 	double pct;
862 	struct handle *hp;
863 	const char *statep;
864 #ifdef KI_NOCPU
865 	char state[10];
866 #endif
867 	char wmesg[KI_WMESGLEN + 1];
868 	static char fmt[MAX_COLS];		/* static area where result is built */
869 	char *pretty = "";
870 	char *comm;
871 	int uid;
872 
873 	/* find and remember the next proc structure */
874 	hp = (struct handle *)handle;
875 	pl = (struct kinfo_lwp *)*(hp->next_proc++);
876 	hp->remaining--;
877 	pp = proc_from_thread(pl);
878 
879 	/* get the process's user struct and set cputime */
880 	if (pp) {
881 		comm = pp->p_comm;
882 #if 0
883 		/* XXX needs to be per thread but is not. just ignore for now. */
884 		if ((pp->p_flag & L_INMEM) == 0)
885 			pretty = "<>";
886 		else
887 #endif
888 		if ((pp->p_flag & P_SYSTEM) != 0)
889 			pretty = "[]";
890 
891 		if (pretty[0] != '\0' && comm[0] != pretty[0]) {
892 			/*
893 			 * Print swapped processes as <pname> and
894 			 * system processes as [pname]
895 			 */
896 #define COMSIZ sizeof(pp->p_comm)
897 			char buf[COMSIZ];
898 			(void) strncpy(buf, comm, COMSIZ);
899 			comm[0] = pretty[0];
900 			(void) strncpy(&comm[1], buf, COMSIZ - 2);
901 			comm[COMSIZ - 2] = '\0';
902 			(void) strncat(comm, &pretty[1], COMSIZ - 1);
903 			comm[COMSIZ - 1] = '\0';
904 		}
905 		uid = pp->p_ruid;
906 	} else {
907 		comm = "<gone>";
908 		uid = 0;
909 	}
910 
911 	cputime = pl->l_rtime_sec;
912 
913 	/* calculate the base for CPU percentages */
914 	pct = pctdouble(pl->l_pctcpu);
915 
916 	if (pl->l_stat == LSSLEEP) {
917 		strlcpy(wmesg, pl->l_wmesg, sizeof(wmesg));
918 		statep = wmesg;
919 	} else
920 		statep = state_abbrev[(unsigned)pl->l_stat];
921 
922 #ifdef KI_NOCPU
923 	/* Post-1.5 change: add CPU number if appropriate */
924 	if (pl->l_cpuid != KI_NOCPU && ncpu > 1) {
925 		switch (pl->l_stat) {
926 		case LSONPROC:
927 		case LSRUN:
928 		case LSSLEEP:
929 		case LSIDL:
930 			(void)snprintf(state, sizeof(state), "%.6s/%d",
931 			     statep, get_cpunum(pl->l_cpuid));
932 			statep = state;
933 			break;
934 		}
935 	}
936 #endif
937 
938 	if (pl->l_name[0] == '\0') {
939 		pl->l_name[0] = '-';
940 		pl->l_name[1] = '\0';
941 	}
942 
943 	/* format this entry */
944 	sprintf(fmt,
945 	    Thread_format,
946 	    pl->l_pid,
947 	    pl->l_lid,
948 	    (*userprint)(uid),
949 	    pl->l_priority,
950 	    statep,
951 	    format_time(cputime),
952 	    100.0 * weighted_cpu(l_, pct, pl),
953 	    100.0 * pct,
954 	    printable(comm),
955 	    printable(pl->l_name));
956 
957 	/* return the result */
958 	return(fmt);
959 }
960 
961 /* comparison routines for qsort */
962 
963 /*
964  * There are currently four possible comparison routines.  main selects
965  * one of these by indexing in to the array proc_compares.
966  *
967  * Possible keys are defined as macros below.  Currently these keys are
968  * defined:  percent CPU, CPU ticks, process state, resident set size,
969  * total virtual memory usage.  The process states are ordered as follows
970  * (from least to most important):  WAIT, zombie, sleep, stop, start, run.
971  * The array declaration below maps a process state index into a number
972  * that reflects this ordering.
973  */
974 
975 /*
976  * First, the possible comparison keys.  These are defined in such a way
977  * that they can be merely listed in the source code to define the actual
978  * desired ordering.
979  */
980 
981 #define ORDERKEY_PCTCPU(pfx) \
982 	if (lresult = (pctcpu)(p2)->pfx ## pctcpu - (pctcpu)(p1)->pfx ## pctcpu,\
983 	    (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
984 
985 #define ORDERKEY_CPTICKS(pfx) \
986 	if (lresult = (pctcpu)(p2)->pfx ## rtime_sec \
987 		    - (pctcpu)(p1)->pfx ## rtime_sec,\
988 	    (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
989 
990 #define ORDERKEY_STATE(pfx) \
991 	if ((result = sorted_state[(int)(p2)->pfx ## stat] - \
992 		      sorted_state[(int)(p1)->pfx ## stat] ) == 0)
993 
994 #define ORDERKEY_PRIO(pfx) \
995 	if ((result = (p2)->pfx ## priority - (p1)->pfx ## priority) == 0)
996 
997 #define ORDERKEY_RSSIZE \
998 	if ((result = p2->p_vm_rssize - p1->p_vm_rssize) == 0)
999 
1000 #define ORDERKEY_MEM	\
1001 	if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0)
1002 #define ORDERKEY_SIZE(v1, v2)	\
1003 	if ((result = (v2 - v1)) == 0)
1004 
1005 /*
1006  * Now the array that maps process state to a weight.
1007  * The order of the elements should match those in state_abbrev[]
1008  */
1009 
1010 static int sorted_state[] = {
1011 	0,	/*  (not used)	  ?	*/
1012 	6,	/* "start"	SIDL	*/
1013 	4,	/* "run"	SRUN	*/
1014 	3,	/* "sleep"	SSLEEP	*/
1015 	3,	/* "stop"	SSTOP	*/
1016 	2,	/* "dead"	SDEAD	*/
1017 	1,	/* "zomb"	SZOMB	*/
1018 	5,	/* "onproc"	SONPROC	*/
1019 };
1020 
1021 /* compare_cpu - the comparison function for sorting by CPU percentage */
1022 
1023 static int
1024 compare_cpu(pp1, pp2)
1025 	struct proc **pp1, **pp2;
1026 {
1027 	int result;
1028 	pctcpu lresult;
1029 
1030 	if (threadmode) {
1031 		struct kinfo_lwp *p1 = *(struct kinfo_lwp **) pp1;
1032 		struct kinfo_lwp *p2 = *(struct kinfo_lwp **) pp2;
1033 
1034 		ORDERKEY_PCTCPU(l_)
1035 		ORDERKEY_CPTICKS(l_)
1036 		ORDERKEY_STATE(l_)
1037 		ORDERKEY_PRIO(l_)
1038 		;
1039 	} else {
1040 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1041 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1042 
1043 		ORDERKEY_PCTCPU(p_)
1044 		ORDERKEY_CPTICKS(p_)
1045 		ORDERKEY_STATE(p_)
1046 		ORDERKEY_PRIO(p_)
1047 		ORDERKEY_RSSIZE
1048 		ORDERKEY_MEM
1049 		;
1050 	}
1051 
1052 	return (result);
1053 }
1054 
1055 /* compare_prio - the comparison function for sorting by process priority */
1056 
1057 static int
1058 compare_prio(pp1, pp2)
1059 	struct proc **pp1, **pp2;
1060 {
1061 	int result;
1062 	pctcpu lresult;
1063 
1064 	if (threadmode) {
1065 		struct kinfo_lwp *p1 = *(struct kinfo_lwp **) pp1;
1066 		struct kinfo_lwp *p2 = *(struct kinfo_lwp **) pp2;
1067 
1068 		ORDERKEY_PRIO(l_)
1069 		ORDERKEY_PCTCPU(l_)
1070 		ORDERKEY_CPTICKS(l_)
1071 		ORDERKEY_STATE(l_)
1072 		;
1073 	} else {
1074 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1075 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1076 
1077 		ORDERKEY_PRIO(p_)
1078 		ORDERKEY_PCTCPU(p_)
1079 		ORDERKEY_CPTICKS(p_)
1080 		ORDERKEY_STATE(p_)
1081 		ORDERKEY_RSSIZE
1082 		ORDERKEY_MEM
1083 		;
1084 	}
1085 
1086 	return (result);
1087 }
1088 
1089 /* compare_res - the comparison function for sorting by resident set size */
1090 
1091 static int
1092 compare_res(pp1, pp2)
1093 	struct proc **pp1, **pp2;
1094 {
1095 	int result;
1096 	pctcpu lresult;
1097 
1098 	if (threadmode) {
1099 		struct kinfo_lwp *p1 = *(struct kinfo_lwp **) pp1;
1100 		struct kinfo_lwp *p2 = *(struct kinfo_lwp **) pp2;
1101 
1102 		ORDERKEY_PCTCPU(l_)
1103 		ORDERKEY_CPTICKS(l_)
1104 		ORDERKEY_STATE(l_)
1105 		ORDERKEY_PRIO(l_)
1106 		;
1107 	} else {
1108 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1109 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1110 
1111 		ORDERKEY_RSSIZE
1112 		ORDERKEY_MEM
1113 		ORDERKEY_PCTCPU(p_)
1114 		ORDERKEY_CPTICKS(p_)
1115 		ORDERKEY_STATE(p_)
1116 		ORDERKEY_PRIO(p_)
1117 		;
1118 	}
1119 
1120 	return (result);
1121 }
1122 
1123 static int
1124 compare_pid(pp1, pp2)
1125 	struct proc **pp1, **pp2;
1126 {
1127 	if (threadmode) {
1128 		struct kinfo_lwp *l1 = *(struct kinfo_lwp **) pp1;
1129 		struct kinfo_lwp *l2 = *(struct kinfo_lwp **) pp2;
1130 		struct kinfo_proc2 *p1 = proc_from_thread(l1);
1131 		struct kinfo_proc2 *p2 = proc_from_thread(l2);
1132 		return p2->p_pid - p1->p_pid;
1133 	} else {
1134 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1135 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1136 		return p2->p_pid - p1->p_pid;
1137 	}
1138 }
1139 
1140 static int
1141 compare_command(pp1, pp2)
1142 	struct proc **pp1, **pp2;
1143 {
1144 	if (threadmode) {
1145 		struct kinfo_lwp *l1 = *(struct kinfo_lwp **) pp1;
1146 		struct kinfo_lwp *l2 = *(struct kinfo_lwp **) pp2;
1147 		struct kinfo_proc2 *p1 = proc_from_thread(l1);
1148 		struct kinfo_proc2 *p2 = proc_from_thread(l2);
1149 		return strcmp(p2->p_comm, p1->p_comm);
1150 	} else {
1151 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1152 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1153 		return strcmp(p2->p_comm, p1->p_comm);
1154 	}
1155 }
1156 
1157 static int
1158 compare_username(pp1, pp2)
1159 	struct proc **pp1, **pp2;
1160 {
1161 	if (threadmode) {
1162 		struct kinfo_lwp *l1 = *(struct kinfo_lwp **) pp1;
1163 		struct kinfo_lwp *l2 = *(struct kinfo_lwp **) pp2;
1164 		struct kinfo_proc2 *p1 = proc_from_thread(l1);
1165 		struct kinfo_proc2 *p2 = proc_from_thread(l2);
1166 		return strcmp(p2->p_login, p1->p_login);
1167 	} else {
1168 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1169 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1170 		return strcmp(p2->p_login, p1->p_login);
1171 	}
1172 }
1173 /* compare_size - the comparison function for sorting by total memory usage */
1174 
1175 static int
1176 compare_size(pp1, pp2)
1177 	struct proc **pp1, **pp2;
1178 {
1179 	int result;
1180 	pctcpu lresult;
1181 
1182 	if (threadmode) {
1183 		struct kinfo_lwp *p1 = *(struct kinfo_lwp **) pp1;
1184 		struct kinfo_lwp *p2 = *(struct kinfo_lwp **) pp2;
1185 
1186 		ORDERKEY_PCTCPU(l_)
1187 		ORDERKEY_CPTICKS(l_)
1188 		ORDERKEY_STATE(l_)
1189 		ORDERKEY_PRIO(l_)
1190 		;
1191 	} else {
1192 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1193 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1194 
1195 		ORDERKEY_MEM
1196 		ORDERKEY_RSSIZE
1197 		ORDERKEY_PCTCPU(p_)
1198 		ORDERKEY_CPTICKS(p_)
1199 		ORDERKEY_STATE(p_)
1200 		ORDERKEY_PRIO(p_)
1201 		;
1202 	}
1203 
1204 	return (result);
1205 }
1206 
1207 /* compare_state - the comparison function for sorting by process state */
1208 
1209 static int
1210 compare_state(pp1, pp2)
1211 	struct proc **pp1, **pp2;
1212 {
1213 	int result;
1214 	pctcpu lresult;
1215 
1216 	if (threadmode) {
1217 		struct kinfo_lwp *p1 = *(struct kinfo_lwp **) pp1;
1218 		struct kinfo_lwp *p2 = *(struct kinfo_lwp **) pp2;
1219 
1220 		ORDERKEY_STATE(l_)
1221 		ORDERKEY_PCTCPU(l_)
1222 		ORDERKEY_CPTICKS(l_)
1223 		ORDERKEY_PRIO(l_)
1224 		;
1225 	} else {
1226 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1227 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1228 
1229 		ORDERKEY_STATE(p_)
1230 		ORDERKEY_PCTCPU(p_)
1231 		ORDERKEY_CPTICKS(p_)
1232 		ORDERKEY_PRIO(p_)
1233 		ORDERKEY_RSSIZE
1234 		ORDERKEY_MEM
1235 		;
1236 	}
1237 
1238 	return (result);
1239 }
1240 
1241 /* compare_time - the comparison function for sorting by total CPU time */
1242 
1243 static int
1244 compare_time(pp1, pp2)
1245 	struct proc **pp1, **pp2;
1246 {
1247 	int result;
1248 	pctcpu lresult;
1249 
1250 	if (threadmode) {
1251 		struct kinfo_lwp *p1 = *(struct kinfo_lwp **) pp1;
1252 		struct kinfo_lwp *p2 = *(struct kinfo_lwp **) pp2;
1253 
1254 		ORDERKEY_CPTICKS(l_)
1255 		ORDERKEY_PCTCPU(l_)
1256 		ORDERKEY_STATE(l_)
1257 		ORDERKEY_PRIO(l_)
1258 		;
1259 	} else {
1260 		struct kinfo_proc2 *p1 = *(struct kinfo_proc2 **) pp1;
1261 		struct kinfo_proc2 *p2 = *(struct kinfo_proc2 **) pp2;
1262 
1263 		ORDERKEY_CPTICKS(p_)
1264 		ORDERKEY_PCTCPU(p_)
1265 		ORDERKEY_STATE(p_)
1266 		ORDERKEY_PRIO(p_)
1267 		ORDERKEY_MEM
1268 		ORDERKEY_RSSIZE
1269 		;
1270 	}
1271 
1272 	return (result);
1273 }
1274 
1275 
1276 /*
1277  * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
1278  *		the process does not exist.
1279  *		It is EXTREMLY IMPORTANT that this function work correctly.
1280  *		If top runs setuid root (as in SVR4), then this function
1281  *		is the only thing that stands in the way of a serious
1282  *		security problem.  It validates requests for the "kill"
1283  *		and "renice" commands.
1284  */
1285 
1286 int
1287 proc_owner(pid)
1288 	int pid;
1289 {
1290 	int cnt;
1291 	struct kinfo_proc2 **prefp;
1292 	struct kinfo_proc2 *pp;
1293 
1294 	if (threadmode)
1295 		return(-1);
1296 
1297 	prefp = pref;
1298 	cnt = pref_len;
1299 	while (--cnt >= 0) {
1300 		pp = *prefp++;
1301 		if (pp->p_pid == (pid_t)pid)
1302 			return(pp->p_ruid);
1303 	}
1304 	return(-1);
1305 }
1306 
1307 /*
1308  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
1309  *	between array "old" and "new", putting the percentages i "out".
1310  *	"cnt" is size of each array and "diffs" is used for scratch space.
1311  *	The array "old" is updated on each call.
1312  *	The routine assumes modulo arithmetic.  This function is especially
1313  *	useful on BSD mchines for calculating CPU state percentages.
1314  */
1315 
1316 static void
1317 percentages64(cnt, out, new, old, diffs)
1318 	int cnt;
1319 	int *out;
1320 	u_int64_t *new;
1321 	u_int64_t *old;
1322 	u_int64_t *diffs;
1323 {
1324 	int i;
1325 	u_int64_t change;
1326 	u_int64_t total_change;
1327 	u_int64_t *dp;
1328 	u_int64_t half_total;
1329 
1330 	/* initialization */
1331 	total_change = 0;
1332 	dp = diffs;
1333 
1334 	/* calculate changes for each state and the overall change */
1335 	for (i = 0; i < cnt; i++) {
1336 		/*
1337 		 * Don't worry about wrapping - even at hz=1GHz, a
1338 		 * u_int64_t will last at least 544 years.
1339 		 */
1340 		change = *new - *old;
1341 		total_change += (*dp++ = change);
1342 		*old++ = *new++;
1343 	}
1344 
1345 	/* avoid divide by zero potential */
1346 	if (total_change == 0)
1347 		total_change = 1;
1348 
1349 	/* calculate percentages based on overall change, rounding up */
1350 	half_total = total_change / 2;
1351 	for (i = 0; i < cnt; i++)
1352 		*out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
1353 }
1354