pigs.c revision 172207
175584Sru/*-
275584Sru * Copyright (c) 1980, 1992, 1993
375584Sru *	The Regents of the University of California.  All rights reserved.
4104862Sru *
575584Sru * Redistribution and use in source and binary forms, with or without
675584Sru * modification, are permitted provided that the following conditions
775584Sru * are met:
875584Sru * 1. Redistributions of source code must retain the above copyright
975584Sru *    notice, this list of conditions and the following disclaimer.
1075584Sru * 2. Redistributions in binary form must reproduce the above copyright
1175584Sru *    notice, this list of conditions and the following disclaimer in the
1275584Sru *    documentation and/or other materials provided with the distribution.
1375584Sru * 3. All advertising materials mentioning features or use of this software
1475584Sru *    must display the following acknowledgement:
15104862Sru *	This product includes software developed by the University of
1675584Sru *	California, Berkeley and its contributors.
1775584Sru * 4. Neither the name of the University nor the names of its contributors
1875584Sru *    may be used to endorse or promote products derived from this software
1975584Sru *    without specific prior written permission.
2075584Sru *
2175584Sru * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22104862Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2375584Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2475584Sru * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2575584Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2675584Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2775584Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2875584Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2975584Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3075584Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3175584Sru * SUCH DAMAGE.
3275584Sru */
3375584Sru
3475584Sru#if 0
3575584Sru#ifndef lint
3675584Srustatic char sccsid[] = "@(#)pigs.c	8.2 (Berkeley) 9/23/93";
3775584Sru#endif /* not lint */
3875584Sru#endif
3975584Sru
4075584Sru#include <sys/cdefs.h>
4175584Sru__FBSDID("$FreeBSD: head/usr.bin/systat/pigs.c 172207 2007-09-17 05:31:39Z jeff $");
4275584Sru
4375584Sru/*
4475584Sru * Pigs display from Bill Reeves at Lucasfilm
4575584Sru */
4675584Sru
4775584Sru#include <sys/param.h>
4875584Sru#include <sys/proc.h>
4975584Sru#include <sys/sysctl.h>
5075584Sru#include <sys/time.h>
5175584Sru#include <sys/user.h>
5275584Sru
5375584Sru#include <curses.h>
5475584Sru#include <math.h>
5575584Sru#include <pwd.h>
5675584Sru#include <stdlib.h>
5775584Sru
5875584Sru#include "systat.h"
5975584Sru#include "extern.h"
6075584Sru
6175584Sruint compar(const void *, const void *);
6275584Sru
6375584Srustatic int nproc;
6475584Srustatic struct p_times {
6575584Sru	float pt_pctcpu;
6675584Sru	struct kinfo_proc *pt_kp;
6775584Sru} *pt;
6875584Sru
6975584Srustatic int    fscale;
7075584Srustatic double  lccpu;
7175584Sru
7275584SruWINDOW *
7375584Sruopenpigs()
7475584Sru{
7575584Sru	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
7675584Sru}
7775584Sru
7875584Sruvoid
7975584Sruclosepigs(w)
80104862Sru	WINDOW *w;
8175584Sru{
8275584Sru	if (w == NULL)
8375584Sru		return;
8475584Sru	wclear(w);
8575584Sru	wrefresh(w);
8675584Sru	delwin(w);
8775584Sru}
8875584Sru
8975584Sru
9075584Sruvoid
9175584Srushowpigs()
9275584Sru{
9375584Sru	register int i, j, y, k;
9475584Sru	const char *uname, *pname;
9575584Sru	char pidname[30];
9675584Sru
9775584Sru	if (pt == NULL)
9875584Sru		return;
9975584Sru
10075584Sru	qsort(pt, nproc, sizeof (struct p_times), compar);
10175584Sru	y = 1;
10275584Sru	i = nproc;
10375584Sru	if (i > wnd->_maxy-1)
10475584Sru		i = wnd->_maxy-1;
10575584Sru	for (k = 0; i > 0 && pt[k].pt_pctcpu > 0.01; i--, y++, k++) {
10675584Sru		uname = user_from_uid(pt[k].pt_kp->ki_uid, 0);
10775584Sru		pname = pt[k].pt_kp->ki_comm;
10875584Sru		wmove(wnd, y, 0);
10975584Sru		wclrtoeol(wnd);
11075584Sru		mvwaddstr(wnd, y, 0, uname);
11175584Sru		snprintf(pidname, sizeof(pidname), "%10.10s", pname);
11275584Sru		mvwaddstr(wnd, y, 9, pidname);
11375584Sru		wmove(wnd, y, 20);
11475584Sru		for (j = pt[k].pt_pctcpu * 50 + 0.5; j > 0; j--)
11575584Sru			waddch(wnd, 'X');
11675584Sru	}
117104862Sru	wmove(wnd, y, 0); wclrtobot(wnd);
11875584Sru}
11975584Sru
12075584Sruint
12175584Sruinitpigs()
12275584Sru{
12375584Sru	fixpt_t ccpu;
12475584Sru	size_t len;
12575584Sru	int err;
12675584Sru
12775584Sru	len = sizeof(ccpu);
12875584Sru	err = sysctlbyname("kern.ccpu", &ccpu, &len, NULL, 0);
129114402Sru	if (err || len != sizeof(ccpu)) {
13075584Sru		perror("kern.ccpu");
13175584Sru		return (0);
13275584Sru	}
13375584Sru
13475584Sru	len = sizeof(fscale);
135104862Sru	err = sysctlbyname("kern.fscale", &fscale, &len, NULL, 0);
13675584Sru	if (err || len != sizeof(fscale)) {
13775584Sru		perror("kern.fscale");
13875584Sru		return (0);
139104862Sru	}
14075584Sru
14175584Sru	lccpu = log((double) ccpu / fscale);
14275584Sru
14375584Sru	return(1);
14475584Sru}
14575584Sru
14675584Sruvoid
14775584Srufetchpigs()
14875584Sru{
14975584Sru	int i;
15075584Sru	float ftime;
15175584Sru	float *pctp;
15275584Sru	struct kinfo_proc *kpp;
15375584Sru	static int lastnproc = 0;
15475584Sru
15575584Sru	if ((kpp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc)) == NULL) {
15675584Sru		error("%s", kvm_geterr(kd));
15775584Sru		if (pt)
15875584Sru			free(pt);
15975584Sru		return;
16075584Sru	}
16175584Sru	if (nproc > lastnproc) {
16275584Sru		free(pt);
16375584Sru		if ((pt =
16475584Sru		    malloc(nproc * sizeof(struct p_times))) == NULL) {
16575584Sru			error("Out of memory");
16675584Sru			die(0);
16775584Sru		}
16875584Sru	}
16975584Sru	lastnproc = nproc;
17075584Sru	/*
17175584Sru	 * calculate %cpu for each proc
17275584Sru	 */
173104862Sru	for (i = 0; i < nproc; i++) {
17475584Sru		pt[i].pt_kp = &kpp[i];
17575584Sru		pctp = &pt[i].pt_pctcpu;
17675584Sru		ftime = kpp[i].ki_swtime;
17775584Sru		if (ftime == 0 || (kpp[i].ki_flag & P_INMEM) == 0)
17875584Sru			*pctp = 0;
17975584Sru		else
18075584Sru			*pctp = ((double) kpp[i].ki_pctcpu /
18175584Sru					fscale) / (1.0 - exp(ftime * lccpu));
18275584Sru	}
18375584Sru}
18475584Sru
18575584Sruvoid
18675584Srulabelpigs()
18775584Sru{
18875584Sru	wmove(wnd, 0, 0);
18975584Sru	wclrtoeol(wnd);
19075584Sru	mvwaddstr(wnd, 0, 20,
19175584Sru	    "/0%  /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
19275584Sru}
19375584Sru
19475584Sruint
19575584Srucompar(a, b)
19675584Sru	const void *a, *b;
19775584Sru{
19875584Sru	return (((const struct p_times *) a)->pt_pctcpu >
19975584Sru		((const struct p_times *) b)->pt_pctcpu)? -1: 1;
20075584Sru}
20175584Sru