xref: /minix3/external/bsd/top/dist/machine/m_aix5.c (revision b89261ba018da33f0bd8cd05f5a1fe9e7a9c837b)
1*b89261baSDavid van Moolenbroek /*
2*b89261baSDavid van Moolenbroek  * Copyright (c) 1984 through 2008, William LeFebvre
3*b89261baSDavid van Moolenbroek  * All rights reserved.
4*b89261baSDavid van Moolenbroek  *
5*b89261baSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*b89261baSDavid van Moolenbroek  * modification, are permitted provided that the following conditions are met:
7*b89261baSDavid van Moolenbroek  *
8*b89261baSDavid van Moolenbroek  *     * Redistributions of source code must retain the above copyright
9*b89261baSDavid van Moolenbroek  * notice, this list of conditions and the following disclaimer.
10*b89261baSDavid van Moolenbroek  *
11*b89261baSDavid van Moolenbroek  *     * Redistributions in binary form must reproduce the above
12*b89261baSDavid van Moolenbroek  * copyright notice, this list of conditions and the following disclaimer
13*b89261baSDavid van Moolenbroek  * in the documentation and/or other materials provided with the
14*b89261baSDavid van Moolenbroek  * distribution.
15*b89261baSDavid van Moolenbroek  *
16*b89261baSDavid van Moolenbroek  *     * Neither the name of William LeFebvre nor the names of other
17*b89261baSDavid van Moolenbroek  * contributors may be used to endorse or promote products derived from
18*b89261baSDavid van Moolenbroek  * this software without specific prior written permission.
19*b89261baSDavid van Moolenbroek  *
20*b89261baSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*b89261baSDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*b89261baSDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*b89261baSDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24*b89261baSDavid van Moolenbroek  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25*b89261baSDavid van Moolenbroek  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26*b89261baSDavid van Moolenbroek  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*b89261baSDavid van Moolenbroek  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*b89261baSDavid van Moolenbroek  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*b89261baSDavid van Moolenbroek  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30*b89261baSDavid van Moolenbroek  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*b89261baSDavid van Moolenbroek  */
32*b89261baSDavid van Moolenbroek 
33*b89261baSDavid van Moolenbroek /*
34*b89261baSDavid van Moolenbroek  * top - a top users display for Unix
35*b89261baSDavid van Moolenbroek  *
36*b89261baSDavid van Moolenbroek  * SYNOPSIS:  PowerPC running AIX 5.1 or higher
37*b89261baSDavid van Moolenbroek  *
38*b89261baSDavid van Moolenbroek  * DESCRIPTION:
39*b89261baSDavid van Moolenbroek  * This is the machine-dependent module for AIX 5.1 and higher (may work on
40*b89261baSDavid van Moolenbroek  * older releases too).  It is currently only tested on PowerPC
41*b89261baSDavid van Moolenbroek  * architectures.
42*b89261baSDavid van Moolenbroek  *
43*b89261baSDavid van Moolenbroek  * TERMCAP: -lcurses
44*b89261baSDavid van Moolenbroek  *
45*b89261baSDavid van Moolenbroek  * CFLAGS: -DORDER -DHAVE_GETOPT -DHAVE_STRERROR -DMAXPROCS=10240
46*b89261baSDavid van Moolenbroek  *
47*b89261baSDavid van Moolenbroek  * LIBS: -lperfstat
48*b89261baSDavid van Moolenbroek  *
49*b89261baSDavid van Moolenbroek  * AUTHOR:  Joep Vesseur <joep@fwi.uva.nl>
50*b89261baSDavid van Moolenbroek  *
51*b89261baSDavid van Moolenbroek  * PATCHES: Antoine Tabary <tabary@bruyeres.cea.fr>, Dan Nelson <dnelson@allantgroup.com>
52*b89261baSDavid van Moolenbroek  */
53*b89261baSDavid van Moolenbroek 
54*b89261baSDavid van Moolenbroek #define MAXPROCS 10240
55*b89261baSDavid van Moolenbroek 
56*b89261baSDavid van Moolenbroek #include "config.h"
57*b89261baSDavid van Moolenbroek 
58*b89261baSDavid van Moolenbroek #include <time.h>
59*b89261baSDavid van Moolenbroek #include <stdlib.h>
60*b89261baSDavid van Moolenbroek #include <string.h>
61*b89261baSDavid van Moolenbroek #include <stdio.h>
62*b89261baSDavid van Moolenbroek #include <fcntl.h>
63*b89261baSDavid van Moolenbroek #include <nlist.h>
64*b89261baSDavid van Moolenbroek #include <procinfo.h>
65*b89261baSDavid van Moolenbroek #include <sys/types.h>
66*b89261baSDavid van Moolenbroek #include <sys/proc.h>
67*b89261baSDavid van Moolenbroek #include <sys/sysinfo.h>
68*b89261baSDavid van Moolenbroek #include <sys/sysconfig.h>
69*b89261baSDavid van Moolenbroek #include <pwd.h>
70*b89261baSDavid van Moolenbroek #include <errno.h>
71*b89261baSDavid van Moolenbroek #include <libperfstat.h>
72*b89261baSDavid van Moolenbroek #include "top.h"
73*b89261baSDavid van Moolenbroek #include "machine.h"
74*b89261baSDavid van Moolenbroek #include "utils.h"
75*b89261baSDavid van Moolenbroek 
76*b89261baSDavid van Moolenbroek 
77*b89261baSDavid van Moolenbroek #define PROCRESS(p) (((p)->pi_trss + (p)->pi_drss)*4)
78*b89261baSDavid van Moolenbroek #define PROCSIZE(p) (((p)->pi_tsize/1024+(p)->pi_dvm)*4)
79*b89261baSDavid van Moolenbroek #define PROCTIME(pi) (pi->pi_ru.ru_utime.tv_sec + pi->pi_ru.ru_stime.tv_sec)
80*b89261baSDavid van Moolenbroek 
81*b89261baSDavid van Moolenbroek #ifdef OLD
82*b89261baSDavid van Moolenbroek /*
83*b89261baSDavid van Moolenbroek  * structure definition taken from 'monitor' by Jussi Maki (jmaki@hut.fi)
84*b89261baSDavid van Moolenbroek  */
85*b89261baSDavid van Moolenbroek struct vmker {
86*b89261baSDavid van Moolenbroek     uint n0,n1,n2,n3,n4,n5,n6,n7,n8;
87*b89261baSDavid van Moolenbroek     uint totalmem;
88*b89261baSDavid van Moolenbroek     uint badmem; /* this is used in RS/6000 model 220 */
89*b89261baSDavid van Moolenbroek     uint freemem;
90*b89261baSDavid van Moolenbroek     uint n12;
91*b89261baSDavid van Moolenbroek     uint numperm;   /* this seems to keep other than text and data segment
92*b89261baSDavid van Moolenbroek                        usage; name taken from /usr/lpp/bos/samples/vmtune.c */
93*b89261baSDavid van Moolenbroek     uint totalvmem,freevmem;
94*b89261baSDavid van Moolenbroek     uint n15, n16, n17, n18, n19;
95*b89261baSDavid van Moolenbroek };
96*b89261baSDavid van Moolenbroek 
97*b89261baSDavid van Moolenbroek #define KMEM "/dev/kmem"
98*b89261baSDavid van Moolenbroek 
99*b89261baSDavid van Moolenbroek /* Indices in the nlist array */
100*b89261baSDavid van Moolenbroek #define X_AVENRUN       0
101*b89261baSDavid van Moolenbroek #define X_SYSINFO       1
102*b89261baSDavid van Moolenbroek #define X_VMKER         2
103*b89261baSDavid van Moolenbroek #define X_V             3
104*b89261baSDavid van Moolenbroek 
105*b89261baSDavid van Moolenbroek static struct nlist nlst[] = {
106*b89261baSDavid van Moolenbroek     { "avenrun", 0, 0, 0, 0, 0 }, /* 0 */
107*b89261baSDavid van Moolenbroek     { "sysinfo", 0, 0, 0, 0, 0 }, /* 1 */
108*b89261baSDavid van Moolenbroek     { "vmker",   0, 0, 0, 0, 0 }, /* 2 */
109*b89261baSDavid van Moolenbroek     { "v",       0, 0, 0, 0, 0 }, /* 3 */
110*b89261baSDavid van Moolenbroek     {  NULL, 0, 0, 0, 0, 0 }
111*b89261baSDavid van Moolenbroek };
112*b89261baSDavid van Moolenbroek 
113*b89261baSDavid van Moolenbroek #endif
114*b89261baSDavid van Moolenbroek 
115*b89261baSDavid van Moolenbroek /* get_process_info returns handle. definition is here */
116*b89261baSDavid van Moolenbroek struct handle
117*b89261baSDavid van Moolenbroek {
118*b89261baSDavid van Moolenbroek 	struct procentry64 **next_proc;
119*b89261baSDavid van Moolenbroek 	int remaining;
120*b89261baSDavid van Moolenbroek };
121*b89261baSDavid van Moolenbroek 
122*b89261baSDavid van Moolenbroek /*
123*b89261baSDavid van Moolenbroek  *  These definitions control the format of the per-process area
124*b89261baSDavid van Moolenbroek  */
125*b89261baSDavid van Moolenbroek static char header[] =
126*b89261baSDavid van Moolenbroek   "   PID X        PRI NICE   SIZE   RES STATE   TIME   WCPU    CPU COMMAND";
127*b89261baSDavid van Moolenbroek /* 0123456   -- field to fill in starts at header+6 */
128*b89261baSDavid van Moolenbroek #define UNAME_START 7
129*b89261baSDavid van Moolenbroek 
130*b89261baSDavid van Moolenbroek #define Proc_format \
131*b89261baSDavid van Moolenbroek 	"%6d %-8.8s %3d %4d %5d%c %4d%c %-5s %6s %5.2f%% %5.2f%% %.14s%s"
132*b89261baSDavid van Moolenbroek 
133*b89261baSDavid van Moolenbroek 
134*b89261baSDavid van Moolenbroek /* these are for detailing the process states */
135*b89261baSDavid van Moolenbroek int process_states[9];
136*b89261baSDavid van Moolenbroek char *procstatenames[] = {
137*b89261baSDavid van Moolenbroek     " none, ", " sleeping, ", " state2, ", " runnable, ",
138*b89261baSDavid van Moolenbroek     " idle, ", " zombie, ", " stopped, ", " running, ", " swapped, ",
139*b89261baSDavid van Moolenbroek     NULL
140*b89261baSDavid van Moolenbroek };
141*b89261baSDavid van Moolenbroek 
142*b89261baSDavid van Moolenbroek /* these are for detailing the cpu states */
143*b89261baSDavid van Moolenbroek int cpu_states[CPU_NTIMES];
144*b89261baSDavid van Moolenbroek char *cpustatenames[] = {
145*b89261baSDavid van Moolenbroek     "idle", "user", "kernel", "wait",
146*b89261baSDavid van Moolenbroek     NULL
147*b89261baSDavid van Moolenbroek };
148*b89261baSDavid van Moolenbroek 
149*b89261baSDavid van Moolenbroek /* these are for detailing the memory statistics */
150*b89261baSDavid van Moolenbroek long memory_stats[7];
151*b89261baSDavid van Moolenbroek char *memorynames[] = {
152*b89261baSDavid van Moolenbroek     "K total, ", "K buf, ", "K sys, ", "K free", NULL
153*b89261baSDavid van Moolenbroek };
154*b89261baSDavid van Moolenbroek #define M_REAL		0
155*b89261baSDavid van Moolenbroek #define M_BUFFERS	1
156*b89261baSDavid van Moolenbroek #define M_SYSTEM	2
157*b89261baSDavid van Moolenbroek #define M_REALFREE	3
158*b89261baSDavid van Moolenbroek 
159*b89261baSDavid van Moolenbroek long swap_stats[3];
160*b89261baSDavid van Moolenbroek char *swapnames[] = {
161*b89261baSDavid van Moolenbroek     "K total, ", "K free", NULL
162*b89261baSDavid van Moolenbroek };
163*b89261baSDavid van Moolenbroek #define M_VIRTUAL 0
164*b89261baSDavid van Moolenbroek #define M_VIRTFREE 1
165*b89261baSDavid van Moolenbroek 
166*b89261baSDavid van Moolenbroek char *state_abbrev[] = {
167*b89261baSDavid van Moolenbroek     NULL, NULL, NULL, NULL, "idle", "zomb", "stop", "run", "swap"
168*b89261baSDavid van Moolenbroek };
169*b89261baSDavid van Moolenbroek 
170*b89261baSDavid van Moolenbroek /* sorting orders. first is default */
171*b89261baSDavid van Moolenbroek char *ordernames[] = {
172*b89261baSDavid van Moolenbroek     "cpu", "size", "res", "time", "pri", NULL
173*b89261baSDavid van Moolenbroek };
174*b89261baSDavid van Moolenbroek 
175*b89261baSDavid van Moolenbroek /* compare routines */
176*b89261baSDavid van Moolenbroek int compare_cpu(), compare_size(), compare_res(), compare_time(),
177*b89261baSDavid van Moolenbroek     compare_prio();
178*b89261baSDavid van Moolenbroek 
179*b89261baSDavid van Moolenbroek int (*proc_compares[])() = {
180*b89261baSDavid van Moolenbroek     compare_cpu,
181*b89261baSDavid van Moolenbroek     compare_size,
182*b89261baSDavid van Moolenbroek     compare_res,
183*b89261baSDavid van Moolenbroek     compare_time,
184*b89261baSDavid van Moolenbroek     compare_prio,
185*b89261baSDavid van Moolenbroek     NULL
186*b89261baSDavid van Moolenbroek };
187*b89261baSDavid van Moolenbroek 
188*b89261baSDavid van Moolenbroek /* useful externals */
189*b89261baSDavid van Moolenbroek long percentages(int cnt, int *out, long *new, long *old, long *diffs);
190*b89261baSDavid van Moolenbroek char *format_time(long seconds);
191*b89261baSDavid van Moolenbroek 
192*b89261baSDavid van Moolenbroek #ifdef OLD
193*b89261baSDavid van Moolenbroek /* useful globals */
194*b89261baSDavid van Moolenbroek int kmem;			/* file descriptor */
195*b89261baSDavid van Moolenbroek 
196*b89261baSDavid van Moolenbroek /* offsets in kernel */
197*b89261baSDavid van Moolenbroek static unsigned long avenrun_offset;
198*b89261baSDavid van Moolenbroek static unsigned long sysinfo_offset;
199*b89261baSDavid van Moolenbroek static unsigned long vmker_offset;
200*b89261baSDavid van Moolenbroek static unsigned long v_offset;
201*b89261baSDavid van Moolenbroek #endif
202*b89261baSDavid van Moolenbroek 
203*b89261baSDavid van Moolenbroek /* used for calculating cpu state percentages */
204*b89261baSDavid van Moolenbroek static long cp_time[CPU_NTIMES];
205*b89261baSDavid van Moolenbroek static long cp_old[CPU_NTIMES];
206*b89261baSDavid van Moolenbroek static long cp_diff[CPU_NTIMES];
207*b89261baSDavid van Moolenbroek 
208*b89261baSDavid van Moolenbroek /* the runqueue length is a cumulative value. keep old value */
209*b89261baSDavid van Moolenbroek long old_runque;
210*b89261baSDavid van Moolenbroek 
211*b89261baSDavid van Moolenbroek /* process info */
212*b89261baSDavid van Moolenbroek struct kernvars v_info;		/* to determine nprocs */
213*b89261baSDavid van Moolenbroek int nprocs;			/* maximum nr of procs in proctab */
214*b89261baSDavid van Moolenbroek int ncpus;			/* nr of cpus installed */
215*b89261baSDavid van Moolenbroek 
216*b89261baSDavid van Moolenbroek struct procentry64 *p_info;	/* needed for vm and ru info */
217*b89261baSDavid van Moolenbroek struct procentry64 **pref;	/* processes selected for display */
218*b89261baSDavid van Moolenbroek struct timeval64 *cpu_proc, *old_cpu_proc; /* total cpu used by each process */
219*b89261baSDavid van Moolenbroek int pref_len;			/* number of processes selected */
220*b89261baSDavid van Moolenbroek 
221*b89261baSDavid van Moolenbroek /* needed to calculate WCPU */
222*b89261baSDavid van Moolenbroek unsigned long curtime;
223*b89261baSDavid van Moolenbroek 
224*b89261baSDavid van Moolenbroek /* needed to calculate CPU */
225*b89261baSDavid van Moolenbroek struct timeval curtimeval;
226*b89261baSDavid van Moolenbroek struct timeval lasttimeval;
227*b89261baSDavid van Moolenbroek 
228*b89261baSDavid van Moolenbroek #ifdef OLD
229*b89261baSDavid van Moolenbroek int getkval(unsigned long offset, caddr_t ptr, int size, char *refstr);
230*b89261baSDavid van Moolenbroek #endif
231*b89261baSDavid van Moolenbroek 
xmalloc(long size)232*b89261baSDavid van Moolenbroek void *xmalloc(long size)
233*b89261baSDavid van Moolenbroek {
234*b89261baSDavid van Moolenbroek 	void *p = malloc(size);
235*b89261baSDavid van Moolenbroek 	if (!p)
236*b89261baSDavid van Moolenbroek 	{
237*b89261baSDavid van Moolenbroek 		fprintf(stderr,"Could not allocate %ld bytes: %s\n", size, strerror(errno));
238*b89261baSDavid van Moolenbroek 		exit(1);
239*b89261baSDavid van Moolenbroek 	}
240*b89261baSDavid van Moolenbroek 	return p;
241*b89261baSDavid van Moolenbroek }
242*b89261baSDavid van Moolenbroek 
243*b89261baSDavid van Moolenbroek /*
244*b89261baSDavid van Moolenbroek  * Initialize globals, get kernel offsets and stuff...
245*b89261baSDavid van Moolenbroek  */
machine_init(statics)246*b89261baSDavid van Moolenbroek int machine_init(statics)
247*b89261baSDavid van Moolenbroek     struct statics *statics;
248*b89261baSDavid van Moolenbroek {
249*b89261baSDavid van Moolenbroek #ifdef OLD
250*b89261baSDavid van Moolenbroek     if ((kmem = open(KMEM, O_RDONLY)) == -1) {
251*b89261baSDavid van Moolenbroek 	perror(KMEM);
252*b89261baSDavid van Moolenbroek 	return -1;
253*b89261baSDavid van Moolenbroek     }
254*b89261baSDavid van Moolenbroek 
255*b89261baSDavid van Moolenbroek     /* get kernel symbol offsets */
256*b89261baSDavid van Moolenbroek     if (knlist(nlst, 4, sizeof(struct nlist)) != 0) {
257*b89261baSDavid van Moolenbroek 	perror("knlist");
258*b89261baSDavid van Moolenbroek 	return -1;
259*b89261baSDavid van Moolenbroek     }
260*b89261baSDavid van Moolenbroek     avenrun_offset = nlst[X_AVENRUN].n_value;
261*b89261baSDavid van Moolenbroek     sysinfo_offset = nlst[X_SYSINFO].n_value;
262*b89261baSDavid van Moolenbroek     vmker_offset   = nlst[X_VMKER].n_value;
263*b89261baSDavid van Moolenbroek     v_offset       = nlst[X_V].n_value;
264*b89261baSDavid van Moolenbroek 
265*b89261baSDavid van Moolenbroek     getkval(v_offset, (caddr_t)&v_info, sizeof v_info, "v");
266*b89261baSDavid van Moolenbroek #else
267*b89261baSDavid van Moolenbroek 	sysconfig(SYS_GETPARMS, &v_info, sizeof v_info);
268*b89261baSDavid van Moolenbroek #endif
269*b89261baSDavid van Moolenbroek     ncpus = v_info.v_ncpus;	/* number of cpus */
270*b89261baSDavid van Moolenbroek 
271*b89261baSDavid van Moolenbroek /* procentry64 is 4912 bytes, and PROCMASK(PIDMAX) is 262144.  That'd
272*b89261baSDavid van Moolenbroek    require 1.2gb for the p_info array, which is way overkill.  Raise
273*b89261baSDavid van Moolenbroek    MAXPROCS if you have more than 10240 active processes in the system.
274*b89261baSDavid van Moolenbroek */
275*b89261baSDavid van Moolenbroek 
276*b89261baSDavid van Moolenbroek #if 0
277*b89261baSDavid van Moolenbroek     nprocs = PROCMASK(PIDMAX);
278*b89261baSDavid van Moolenbroek #else
279*b89261baSDavid van Moolenbroek     nprocs = MAXPROCS;
280*b89261baSDavid van Moolenbroek #endif
281*b89261baSDavid van Moolenbroek 
282*b89261baSDavid van Moolenbroek     cpu_proc = (struct timeval64 *)xmalloc(PROCMASK(PIDMAX) * sizeof (struct timeval64));
283*b89261baSDavid van Moolenbroek     old_cpu_proc = (struct timeval64 *)xmalloc(PROCMASK(PIDMAX) * sizeof (struct timeval64));
284*b89261baSDavid van Moolenbroek     p_info = (struct procentry64 *)xmalloc(nprocs * sizeof (struct procentry64));
285*b89261baSDavid van Moolenbroek     pref = (struct procentry64 **)xmalloc(nprocs * sizeof (struct procentry64 *));
286*b89261baSDavid van Moolenbroek 
287*b89261baSDavid van Moolenbroek     statics->procstate_names = procstatenames;
288*b89261baSDavid van Moolenbroek     statics->cpustate_names = cpustatenames;
289*b89261baSDavid van Moolenbroek     statics->memory_names = memorynames;
290*b89261baSDavid van Moolenbroek     statics->swap_names = swapnames;
291*b89261baSDavid van Moolenbroek     statics->order_names = ordernames;
292*b89261baSDavid van Moolenbroek 
293*b89261baSDavid van Moolenbroek     return(0);
294*b89261baSDavid van Moolenbroek }
295*b89261baSDavid van Moolenbroek 
format_header(uname_field)296*b89261baSDavid van Moolenbroek char *format_header(uname_field)
297*b89261baSDavid van Moolenbroek     register char *uname_field;
298*b89261baSDavid van Moolenbroek {
299*b89261baSDavid van Moolenbroek     register char *ptr;
300*b89261baSDavid van Moolenbroek 
301*b89261baSDavid van Moolenbroek     ptr = header + UNAME_START;
302*b89261baSDavid van Moolenbroek     while (*uname_field != '\0')
303*b89261baSDavid van Moolenbroek     {
304*b89261baSDavid van Moolenbroek 	*ptr++ = *uname_field++;
305*b89261baSDavid van Moolenbroek     }
306*b89261baSDavid van Moolenbroek 
307*b89261baSDavid van Moolenbroek     return(header);
308*b89261baSDavid van Moolenbroek }
309*b89261baSDavid van Moolenbroek 
310*b89261baSDavid van Moolenbroek 
311*b89261baSDavid van Moolenbroek 
312*b89261baSDavid van Moolenbroek 
get_system_info(si)313*b89261baSDavid van Moolenbroek void get_system_info(si)
314*b89261baSDavid van Moolenbroek     struct system_info *si;
315*b89261baSDavid van Moolenbroek {
316*b89261baSDavid van Moolenbroek #ifdef OLD
317*b89261baSDavid van Moolenbroek     long long load_avg[3];
318*b89261baSDavid van Moolenbroek     struct sysinfo64 s_info;
319*b89261baSDavid van Moolenbroek     struct vmker m_info;
320*b89261baSDavid van Moolenbroek #else
321*b89261baSDavid van Moolenbroek     perfstat_memory_total_t m_info1;
322*b89261baSDavid van Moolenbroek     perfstat_cpu_total_t s_info1;
323*b89261baSDavid van Moolenbroek #endif
324*b89261baSDavid van Moolenbroek     int i;
325*b89261baSDavid van Moolenbroek     int total = 0;
326*b89261baSDavid van Moolenbroek 
327*b89261baSDavid van Moolenbroek #ifdef OLD
328*b89261baSDavid van Moolenbroek     /* get the load avarage array */
329*b89261baSDavid van Moolenbroek     getkval(avenrun_offset, (caddr_t)load_avg, sizeof load_avg, "avenrun");
330*b89261baSDavid van Moolenbroek 
331*b89261baSDavid van Moolenbroek     /* get the sysinfo structure */
332*b89261baSDavid van Moolenbroek     getkval(sysinfo_offset, (caddr_t)&s_info, sizeof s_info, "sysinfo64");
333*b89261baSDavid van Moolenbroek 
334*b89261baSDavid van Moolenbroek     /* get vmker structure */
335*b89261baSDavid van Moolenbroek     getkval(vmker_offset, (caddr_t)&m_info, sizeof m_info, "vmker");
336*b89261baSDavid van Moolenbroek #else
337*b89261baSDavid van Moolenbroek     /* cpu stats */
338*b89261baSDavid van Moolenbroek     perfstat_cpu_total(NULL, &s_info1, sizeof s_info1, 1);
339*b89261baSDavid van Moolenbroek 
340*b89261baSDavid van Moolenbroek     /* memory stats */
341*b89261baSDavid van Moolenbroek     perfstat_memory_total(NULL, &m_info1, sizeof m_info1, 1);
342*b89261baSDavid van Moolenbroek #endif
343*b89261baSDavid van Moolenbroek 
344*b89261baSDavid van Moolenbroek 
345*b89261baSDavid van Moolenbroek #ifdef OLD
346*b89261baSDavid van Moolenbroek     /* convert load avarages to doubles */
347*b89261baSDavid van Moolenbroek     for (i = 0; i < 3; i++)
348*b89261baSDavid van Moolenbroek 	si->load_avg[i] = (double)load_avg[i]/65536.0;
349*b89261baSDavid van Moolenbroek 
350*b89261baSDavid van Moolenbroek     /* calculate cpu state in percentages */
351*b89261baSDavid van Moolenbroek     for (i = 0; i < CPU_NTIMES; i++) {
352*b89261baSDavid van Moolenbroek 	cp_old[i] = cp_time[i];
353*b89261baSDavid van Moolenbroek 	cp_time[i] = s_info.cpu[i];
354*b89261baSDavid van Moolenbroek 	cp_diff[i] = cp_time[i] - cp_old[i];
355*b89261baSDavid van Moolenbroek 	total += cp_diff[i];
356*b89261baSDavid van Moolenbroek     }
357*b89261baSDavid van Moolenbroek 
358*b89261baSDavid van Moolenbroek #else
359*b89261baSDavid van Moolenbroek     /* convert load avarages to doubles */
360*b89261baSDavid van Moolenbroek     for (i = 0; i < 3; i++)
361*b89261baSDavid van Moolenbroek         si->load_avg[i] = (double)s_info1.loadavg[i]/(1<<SBITS);
362*b89261baSDavid van Moolenbroek 
363*b89261baSDavid van Moolenbroek     /* calculate cpu state in percentages */
364*b89261baSDavid van Moolenbroek     for (i = 0; i < CPU_NTIMES; i++) {
365*b89261baSDavid van Moolenbroek 	cp_old[i] = cp_time[i];
366*b89261baSDavid van Moolenbroek 	cp_time[i] = (	i==CPU_IDLE?s_info1.idle:
367*b89261baSDavid van Moolenbroek 			i==CPU_USER?s_info1.user:
368*b89261baSDavid van Moolenbroek 			i==CPU_KERNEL?s_info1.sys:
369*b89261baSDavid van Moolenbroek 			i==CPU_WAIT?s_info1.wait:0);
370*b89261baSDavid van Moolenbroek 	cp_diff[i] = cp_time[i] - cp_old[i];
371*b89261baSDavid van Moolenbroek 	total += cp_diff[i];
372*b89261baSDavid van Moolenbroek     }
373*b89261baSDavid van Moolenbroek #endif
374*b89261baSDavid van Moolenbroek     for (i = 0; i < CPU_NTIMES; i++) {
375*b89261baSDavid van Moolenbroek         cpu_states[i] = 1000 * cp_diff[i] / total;
376*b89261baSDavid van Moolenbroek     }
377*b89261baSDavid van Moolenbroek 
378*b89261baSDavid van Moolenbroek     /* calculate memory statistics, scale 4K pages */
379*b89261baSDavid van Moolenbroek #ifdef OLD
380*b89261baSDavid van Moolenbroek #define PAGE_TO_MB(a) ((a)*4/1024)
381*b89261baSDavid van Moolenbroek     memory_stats[M_TOTAL]    = PAGE_TO_MB(m_info.totalmem+m_info.totalvmem);
382*b89261baSDavid van Moolenbroek     memory_stats[M_REAL]     = PAGE_TO_MB(m_info.totalmem);
383*b89261baSDavid van Moolenbroek     memory_stats[M_REALFREE] = PAGE_TO_MB(m_info.freemem);
384*b89261baSDavid van Moolenbroek     memory_stats[M_BUFFERS]  = PAGE_TO_MB(m_info.numperm);
385*b89261baSDavid van Moolenbroek     swap_stats[M_VIRTUAL]  = PAGE_TO_MB(m_info.totalvmem);
386*b89261baSDavid van Moolenbroek     swap_stats[M_VIRTFREE] = PAGE_TO_MB(m_info.freevmem);
387*b89261baSDavid van Moolenbroek #else
388*b89261baSDavid van Moolenbroek #define PAGE_TO_KB(a) ((a)*4)
389*b89261baSDavid van Moolenbroek     memory_stats[M_REAL] = PAGE_TO_KB(m_info1.real_total);
390*b89261baSDavid van Moolenbroek     memory_stats[M_BUFFERS] = PAGE_TO_KB(m_info1.numperm);
391*b89261baSDavid van Moolenbroek #ifdef _AIXVERSION_520
392*b89261baSDavid van Moolenbroek     memory_stats[M_SYSTEM] = PAGE_TO_KB(m_info1.real_system);
393*b89261baSDavid van Moolenbroek #endif
394*b89261baSDavid van Moolenbroek     memory_stats[M_REALFREE] = PAGE_TO_KB(m_info1.real_free);
395*b89261baSDavid van Moolenbroek     swap_stats[M_VIRTUAL] = PAGE_TO_KB(m_info1.pgsp_total);
396*b89261baSDavid van Moolenbroek     swap_stats[M_VIRTFREE] = PAGE_TO_KB(m_info1.pgsp_free);
397*b89261baSDavid van Moolenbroek #endif
398*b89261baSDavid van Moolenbroek 
399*b89261baSDavid van Moolenbroek     /* runnable processes */
400*b89261baSDavid van Moolenbroek #ifdef OLD
401*b89261baSDavid van Moolenbroek     process_states[0] = s_info.runque - old_runque;
402*b89261baSDavid van Moolenbroek     old_runque = s_info.runque;
403*b89261baSDavid van Moolenbroek #else
404*b89261baSDavid van Moolenbroek     process_states[0] = s_info1.runque - old_runque;
405*b89261baSDavid van Moolenbroek     old_runque = s_info1.runque;
406*b89261baSDavid van Moolenbroek #endif
407*b89261baSDavid van Moolenbroek 
408*b89261baSDavid van Moolenbroek     si->cpustates = cpu_states;
409*b89261baSDavid van Moolenbroek     si->memory = memory_stats;
410*b89261baSDavid van Moolenbroek     si->swap = swap_stats;
411*b89261baSDavid van Moolenbroek }
412*b89261baSDavid van Moolenbroek 
413*b89261baSDavid van Moolenbroek static struct handle handle;
414*b89261baSDavid van Moolenbroek 
get_process_info(si,sel,compare_index)415*b89261baSDavid van Moolenbroek caddr_t get_process_info(si, sel, compare_index)
416*b89261baSDavid van Moolenbroek     struct system_info *si;
417*b89261baSDavid van Moolenbroek     struct process_select *sel;
418*b89261baSDavid van Moolenbroek     int compare_index;
419*b89261baSDavid van Moolenbroek {
420*b89261baSDavid van Moolenbroek     int i, nproc;
421*b89261baSDavid van Moolenbroek     int active_procs = 0, total_procs = 0;
422*b89261baSDavid van Moolenbroek     struct procentry64 *pp, **p_pref = pref;
423*b89261baSDavid van Moolenbroek     struct timeval64 *cpu_proc_temp;
424*b89261baSDavid van Moolenbroek     double timediff;
425*b89261baSDavid van Moolenbroek     pid_t procsindex = 0;
426*b89261baSDavid van Moolenbroek 
427*b89261baSDavid van Moolenbroek     si->procstates = process_states;
428*b89261baSDavid van Moolenbroek 
429*b89261baSDavid van Moolenbroek     curtime = time(0);
430*b89261baSDavid van Moolenbroek     lasttimeval = curtimeval;
431*b89261baSDavid van Moolenbroek     gettimeofday(&curtimeval, NULL);
432*b89261baSDavid van Moolenbroek 
433*b89261baSDavid van Moolenbroek     /* get the procentry64 structures of all running processes */
434*b89261baSDavid van Moolenbroek     nproc = getprocs64(p_info, sizeof (struct procentry64), NULL, 0,
435*b89261baSDavid van Moolenbroek                        &procsindex, nprocs);
436*b89261baSDavid van Moolenbroek     if (nproc < 0) {
437*b89261baSDavid van Moolenbroek 	perror("getprocs64");
438*b89261baSDavid van Moolenbroek 	quit(1);
439*b89261baSDavid van Moolenbroek     }
440*b89261baSDavid van Moolenbroek 
441*b89261baSDavid van Moolenbroek     /* the swapper has no cmd-line attached */
442*b89261baSDavid van Moolenbroek     strcpy(p_info[0].pi_comm, "swapper");
443*b89261baSDavid van Moolenbroek 
444*b89261baSDavid van Moolenbroek     if (lasttimeval.tv_sec)
445*b89261baSDavid van Moolenbroek     {
446*b89261baSDavid van Moolenbroek         timediff = (curtimeval.tv_sec - lasttimeval.tv_sec) +
447*b89261baSDavid van Moolenbroek                    1.0*(curtimeval.tv_usec - lasttimeval.tv_usec) / uS_PER_SECOND;
448*b89261baSDavid van Moolenbroek     }
449*b89261baSDavid van Moolenbroek 
450*b89261baSDavid van Moolenbroek     /* The pi_cpu value is wildly inaccurate.  The maximum value is 120, but
451*b89261baSDavid van Moolenbroek        when the scheduling timer fires, the field is zeroed for all
452*b89261baSDavid van Moolenbroek        processes and ramps up over a short period of time.  Instead of using
453*b89261baSDavid van Moolenbroek        this weird number, manually calculate an accurate value from the
454*b89261baSDavid van Moolenbroek        rusage data.  Store this run's rusage in cpu_proc[pid], and subtract
455*b89261baSDavid van Moolenbroek        from old_cpu_proc.
456*b89261baSDavid van Moolenbroek     */
457*b89261baSDavid van Moolenbroek     for (pp = p_info, i = 0; i < nproc; pp++, i++) {
458*b89261baSDavid van Moolenbroek         pid_t pid = PROCMASK(pp->pi_pid);
459*b89261baSDavid van Moolenbroek 
460*b89261baSDavid van Moolenbroek         /* total system and user time into cpu_proc */
461*b89261baSDavid van Moolenbroek         cpu_proc[pid] = pp->pi_ru.ru_utime;
462*b89261baSDavid van Moolenbroek         cpu_proc[pid].tv_sec += pp->pi_ru.ru_stime.tv_sec;
463*b89261baSDavid van Moolenbroek         cpu_proc[pid].tv_usec += pp->pi_ru.ru_stime.tv_usec;
464*b89261baSDavid van Moolenbroek         if (cpu_proc[pid].tv_usec > NS_PER_SEC) {
465*b89261baSDavid van Moolenbroek             cpu_proc[pid].tv_sec++;
466*b89261baSDavid van Moolenbroek             cpu_proc[pid].tv_usec -= NS_PER_SEC;
467*b89261baSDavid van Moolenbroek         }
468*b89261baSDavid van Moolenbroek 
469*b89261baSDavid van Moolenbroek         /* If this process was around during the previous update, calculate
470*b89261baSDavid van Moolenbroek            a true %CPU.  If not, convert the kernel's cpu value from its
471*b89261baSDavid van Moolenbroek            120-max value to a 10000-max one.
472*b89261baSDavid van Moolenbroek         */
473*b89261baSDavid van Moolenbroek         if (old_cpu_proc[pid].tv_sec == 0 && old_cpu_proc[pid].tv_usec == 0)
474*b89261baSDavid van Moolenbroek             pp->pi_cpu = pp->pi_cpu * 10000 / 120;
475*b89261baSDavid van Moolenbroek         else
476*b89261baSDavid van Moolenbroek             pp->pi_cpu = ((cpu_proc[pid].tv_sec - old_cpu_proc[pid].tv_sec) +
477*b89261baSDavid van Moolenbroek                          1.0*(cpu_proc[pid].tv_usec - old_cpu_proc[pid].tv_usec) / NS_PER_SEC) / timediff * 10000;
478*b89261baSDavid van Moolenbroek     }
479*b89261baSDavid van Moolenbroek 
480*b89261baSDavid van Moolenbroek     /* remember our current values as old_cpu_proc, and zero out cpu_proc
481*b89261baSDavid van Moolenbroek        for the next update cycle */
482*b89261baSDavid van Moolenbroek     memset(old_cpu_proc, 0, sizeof(struct timeval64) * nprocs);
483*b89261baSDavid van Moolenbroek     cpu_proc_temp = cpu_proc;
484*b89261baSDavid van Moolenbroek     cpu_proc = old_cpu_proc;
485*b89261baSDavid van Moolenbroek     old_cpu_proc = cpu_proc_temp;
486*b89261baSDavid van Moolenbroek 
487*b89261baSDavid van Moolenbroek     memset(process_states, 0, sizeof process_states);
488*b89261baSDavid van Moolenbroek 
489*b89261baSDavid van Moolenbroek     /* build a list of pointers to processes to show. */
490*b89261baSDavid van Moolenbroek     for (pp = p_info, i = 0; i < nproc; pp++, i++) {
491*b89261baSDavid van Moolenbroek 
492*b89261baSDavid van Moolenbroek 	/* AIX marks all runnable processes as ACTIVE. We want to know
493*b89261baSDavid van Moolenbroek 	   which processes are sleeping, so check used cpu and adjust status
494*b89261baSDavid van Moolenbroek 	   field accordingly
495*b89261baSDavid van Moolenbroek 	 */
496*b89261baSDavid van Moolenbroek 	if (pp->pi_state == SACTIVE && pp->pi_cpu == 0)
497*b89261baSDavid van Moolenbroek 	    pp->pi_state = SIDL;
498*b89261baSDavid van Moolenbroek 
499*b89261baSDavid van Moolenbroek         if (pp->pi_state && (sel->system || ((pp->pi_flags & SKPROC) == 0))) {
500*b89261baSDavid van Moolenbroek 	    total_procs++;
501*b89261baSDavid van Moolenbroek 	    process_states[pp->pi_state]++;
502*b89261baSDavid van Moolenbroek 	    if ( (pp->pi_state != SZOMB) &&
503*b89261baSDavid van Moolenbroek 		(sel->idle || pp->pi_cpu != 0 || (pp->pi_state == SACTIVE))
504*b89261baSDavid van Moolenbroek 		&& (sel->uid == -1 || pp->pi_uid == (uid_t)sel->uid)) {
505*b89261baSDavid van Moolenbroek                 *p_pref++ = pp;
506*b89261baSDavid van Moolenbroek 		active_procs++;
507*b89261baSDavid van Moolenbroek 	    }
508*b89261baSDavid van Moolenbroek 	}
509*b89261baSDavid van Moolenbroek     }
510*b89261baSDavid van Moolenbroek 
511*b89261baSDavid van Moolenbroek     /* the pref array now holds pointers to the procentry64 structures in
512*b89261baSDavid van Moolenbroek      * the p_info array that were selected for display
513*b89261baSDavid van Moolenbroek      */
514*b89261baSDavid van Moolenbroek 
515*b89261baSDavid van Moolenbroek     /* sort if requested */
516*b89261baSDavid van Moolenbroek     if ( proc_compares[compare_index] != NULL)
517*b89261baSDavid van Moolenbroek 	qsort((char *)pref, active_procs, sizeof (struct procentry64 *),
518*b89261baSDavid van Moolenbroek 	      proc_compares[compare_index]);
519*b89261baSDavid van Moolenbroek 
520*b89261baSDavid van Moolenbroek     si->last_pid = -1;		/* no way to figure out last used pid */
521*b89261baSDavid van Moolenbroek     si->p_total = total_procs;
522*b89261baSDavid van Moolenbroek     si->p_active = pref_len = active_procs;
523*b89261baSDavid van Moolenbroek 
524*b89261baSDavid van Moolenbroek     handle.next_proc = pref;
525*b89261baSDavid van Moolenbroek     handle.remaining = active_procs;
526*b89261baSDavid van Moolenbroek 
527*b89261baSDavid van Moolenbroek     return((caddr_t)&handle);
528*b89261baSDavid van Moolenbroek }
529*b89261baSDavid van Moolenbroek 
530*b89261baSDavid van Moolenbroek char fmt[128];		/* static area where result is built */
531*b89261baSDavid van Moolenbroek 
532*b89261baSDavid van Moolenbroek /* define what weighted cpu is. use definition of %CPU from 'man ps(1)' */
533*b89261baSDavid van Moolenbroek #define weighted_cpu(pp) (PROCTIME(pp) == 0 ? 0.0 : \
534*b89261baSDavid van Moolenbroek                         (((PROCTIME(pp)*100.0)/(curtime-pi->pi_start))))
535*b89261baSDavid van Moolenbroek 
format_next_process(handle,get_userid)536*b89261baSDavid van Moolenbroek char *format_next_process(handle, get_userid)
537*b89261baSDavid van Moolenbroek     caddr_t handle;
538*b89261baSDavid van Moolenbroek     char *(*get_userid)();
539*b89261baSDavid van Moolenbroek {
540*b89261baSDavid van Moolenbroek     register struct handle *hp;
541*b89261baSDavid van Moolenbroek     register struct procentry64 *pi;
542*b89261baSDavid van Moolenbroek     long cpu_time;
543*b89261baSDavid van Moolenbroek     int proc_size, proc_ress;
544*b89261baSDavid van Moolenbroek     char size_unit = 'K';
545*b89261baSDavid van Moolenbroek     char ress_unit = 'K';
546*b89261baSDavid van Moolenbroek 
547*b89261baSDavid van Moolenbroek     hp = (struct handle *)handle;
548*b89261baSDavid van Moolenbroek     if (hp->remaining == 0) {	/* safe guard */
549*b89261baSDavid van Moolenbroek 	fmt[0] = '\0';
550*b89261baSDavid van Moolenbroek 	return fmt;
551*b89261baSDavid van Moolenbroek     }
552*b89261baSDavid van Moolenbroek     pi = *(hp->next_proc++);
553*b89261baSDavid van Moolenbroek     hp->remaining--;
554*b89261baSDavid van Moolenbroek 
555*b89261baSDavid van Moolenbroek     cpu_time = PROCTIME(pi);
556*b89261baSDavid van Moolenbroek 
557*b89261baSDavid van Moolenbroek     /* we disply sizes up to 10M in KiloBytes, beyond 10M in MegaBytes */
558*b89261baSDavid van Moolenbroek     if ((proc_size = (pi->pi_tsize/1024+pi->pi_dvm)*4) > 10240) {
559*b89261baSDavid van Moolenbroek 	proc_size /= 1024;
560*b89261baSDavid van Moolenbroek 	size_unit = 'M';
561*b89261baSDavid van Moolenbroek     }
562*b89261baSDavid van Moolenbroek     if ((proc_ress = (pi->pi_trss + pi->pi_drss)*4) > 10240) {
563*b89261baSDavid van Moolenbroek 	proc_ress /= 1024;
564*b89261baSDavid van Moolenbroek 	ress_unit = 'M';
565*b89261baSDavid van Moolenbroek     }
566*b89261baSDavid van Moolenbroek 
567*b89261baSDavid van Moolenbroek     sprintf(fmt, Proc_format ,
568*b89261baSDavid van Moolenbroek             pi->pi_pid,					  /* PID */
569*b89261baSDavid van Moolenbroek             (*get_userid)(pi->pi_uid),			  /* login name */
570*b89261baSDavid van Moolenbroek 	        pi->pi_nice,				  /* fixed or vari */
571*b89261baSDavid van Moolenbroek             getpriority(PRIO_PROCESS, pi->pi_pid),
572*b89261baSDavid van Moolenbroek             proc_size,					  /* size */
573*b89261baSDavid van Moolenbroek             size_unit,					  /* K or M */
574*b89261baSDavid van Moolenbroek             proc_ress,					  /* resident */
575*b89261baSDavid van Moolenbroek             ress_unit,					  /* K or M */
576*b89261baSDavid van Moolenbroek             state_abbrev[pi->pi_state],			  /* process state */
577*b89261baSDavid van Moolenbroek             format_time(cpu_time),			  /* time used */
578*b89261baSDavid van Moolenbroek             weighted_cpu(pi),	                          /* WCPU */
579*b89261baSDavid van Moolenbroek             pi->pi_cpu / 100.0,                     /* CPU */
580*b89261baSDavid van Moolenbroek             printable(pi->pi_comm),                       /* COMM */
581*b89261baSDavid van Moolenbroek             (pi->pi_flags & SKPROC) == 0 ? "" : " (sys)"  /* kernel process? */
582*b89261baSDavid van Moolenbroek 	    );
583*b89261baSDavid van Moolenbroek     return(fmt);
584*b89261baSDavid van Moolenbroek }
585*b89261baSDavid van Moolenbroek 
586*b89261baSDavid van Moolenbroek #ifdef OLD
587*b89261baSDavid van Moolenbroek /*
588*b89261baSDavid van Moolenbroek  *  getkval(offset, ptr, size, refstr) - get a value out of the kernel.
589*b89261baSDavid van Moolenbroek  *	"offset" is the byte offset into the kernel for the desired value,
590*b89261baSDavid van Moolenbroek  *  	"ptr" points to a buffer into which the value is retrieved,
591*b89261baSDavid van Moolenbroek  *  	"size" is the size of the buffer (and the object to retrieve),
592*b89261baSDavid van Moolenbroek  *  	"refstr" is a reference string used when printing error meessages,
593*b89261baSDavid van Moolenbroek  *	    if "refstr" starts with a '!', then a failure on read will not
594*b89261baSDavid van Moolenbroek  *  	    be fatal (this may seem like a silly way to do things, but I
595*b89261baSDavid van Moolenbroek  *  	    really didn't want the overhead of another argument).
596*b89261baSDavid van Moolenbroek  *
597*b89261baSDavid van Moolenbroek  */
getkval(offset,ptr,size,refstr)598*b89261baSDavid van Moolenbroek int getkval(offset, ptr, size, refstr)
599*b89261baSDavid van Moolenbroek     unsigned long offset;
600*b89261baSDavid van Moolenbroek     caddr_t ptr;
601*b89261baSDavid van Moolenbroek     int size;
602*b89261baSDavid van Moolenbroek     char *refstr;
603*b89261baSDavid van Moolenbroek {
604*b89261baSDavid van Moolenbroek     int upper_2gb = 0;
605*b89261baSDavid van Moolenbroek 
606*b89261baSDavid van Moolenbroek     /* reads above 2Gb are done by seeking to offset%2Gb, and supplying
607*b89261baSDavid van Moolenbroek      * 1 (opposed to 0) as fourth parameter to readx (see 'man kmem')
608*b89261baSDavid van Moolenbroek      */
609*b89261baSDavid van Moolenbroek     if (offset > 1<<31) {
610*b89261baSDavid van Moolenbroek 	upper_2gb = 1;
611*b89261baSDavid van Moolenbroek 	offset &= 0x7fffffff;
612*b89261baSDavid van Moolenbroek     }
613*b89261baSDavid van Moolenbroek 
614*b89261baSDavid van Moolenbroek     if (lseek(kmem, offset, SEEK_SET) != offset) {
615*b89261baSDavid van Moolenbroek 	fprintf(stderr, "top: lseek failed\n");
616*b89261baSDavid van Moolenbroek 	quit(2);
617*b89261baSDavid van Moolenbroek     }
618*b89261baSDavid van Moolenbroek 
619*b89261baSDavid van Moolenbroek     if (readx(kmem, ptr, size, upper_2gb) != size) {
620*b89261baSDavid van Moolenbroek 	if (*refstr == '!')
621*b89261baSDavid van Moolenbroek 	    return 0;
622*b89261baSDavid van Moolenbroek 	else {
623*b89261baSDavid van Moolenbroek 	    fprintf(stderr, "top: kvm_read for %s: %s\n", refstr,
624*b89261baSDavid van Moolenbroek 		    sys_errlist[errno]);
625*b89261baSDavid van Moolenbroek 	    quit(2);
626*b89261baSDavid van Moolenbroek 	}
627*b89261baSDavid van Moolenbroek     }
628*b89261baSDavid van Moolenbroek 
629*b89261baSDavid van Moolenbroek     return 1 ;
630*b89261baSDavid van Moolenbroek }
631*b89261baSDavid van Moolenbroek #endif
632*b89261baSDavid van Moolenbroek 
633*b89261baSDavid van Moolenbroek /* comparison routine for qsort */
634*b89261baSDavid van Moolenbroek /*
635*b89261baSDavid van Moolenbroek  * The following code is taken from the solaris module and adjusted
636*b89261baSDavid van Moolenbroek  * for AIX -- JV .
637*b89261baSDavid van Moolenbroek  */
638*b89261baSDavid van Moolenbroek 
639*b89261baSDavid van Moolenbroek #define ORDERKEY_PCTCPU \
640*b89261baSDavid van Moolenbroek            if ((result = pi2->pi_cpu - pi1->pi_cpu) == 0)
641*b89261baSDavid van Moolenbroek 
642*b89261baSDavid van Moolenbroek #define ORDERKEY_CPTICKS \
643*b89261baSDavid van Moolenbroek            if ((result = PROCTIME(pi2) - PROCTIME(pi1)) == 0)
644*b89261baSDavid van Moolenbroek 
645*b89261baSDavid van Moolenbroek #define ORDERKEY_STATE \
646*b89261baSDavid van Moolenbroek            if ((result = sorted_state[pi2->pi_state]  \
647*b89261baSDavid van Moolenbroek                          - sorted_state[pi1->pi_state])  == 0)
648*b89261baSDavid van Moolenbroek 
649*b89261baSDavid van Moolenbroek /* Nice values directly reflect the process' priority, and are always >0 ;-) */
650*b89261baSDavid van Moolenbroek #define ORDERKEY_PRIO \
651*b89261baSDavid van Moolenbroek 	   if ((result = pi1->pi_nice - pi2->pi_nice) == 0)
652*b89261baSDavid van Moolenbroek #define ORDERKEY_RSSIZE \
653*b89261baSDavid van Moolenbroek            if ((result = PROCRESS(pi2) - PROCRESS(pi1)) == 0)
654*b89261baSDavid van Moolenbroek #define ORDERKEY_MEM \
655*b89261baSDavid van Moolenbroek            if ((result = PROCSIZE(pi2) - PROCSIZE(pi1)) == 0)
656*b89261baSDavid van Moolenbroek 
657*b89261baSDavid van Moolenbroek static unsigned char sorted_state[] =
658*b89261baSDavid van Moolenbroek {
659*b89261baSDavid van Moolenbroek     0,	/* not used */
660*b89261baSDavid van Moolenbroek     0,
661*b89261baSDavid van Moolenbroek     0,
662*b89261baSDavid van Moolenbroek     0,
663*b89261baSDavid van Moolenbroek     3,	/* sleep */
664*b89261baSDavid van Moolenbroek     1,	/* zombie */
665*b89261baSDavid van Moolenbroek     4,	/* stop */
666*b89261baSDavid van Moolenbroek     6,	/* run */
667*b89261baSDavid van Moolenbroek     2,	/* swap */
668*b89261baSDavid van Moolenbroek };
669*b89261baSDavid van Moolenbroek 
670*b89261baSDavid van Moolenbroek /* compare_cpu - the comparison function for sorting by cpu percentage */
671*b89261baSDavid van Moolenbroek 
672*b89261baSDavid van Moolenbroek int
compare_cpu(ppi1,ppi2)673*b89261baSDavid van Moolenbroek compare_cpu(ppi1, ppi2)
674*b89261baSDavid van Moolenbroek     struct procentry64 **ppi1;
675*b89261baSDavid van Moolenbroek     struct procentry64 **ppi2;
676*b89261baSDavid van Moolenbroek {
677*b89261baSDavid van Moolenbroek     register struct procentry64 *pi1 = *ppi1, *pi2 = *ppi2;
678*b89261baSDavid van Moolenbroek     register int result;
679*b89261baSDavid van Moolenbroek 
680*b89261baSDavid van Moolenbroek     ORDERKEY_PCTCPU
681*b89261baSDavid van Moolenbroek     ORDERKEY_CPTICKS
682*b89261baSDavid van Moolenbroek     ORDERKEY_STATE
683*b89261baSDavid van Moolenbroek     ORDERKEY_PRIO
684*b89261baSDavid van Moolenbroek     ORDERKEY_RSSIZE
685*b89261baSDavid van Moolenbroek     ORDERKEY_MEM
686*b89261baSDavid van Moolenbroek     ;
687*b89261baSDavid van Moolenbroek 
688*b89261baSDavid van Moolenbroek     return result;
689*b89261baSDavid van Moolenbroek }
690*b89261baSDavid van Moolenbroek 
691*b89261baSDavid van Moolenbroek 
692*b89261baSDavid van Moolenbroek /* compare_size - the comparison function for sorting by total memory usage */
693*b89261baSDavid van Moolenbroek 
694*b89261baSDavid van Moolenbroek int
compare_size(ppi1,ppi2)695*b89261baSDavid van Moolenbroek compare_size(ppi1, ppi2)
696*b89261baSDavid van Moolenbroek     struct procentry64 **ppi1;
697*b89261baSDavid van Moolenbroek     struct procentry64 **ppi2;
698*b89261baSDavid van Moolenbroek {
699*b89261baSDavid van Moolenbroek     register struct procentry64 *pi1 = *ppi1, *pi2 = *ppi2;
700*b89261baSDavid van Moolenbroek     register int result;
701*b89261baSDavid van Moolenbroek 
702*b89261baSDavid van Moolenbroek     ORDERKEY_MEM
703*b89261baSDavid van Moolenbroek     ORDERKEY_RSSIZE
704*b89261baSDavid van Moolenbroek     ORDERKEY_PCTCPU
705*b89261baSDavid van Moolenbroek     ORDERKEY_CPTICKS
706*b89261baSDavid van Moolenbroek     ORDERKEY_STATE
707*b89261baSDavid van Moolenbroek     ORDERKEY_PRIO
708*b89261baSDavid van Moolenbroek     ;
709*b89261baSDavid van Moolenbroek 
710*b89261baSDavid van Moolenbroek     return result;
711*b89261baSDavid van Moolenbroek }
712*b89261baSDavid van Moolenbroek 
713*b89261baSDavid van Moolenbroek 
714*b89261baSDavid van Moolenbroek /* compare_res - the comparison function for sorting by resident set size */
715*b89261baSDavid van Moolenbroek 
716*b89261baSDavid van Moolenbroek int
compare_res(ppi1,ppi2)717*b89261baSDavid van Moolenbroek compare_res(ppi1, ppi2)
718*b89261baSDavid van Moolenbroek     struct procentry64 **ppi1;
719*b89261baSDavid van Moolenbroek     struct procentry64 **ppi2;
720*b89261baSDavid van Moolenbroek {
721*b89261baSDavid van Moolenbroek     register struct procentry64 *pi1 = *ppi1, *pi2 = *ppi2;
722*b89261baSDavid van Moolenbroek     register int result;
723*b89261baSDavid van Moolenbroek 
724*b89261baSDavid van Moolenbroek     ORDERKEY_RSSIZE
725*b89261baSDavid van Moolenbroek     ORDERKEY_MEM
726*b89261baSDavid van Moolenbroek     ORDERKEY_PCTCPU
727*b89261baSDavid van Moolenbroek     ORDERKEY_CPTICKS
728*b89261baSDavid van Moolenbroek     ORDERKEY_STATE
729*b89261baSDavid van Moolenbroek     ORDERKEY_PRIO
730*b89261baSDavid van Moolenbroek     ;
731*b89261baSDavid van Moolenbroek 
732*b89261baSDavid van Moolenbroek     return result;
733*b89261baSDavid van Moolenbroek }
734*b89261baSDavid van Moolenbroek 
735*b89261baSDavid van Moolenbroek 
736*b89261baSDavid van Moolenbroek /* compare_time - the comparison function for sorting by total cpu time */
737*b89261baSDavid van Moolenbroek 
738*b89261baSDavid van Moolenbroek int
compare_time(ppi1,ppi2)739*b89261baSDavid van Moolenbroek compare_time(ppi1, ppi2)
740*b89261baSDavid van Moolenbroek     struct procentry64 **ppi1;
741*b89261baSDavid van Moolenbroek     struct procentry64 **ppi2;
742*b89261baSDavid van Moolenbroek {
743*b89261baSDavid van Moolenbroek     register struct procentry64 *pi1 = *ppi1, *pi2 = *ppi2;
744*b89261baSDavid van Moolenbroek     register int result;
745*b89261baSDavid van Moolenbroek 
746*b89261baSDavid van Moolenbroek     ORDERKEY_CPTICKS
747*b89261baSDavid van Moolenbroek     ORDERKEY_PCTCPU
748*b89261baSDavid van Moolenbroek     ORDERKEY_STATE
749*b89261baSDavid van Moolenbroek     ORDERKEY_PRIO
750*b89261baSDavid van Moolenbroek     ORDERKEY_MEM
751*b89261baSDavid van Moolenbroek     ORDERKEY_RSSIZE
752*b89261baSDavid van Moolenbroek     ;
753*b89261baSDavid van Moolenbroek 
754*b89261baSDavid van Moolenbroek     return result;
755*b89261baSDavid van Moolenbroek }
756*b89261baSDavid van Moolenbroek 
757*b89261baSDavid van Moolenbroek 
758*b89261baSDavid van Moolenbroek /* compare_prio - the comparison function for sorting by cpu percentage */
759*b89261baSDavid van Moolenbroek 
760*b89261baSDavid van Moolenbroek int
compare_prio(ppi1,ppi2)761*b89261baSDavid van Moolenbroek compare_prio(ppi1, ppi2)
762*b89261baSDavid van Moolenbroek     struct procentry64 **ppi1;
763*b89261baSDavid van Moolenbroek     struct procentry64 **ppi2;
764*b89261baSDavid van Moolenbroek {
765*b89261baSDavid van Moolenbroek     register struct procentry64 *pi1 = *ppi1, *pi2 = *ppi2;
766*b89261baSDavid van Moolenbroek     register int result;
767*b89261baSDavid van Moolenbroek 
768*b89261baSDavid van Moolenbroek     ORDERKEY_PRIO
769*b89261baSDavid van Moolenbroek     ORDERKEY_PCTCPU
770*b89261baSDavid van Moolenbroek     ORDERKEY_CPTICKS
771*b89261baSDavid van Moolenbroek     ORDERKEY_STATE
772*b89261baSDavid van Moolenbroek     ORDERKEY_RSSIZE
773*b89261baSDavid van Moolenbroek     ORDERKEY_MEM
774*b89261baSDavid van Moolenbroek     ;
775*b89261baSDavid van Moolenbroek 
776*b89261baSDavid van Moolenbroek     return result;
777*b89261baSDavid van Moolenbroek }
778*b89261baSDavid van Moolenbroek 
779*b89261baSDavid van Moolenbroek 
proc_owner(pid)780*b89261baSDavid van Moolenbroek int proc_owner(pid)
781*b89261baSDavid van Moolenbroek int pid;
782*b89261baSDavid van Moolenbroek {
783*b89261baSDavid van Moolenbroek    register struct procentry64 **prefp = pref;
784*b89261baSDavid van Moolenbroek    register int cnt = pref_len;
785*b89261baSDavid van Moolenbroek 
786*b89261baSDavid van Moolenbroek    while (--cnt >= 0) {
787*b89261baSDavid van Moolenbroek        if ((*prefp)->pi_pid == pid)
788*b89261baSDavid van Moolenbroek 	   return (*prefp)->pi_uid;
789*b89261baSDavid van Moolenbroek        prefp++;
790*b89261baSDavid van Moolenbroek    }
791*b89261baSDavid van Moolenbroek 
792*b89261baSDavid van Moolenbroek    return(-1);
793*b89261baSDavid van Moolenbroek }
794