1 /* $NetBSD: pigs.c,v 1.30 2006/10/22 16:43:24 christos Exp $ */
4 * Copyright (c) 1980, 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)pigs.c 8.2 (Berkeley) 9/23/93";
37 __RCSID("$NetBSD: pigs.c,v 1.30 2006/10/22 16:43:24 christos Exp $");
41 * Pigs display from Bill Reeves at Lucasfilm
44 #include <sys/param.h>
45 #include <sys/sched.h>
46 #include <sys/sysctl.h>
58 int compare_pctcpu(const void *, const void *);
63 u_int64_t stime
[CPUSTATES
];
69 #define P_ZOMBIE(p) ((p)->p_stat == SZOMB)
76 return (subwin(stdscr
, -1, 0, 5, 0));
95 struct kinfo_proc2
*kp
;
99 char pidname
[30], pidstr
[7], usrstr
[9];
103 /* Accumulate the percent of CPU per user. */
105 for (i
= 0; i
<= nproc
; i
++) {
106 /* Accumulate the percentage. */
107 total
+= pt
[i
].pt_pctcpu
;
114 qsort(pt
, nproc
+ 1, sizeof (struct p_times
), compare_pctcpu
);
117 if (i
> getmaxy(wnd
)-1)
119 for (k
= 0; i
> 0 && pt
[k
].pt_pctcpu
> 0.01; i
--, y
++, k
++) {
120 if (pt
[k
].pt_kp
== NULL
) {
128 snprintf(pidstr
, sizeof(pidstr
), "%5d", kp
->p_pid
);
129 snprintf(usrstr
, sizeof(usrstr
), "%8s",
130 user_from_uid(kp
->p_uid
, 0));
134 mvwaddstr(wnd
, y
, 0, usrstr
);
135 mvwaddstr(wnd
, y
, 9, pidstr
);
136 (void)snprintf(pidname
, sizeof(pidname
), "%9.9s", pname
);
137 mvwaddstr(wnd
, y
, 15, pidname
);
138 mvwhline(wnd
, y
, 25, 'X', pt
[k
].pt_pctcpu
*factor
+ 0.5);
140 wmove(wnd
, y
, 0); wclrtobot(wnd
);
143 static struct nlist namelist
[] = {
146 { .n_name
= "_ccpu" },
148 { .n_name
= "_fscale" },
150 { .n_name
= "_physmem" },
159 if (namelist
[X_FIRST
].n_type
== 0) {
160 if (kvm_nlist(kd
, namelist
)) {
164 if (namelist
[X_FIRST
].n_type
== 0) {
165 error("namelist failed");
169 (void) fetch_cptime(stime
);
170 KREAD(NPTR(X_PHYSMEM
), &mempages
, sizeof (mempages
));
171 NREAD(X_CCPU
, &ccpu
, sizeof ccpu
);
172 NREAD(X_FSCALE
, &fscale
, sizeof fscale
);
173 lccpu
= log((double) ccpu
/ fscale
);
183 struct kinfo_proc2
*kpp
, *k
;
184 u_int64_t cputime
[CPUSTATES
];
186 static int lastnproc
= 0;
188 if (namelist
[X_FIRST
].n_type
== 0)
190 if ((kpp
= kvm_getproc2(kd
, KERN_PROC_ALL
, 0, sizeof(*kpp
),
192 error("%s", kvm_geterr(kd
));
197 if (nproc
> lastnproc
) {
200 malloc((nproc
+ 1) * sizeof(struct p_times
))) == NULL
) {
201 error("Out of memory");
207 * calculate %cpu for each proc
209 for (i
= 0; i
< nproc
; i
++) {
210 pt
[i
].pt_kp
= k
= &kpp
[i
];
211 pctp
= &pt
[i
].pt_pctcpu
;
213 if (k
->p_swtime
== 0 || k
->p_stat
== SZOMB
)
216 *pctp
= ((double) k
->p_pctcpu
/
217 fscale
) / (1.0 - exp(k
->p_swtime
* lccpu
));
220 * and for the imaginary "idle" process
222 (void) fetch_cptime(cputime
);
224 for (i
= 0; i
< CPUSTATES
; i
++)
225 t
+= cputime
[i
] - stime
[i
];
228 pt
[nproc
].pt_kp
= NULL
;
229 pt
[nproc
].pt_pctcpu
= (cputime
[CP_IDLE
] - stime
[CP_IDLE
]) / t
;
230 for (i
= 0; i
< CPUSTATES
; i
++)
231 stime
[i
] = cputime
[i
];
239 mvwaddstr(wnd
, 0, 25, "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100");
243 compare_pctcpu(const void *a
, const void *b
)
245 return (((const struct p_times
*) a
)->pt_pctcpu
>
246 ((const struct p_times
*) b
)->pt_pctcpu
)? -1: 1;