pigs.c revision 175387
1/*-
2 * Copyright (c) 1980, 1992, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if 0
35#ifndef lint
36static char sccsid[] = "@(#)pigs.c	8.2 (Berkeley) 9/23/93";
37#endif /* not lint */
38#endif
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/usr.bin/systat/pigs.c 175387 2008-01-16 19:27:43Z delphij $");
42
43/*
44 * Pigs display from Bill Reeves at Lucasfilm
45 */
46
47#include <sys/param.h>
48#include <sys/proc.h>
49#include <sys/sysctl.h>
50#include <sys/time.h>
51#include <sys/user.h>
52
53#include <curses.h>
54#include <math.h>
55#include <pwd.h>
56#include <stdlib.h>
57
58#include "systat.h"
59#include "extern.h"
60
61int compar(const void *, const void *);
62
63static int nproc;
64static struct p_times {
65	float pt_pctcpu;
66	struct kinfo_proc *pt_kp;
67} *pt;
68
69static int    fscale;
70static double  lccpu;
71
72WINDOW *
73openpigs(void)
74{
75	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
76}
77
78void
79closepigs(WINDOW *w)
80{
81	if (w == NULL)
82		return;
83	wclear(w);
84	wrefresh(w);
85	delwin(w);
86}
87
88
89void
90showpigs(void)
91{
92	int i, j, y, k;
93	const char *uname, *pname;
94	char pidname[30];
95
96	if (pt == NULL)
97		return;
98
99	qsort(pt, nproc, sizeof (struct p_times), compar);
100	y = 1;
101	i = nproc;
102	if (i > wnd->_maxy-1)
103		i = wnd->_maxy-1;
104	for (k = 0; i > 0 && pt[k].pt_pctcpu > 0.01; i--, y++, k++) {
105		uname = user_from_uid(pt[k].pt_kp->ki_uid, 0);
106		pname = pt[k].pt_kp->ki_comm;
107		wmove(wnd, y, 0);
108		wclrtoeol(wnd);
109		mvwaddstr(wnd, y, 0, uname);
110		snprintf(pidname, sizeof(pidname), "%10.10s", pname);
111		mvwaddstr(wnd, y, 9, pidname);
112		wmove(wnd, y, 20);
113		for (j = pt[k].pt_pctcpu * 50 + 0.5; j > 0; j--)
114			waddch(wnd, 'X');
115	}
116	wmove(wnd, y, 0); wclrtobot(wnd);
117}
118
119int
120initpigs(void)
121{
122	fixpt_t ccpu;
123	size_t len;
124	int err;
125
126	len = sizeof(ccpu);
127	err = sysctlbyname("kern.ccpu", &ccpu, &len, NULL, 0);
128	if (err || len != sizeof(ccpu)) {
129		perror("kern.ccpu");
130		return (0);
131	}
132
133	len = sizeof(fscale);
134	err = sysctlbyname("kern.fscale", &fscale, &len, NULL, 0);
135	if (err || len != sizeof(fscale)) {
136		perror("kern.fscale");
137		return (0);
138	}
139
140	lccpu = log((double) ccpu / fscale);
141
142	return(1);
143}
144
145void
146fetchpigs(void)
147{
148	int i;
149	float ftime;
150	float *pctp;
151	struct kinfo_proc *kpp;
152	static int lastnproc = 0;
153
154	if ((kpp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc)) == NULL) {
155		error("%s", kvm_geterr(kd));
156		if (pt)
157			free(pt);
158		return;
159	}
160	if (nproc > lastnproc) {
161		free(pt);
162		if ((pt =
163		    malloc(nproc * sizeof(struct p_times))) == NULL) {
164			error("Out of memory");
165			die(0);
166		}
167	}
168	lastnproc = nproc;
169	/*
170	 * calculate %cpu for each proc
171	 */
172	for (i = 0; i < nproc; i++) {
173		pt[i].pt_kp = &kpp[i];
174		pctp = &pt[i].pt_pctcpu;
175		ftime = kpp[i].ki_swtime;
176		if (ftime == 0 || (kpp[i].ki_flag & P_INMEM) == 0)
177			*pctp = 0;
178		else
179			*pctp = ((double) kpp[i].ki_pctcpu /
180					fscale) / (1.0 - exp(ftime * lccpu));
181	}
182}
183
184void
185labelpigs(void)
186{
187	wmove(wnd, 0, 0);
188	wclrtoeol(wnd);
189	mvwaddstr(wnd, 0, 20,
190	    "/0%  /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
191}
192
193int
194compar(const void *a, const void *b)
195{
196	return (((const struct p_times *) a)->pt_pctcpu >
197		((const struct p_times *) b)->pt_pctcpu)? -1: 1;
198}
199