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