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 4.2 or higher
37*b89261baSDavid van Moolenbroek *
38*b89261baSDavid van Moolenbroek * DESCRIPTION:
39*b89261baSDavid van Moolenbroek * This is the machine-dependent module for AIX 4.2 and higher
40*b89261baSDavid van Moolenbroek * It is currenlty only tested on PowerPC architectures.
41*b89261baSDavid van Moolenbroek *
42*b89261baSDavid van Moolenbroek * TERMCAP: -lcurses
43*b89261baSDavid van Moolenbroek *
44*b89261baSDavid van Moolenbroek * CFLAGS: -DORDER -DHAVE_GETOPT
45*b89261baSDavid van Moolenbroek *
46*b89261baSDavid van Moolenbroek * LIBS: -bD:0x18000000
47*b89261baSDavid van Moolenbroek *
48*b89261baSDavid van Moolenbroek * AUTHOR: Joep Vesseur <joep@fwi.uva.nl>
49*b89261baSDavid van Moolenbroek *
50*b89261baSDavid van Moolenbroek * PATCHES: Antoine Tabary <tabary@bruyeres.cea.fr>
51*b89261baSDavid van Moolenbroek */
52*b89261baSDavid van Moolenbroek
53*b89261baSDavid van Moolenbroek #include "config.h"
54*b89261baSDavid van Moolenbroek
55*b89261baSDavid van Moolenbroek #include <stdlib.h>
56*b89261baSDavid van Moolenbroek #include <stdio.h>
57*b89261baSDavid van Moolenbroek #include <fcntl.h>
58*b89261baSDavid van Moolenbroek #include <nlist.h>
59*b89261baSDavid van Moolenbroek #include <sys/sysinfo.h>
60*b89261baSDavid van Moolenbroek #include <procinfo.h>
61*b89261baSDavid van Moolenbroek #include <sys/proc.h>
62*b89261baSDavid van Moolenbroek #include <sys/times.h>
63*b89261baSDavid van Moolenbroek #include <sys/param.h>
64*b89261baSDavid van Moolenbroek #include <pwd.h>
65*b89261baSDavid van Moolenbroek #include "top.h"
66*b89261baSDavid van Moolenbroek #include "machine.h"
67*b89261baSDavid van Moolenbroek #include "utils.h"
68*b89261baSDavid van Moolenbroek
69*b89261baSDavid van Moolenbroek
70*b89261baSDavid van Moolenbroek #define PROCRESS(p) (((p)->pi_trss + (p)->pi_drss)*4)
71*b89261baSDavid van Moolenbroek #define PROCSIZE(p) (((p)->pi_tsize/1024+(p)->pi_dvm)*4)
72*b89261baSDavid van Moolenbroek #define PROCTIME(pi) (pi->pi_ru.ru_utime.tv_sec + pi->pi_ru.ru_stime.tv_sec)
73*b89261baSDavid van Moolenbroek
74*b89261baSDavid van Moolenbroek
75*b89261baSDavid van Moolenbroek /*
76*b89261baSDavid van Moolenbroek * structure definition taken from 'monitor' by Jussi Maki (jmaki@hut.fi)
77*b89261baSDavid van Moolenbroek */
78*b89261baSDavid van Moolenbroek struct vmker {
79*b89261baSDavid van Moolenbroek uint n0,n1,n2,n3,n4,n5,n6,n7,n8;
80*b89261baSDavid van Moolenbroek uint totalmem;
81*b89261baSDavid van Moolenbroek uint badmem; /* this is used in RS/6000 model 220 */
82*b89261baSDavid van Moolenbroek uint freemem;
83*b89261baSDavid van Moolenbroek uint n12;
84*b89261baSDavid van Moolenbroek uint numperm; /* this seems to keep other than text and data segment
85*b89261baSDavid van Moolenbroek usage; name taken from /usr/lpp/bos/samples/vmtune.c */
86*b89261baSDavid van Moolenbroek uint totalvmem,freevmem;
87*b89261baSDavid van Moolenbroek uint n15, n16, n17, n18, n19;
88*b89261baSDavid van Moolenbroek };
89*b89261baSDavid van Moolenbroek
90*b89261baSDavid van Moolenbroek
91*b89261baSDavid van Moolenbroek #define KMEM "/dev/kmem"
92*b89261baSDavid van Moolenbroek
93*b89261baSDavid van Moolenbroek /* Indices in the nlist array */
94*b89261baSDavid van Moolenbroek #define X_AVENRUN 0
95*b89261baSDavid van Moolenbroek #define X_SYSINFO 1
96*b89261baSDavid van Moolenbroek #define X_VMKER 2
97*b89261baSDavid van Moolenbroek #define X_PROC 3
98*b89261baSDavid van Moolenbroek #define X_V 4
99*b89261baSDavid van Moolenbroek
100*b89261baSDavid van Moolenbroek static struct nlist nlst[] = {
101*b89261baSDavid van Moolenbroek { "avenrun", 0, 0, 0, 0, 0 }, /* 0 */
102*b89261baSDavid van Moolenbroek { "sysinfo", 0, 0, 0, 0, 0 }, /* 1 */
103*b89261baSDavid van Moolenbroek { "vmker", 0, 0, 0, 0, 0 }, /* 2 */
104*b89261baSDavid van Moolenbroek { "proc", 0, 0, 0, 0, 0 }, /* 3 */
105*b89261baSDavid van Moolenbroek { "v", 0, 0, 0, 0, 0 }, /* 4 */
106*b89261baSDavid van Moolenbroek { NULL, 0, 0, 0, 0, 0 }
107*b89261baSDavid van Moolenbroek };
108*b89261baSDavid van Moolenbroek
109*b89261baSDavid van Moolenbroek
110*b89261baSDavid van Moolenbroek /* get_process_info returns handle. definition is here */
111*b89261baSDavid van Moolenbroek struct handle
112*b89261baSDavid van Moolenbroek {
113*b89261baSDavid van Moolenbroek struct procsinfo **next_proc;
114*b89261baSDavid van Moolenbroek int remaining;
115*b89261baSDavid van Moolenbroek };
116*b89261baSDavid van Moolenbroek
117*b89261baSDavid van Moolenbroek /*
118*b89261baSDavid van Moolenbroek * These definitions control the format of the per-process area
119*b89261baSDavid van Moolenbroek */
120*b89261baSDavid van Moolenbroek static char header[] =
121*b89261baSDavid van Moolenbroek " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND";
122*b89261baSDavid van Moolenbroek /* 0123456 -- field to fill in starts at header+6 */
123*b89261baSDavid van Moolenbroek #define UNAME_START 7
124*b89261baSDavid van Moolenbroek
125*b89261baSDavid van Moolenbroek #define Proc_format \
126*b89261baSDavid van Moolenbroek "%6d %-8.8s %3d %4d %5d%c %4d%c %-5s %6s %5.2f%% %5.2f%% %.14s%s"
127*b89261baSDavid van Moolenbroek
128*b89261baSDavid van Moolenbroek
129*b89261baSDavid van Moolenbroek /* these are for detailing the process states */
130*b89261baSDavid van Moolenbroek int process_states[9];
131*b89261baSDavid van Moolenbroek char *procstatenames[] = {
132*b89261baSDavid van Moolenbroek " none, ", " sleeping, ", " state2, ", " runnable, ",
133*b89261baSDavid van Moolenbroek " idle, ", " zombie, ", " stopped, ", " running, ", " swapped, ",
134*b89261baSDavid van Moolenbroek NULL
135*b89261baSDavid van Moolenbroek };
136*b89261baSDavid van Moolenbroek
137*b89261baSDavid van Moolenbroek
138*b89261baSDavid van Moolenbroek /* these are for detailing the cpu states */
139*b89261baSDavid van Moolenbroek int cpu_states[4];
140*b89261baSDavid van Moolenbroek char *cpustatenames[] = {
141*b89261baSDavid van Moolenbroek "idle", "user", "kernel", "wait",
142*b89261baSDavid van Moolenbroek NULL
143*b89261baSDavid van Moolenbroek };
144*b89261baSDavid van Moolenbroek
145*b89261baSDavid van Moolenbroek /* these are for detailing the memory statistics */
146*b89261baSDavid van Moolenbroek long memory_stats[4];
147*b89261baSDavid van Moolenbroek char *memorynames[] = {
148*b89261baSDavid van Moolenbroek "K Total, ", "K Free, ", "K Buffers", NULL
149*b89261baSDavid van Moolenbroek };
150*b89261baSDavid van Moolenbroek #define M_REAL 0
151*b89261baSDavid van Moolenbroek #define M_REALFREE 1
152*b89261baSDavid van Moolenbroek #define M_BUFFERS 2
153*b89261baSDavid van Moolenbroek
154*b89261baSDavid van Moolenbroek long swap_stats[3];
155*b89261baSDavid van Moolenbroek char *swapnames[] = {
156*b89261baSDavid van Moolenbroek "K Total, ", "K Free", NULL
157*b89261baSDavid van Moolenbroek };
158*b89261baSDavid van Moolenbroek
159*b89261baSDavid van Moolenbroek #define M_VIRTUAL 0
160*b89261baSDavid van Moolenbroek #define M_VIRTFREE 1
161*b89261baSDavid van Moolenbroek
162*b89261baSDavid van Moolenbroek char *state_abbrev[] = {
163*b89261baSDavid van Moolenbroek "", "sleep", "", "", "sleep", "zomb", "stop", "run", "swap"
164*b89261baSDavid van Moolenbroek };
165*b89261baSDavid van Moolenbroek
166*b89261baSDavid van Moolenbroek /* sorting orders. first is default */
167*b89261baSDavid van Moolenbroek char *ordernames[] = {
168*b89261baSDavid van Moolenbroek "cpu", "size", "res", "time", "pri", NULL
169*b89261baSDavid van Moolenbroek };
170*b89261baSDavid van Moolenbroek
171*b89261baSDavid van Moolenbroek /* compare routines */
172*b89261baSDavid van Moolenbroek int compare_cpu(), compare_size(), compare_res(), compare_time(),
173*b89261baSDavid van Moolenbroek compare_prio();
174*b89261baSDavid van Moolenbroek
175*b89261baSDavid van Moolenbroek int (*proc_compares[])() = {
176*b89261baSDavid van Moolenbroek compare_cpu,
177*b89261baSDavid van Moolenbroek compare_size,
178*b89261baSDavid van Moolenbroek compare_res,
179*b89261baSDavid van Moolenbroek compare_time,
180*b89261baSDavid van Moolenbroek compare_prio,
181*b89261baSDavid van Moolenbroek NULL
182*b89261baSDavid van Moolenbroek };
183*b89261baSDavid van Moolenbroek
184*b89261baSDavid van Moolenbroek /* useful externals */
185*b89261baSDavid van Moolenbroek extern int errno;
186*b89261baSDavid van Moolenbroek extern char *sys_errlist[];
187*b89261baSDavid van Moolenbroek long lseek();
188*b89261baSDavid van Moolenbroek long time();
189*b89261baSDavid van Moolenbroek long percentages();
190*b89261baSDavid van Moolenbroek
191*b89261baSDavid van Moolenbroek
192*b89261baSDavid van Moolenbroek /* useful globals */
193*b89261baSDavid van Moolenbroek int kmem; /* file descriptor */
194*b89261baSDavid van Moolenbroek
195*b89261baSDavid van Moolenbroek /* offsets in kernel */
196*b89261baSDavid van Moolenbroek static unsigned long avenrun_offset;
197*b89261baSDavid van Moolenbroek static unsigned long sysinfo_offset;
198*b89261baSDavid van Moolenbroek static unsigned long vmker_offset;
199*b89261baSDavid van Moolenbroek static unsigned long proc_offset;
200*b89261baSDavid van Moolenbroek static unsigned long v_offset;
201*b89261baSDavid van Moolenbroek
202*b89261baSDavid van Moolenbroek /* used for calculating cpu state percentages */
203*b89261baSDavid van Moolenbroek static long cp_time[CPU_NTIMES];
204*b89261baSDavid van Moolenbroek static long cp_old[CPU_NTIMES];
205*b89261baSDavid van Moolenbroek static long cp_diff[CPU_NTIMES];
206*b89261baSDavid van Moolenbroek
207*b89261baSDavid van Moolenbroek /* the runqueue length is a cumulative value. keep old value */
208*b89261baSDavid van Moolenbroek long old_runque;
209*b89261baSDavid van Moolenbroek
210*b89261baSDavid van Moolenbroek /* process info */
211*b89261baSDavid van Moolenbroek struct var v_info; /* to determine nprocs */
212*b89261baSDavid van Moolenbroek int nprocs; /* maximum nr of procs in proctab */
213*b89261baSDavid van Moolenbroek int ncpus; /* nr of cpus installed */
214*b89261baSDavid van Moolenbroek
215*b89261baSDavid van Moolenbroek int ptsize; /* size of process table in bytes */
216*b89261baSDavid van Moolenbroek struct proc *p_proc; /* a copy of the process table */
217*b89261baSDavid van Moolenbroek struct procsinfo *p_info; /* needed for vm and ru info */
218*b89261baSDavid van Moolenbroek struct procsinfo **pref; /* processes selected for display */
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
225*b89261baSDavid van Moolenbroek /*
226*b89261baSDavid van Moolenbroek * Initialize globals, get kernel offsets and stuff...
227*b89261baSDavid van Moolenbroek */
machine_init(struct statics * statics)228*b89261baSDavid van Moolenbroek machine_init(struct statics *statics)
229*b89261baSDavid van Moolenbroek
230*b89261baSDavid van Moolenbroek {
231*b89261baSDavid van Moolenbroek time_t uptime, now;
232*b89261baSDavid van Moolenbroek struct tms tbuf;
233*b89261baSDavid van Moolenbroek
234*b89261baSDavid van Moolenbroek if ((kmem = open(KMEM, O_RDONLY)) == -1) {
235*b89261baSDavid van Moolenbroek perror(KMEM);
236*b89261baSDavid van Moolenbroek return -1;
237*b89261baSDavid van Moolenbroek }
238*b89261baSDavid van Moolenbroek
239*b89261baSDavid van Moolenbroek /* get kernel symbol offsets */
240*b89261baSDavid van Moolenbroek if (knlist(nlst, 5, sizeof(struct nlist)) != 0) {
241*b89261baSDavid van Moolenbroek perror("knlist");
242*b89261baSDavid van Moolenbroek return -1;
243*b89261baSDavid van Moolenbroek }
244*b89261baSDavid van Moolenbroek avenrun_offset = nlst[X_AVENRUN].n_value;
245*b89261baSDavid van Moolenbroek sysinfo_offset = nlst[X_SYSINFO].n_value;
246*b89261baSDavid van Moolenbroek vmker_offset = nlst[X_VMKER].n_value;
247*b89261baSDavid van Moolenbroek proc_offset = nlst[X_PROC].n_value;
248*b89261baSDavid van Moolenbroek v_offset = nlst[X_V].n_value;
249*b89261baSDavid van Moolenbroek
250*b89261baSDavid van Moolenbroek getkval(v_offset, (caddr_t)&v_info, sizeof v_info, "v");
251*b89261baSDavid van Moolenbroek
252*b89261baSDavid van Moolenbroek ncpus = v_info.v_ncpus; /* number of cpus */
253*b89261baSDavid van Moolenbroek nprocs = PROCMASK(PIDMAX);
254*b89261baSDavid van Moolenbroek if (nprocs > 1024) nprocs = 1024;
255*b89261baSDavid van Moolenbroek
256*b89261baSDavid van Moolenbroek ptsize = nprocs * sizeof (struct proc);
257*b89261baSDavid van Moolenbroek p_proc = (struct proc *)malloc(ptsize);
258*b89261baSDavid van Moolenbroek p_info = (struct procsinfo *)malloc(nprocs * sizeof (struct procsinfo));
259*b89261baSDavid van Moolenbroek pref = (struct procsinfo **)malloc(nprocs * sizeof (struct procsinfo *));
260*b89261baSDavid van Moolenbroek
261*b89261baSDavid van Moolenbroek if (!p_proc || !p_info || !pref) {
262*b89261baSDavid van Moolenbroek fprintf(stderr, "top: not enough memory\n");
263*b89261baSDavid van Moolenbroek return -1;
264*b89261baSDavid van Moolenbroek }
265*b89261baSDavid van Moolenbroek
266*b89261baSDavid van Moolenbroek /* set boot time */
267*b89261baSDavid van Moolenbroek now = time(NULL);
268*b89261baSDavid van Moolenbroek uptime = times(&tbuf) / HZ;
269*b89261baSDavid van Moolenbroek statics->boottime = now - uptime;
270*b89261baSDavid van Moolenbroek
271*b89261baSDavid van Moolenbroek statics->procstate_names = procstatenames;
272*b89261baSDavid van Moolenbroek statics->cpustate_names = cpustatenames;
273*b89261baSDavid van Moolenbroek statics->memory_names = memorynames;
274*b89261baSDavid van Moolenbroek statics->order_names = ordernames;
275*b89261baSDavid van Moolenbroek statics->swap_names = swapnames;
276*b89261baSDavid van Moolenbroek
277*b89261baSDavid van Moolenbroek return(0);
278*b89261baSDavid van Moolenbroek }
279*b89261baSDavid van Moolenbroek
280*b89261baSDavid van Moolenbroek
281*b89261baSDavid van Moolenbroek
format_header(char * uname_field)282*b89261baSDavid van Moolenbroek char *format_header(char *uname_field)
283*b89261baSDavid van Moolenbroek
284*b89261baSDavid van Moolenbroek {
285*b89261baSDavid van Moolenbroek register char *ptr;
286*b89261baSDavid van Moolenbroek
287*b89261baSDavid van Moolenbroek ptr = header + UNAME_START;
288*b89261baSDavid van Moolenbroek while (*uname_field != '\0')
289*b89261baSDavid van Moolenbroek {
290*b89261baSDavid van Moolenbroek *ptr++ = *uname_field++;
291*b89261baSDavid van Moolenbroek }
292*b89261baSDavid van Moolenbroek
293*b89261baSDavid van Moolenbroek return(header);
294*b89261baSDavid van Moolenbroek }
295*b89261baSDavid van Moolenbroek
296*b89261baSDavid van Moolenbroek
297*b89261baSDavid van Moolenbroek
298*b89261baSDavid van Moolenbroek void
get_system_info(struct system_info * si)299*b89261baSDavid van Moolenbroek get_system_info(struct system_info *si)
300*b89261baSDavid van Moolenbroek
301*b89261baSDavid van Moolenbroek {
302*b89261baSDavid van Moolenbroek int load_avg[3];
303*b89261baSDavid van Moolenbroek struct sysinfo s_info;
304*b89261baSDavid van Moolenbroek struct vmker m_info;
305*b89261baSDavid van Moolenbroek int i;
306*b89261baSDavid van Moolenbroek double total = 0;
307*b89261baSDavid van Moolenbroek
308*b89261baSDavid van Moolenbroek /* get the load avarage array */
309*b89261baSDavid van Moolenbroek getkval(avenrun_offset, (caddr_t)load_avg, sizeof load_avg, "avenrun");
310*b89261baSDavid van Moolenbroek
311*b89261baSDavid van Moolenbroek /* get the sysinfo structure */
312*b89261baSDavid van Moolenbroek getkval(sysinfo_offset, (caddr_t)&s_info, sizeof s_info, "sysinfo");
313*b89261baSDavid van Moolenbroek
314*b89261baSDavid van Moolenbroek /* get vmker structure */
315*b89261baSDavid van Moolenbroek getkval(vmker_offset, (caddr_t)&m_info, sizeof m_info, "vmker");
316*b89261baSDavid van Moolenbroek
317*b89261baSDavid van Moolenbroek /* convert load avarages to doubles */
318*b89261baSDavid van Moolenbroek for (i = 0; i < 3; i++)
319*b89261baSDavid van Moolenbroek si->load_avg[i] = (double)load_avg[i]/65536.0;
320*b89261baSDavid van Moolenbroek
321*b89261baSDavid van Moolenbroek /* calculate cpu state in percentages */
322*b89261baSDavid van Moolenbroek for (i = 0; i < CPU_NTIMES; i++) {
323*b89261baSDavid van Moolenbroek cp_old[i] = cp_time[i];
324*b89261baSDavid van Moolenbroek cp_time[i] = s_info.cpu[i];
325*b89261baSDavid van Moolenbroek cp_diff[i] = cp_time[i] - cp_old[i];
326*b89261baSDavid van Moolenbroek total += cp_diff[i];
327*b89261baSDavid van Moolenbroek }
328*b89261baSDavid van Moolenbroek
329*b89261baSDavid van Moolenbroek total = total/1000.0; /* top itself will correct this */
330*b89261baSDavid van Moolenbroek for (i = 0; i < CPU_NTIMES; i++) {
331*b89261baSDavid van Moolenbroek cpu_states[i] = cp_diff[i] / total;
332*b89261baSDavid van Moolenbroek }
333*b89261baSDavid van Moolenbroek
334*b89261baSDavid van Moolenbroek /* calculate memory statistics, scale 4K pages to megabytes */
335*b89261baSDavid van Moolenbroek #define PAGE_TO_MB(a) ((a)*4/1024)
336*b89261baSDavid van Moolenbroek memory_stats[M_REAL] = PAGE_TO_MB(m_info.totalmem);
337*b89261baSDavid van Moolenbroek memory_stats[M_REALFREE] = PAGE_TO_MB(m_info.freemem);
338*b89261baSDavid van Moolenbroek memory_stats[M_BUFFERS] = PAGE_TO_MB(m_info.numperm);
339*b89261baSDavid van Moolenbroek swap_stats[M_VIRTUAL] = PAGE_TO_MB(m_info.totalvmem);
340*b89261baSDavid van Moolenbroek swap_stats[M_VIRTFREE] = PAGE_TO_MB(m_info.freevmem);
341*b89261baSDavid van Moolenbroek
342*b89261baSDavid van Moolenbroek /* runnable processes */
343*b89261baSDavid van Moolenbroek process_states[0] = s_info.runque - old_runque;
344*b89261baSDavid van Moolenbroek old_runque = s_info.runque;
345*b89261baSDavid van Moolenbroek
346*b89261baSDavid van Moolenbroek si->cpustates = cpu_states;
347*b89261baSDavid van Moolenbroek si->memory = memory_stats;
348*b89261baSDavid van Moolenbroek si->swap = swap_stats;
349*b89261baSDavid van Moolenbroek }
350*b89261baSDavid van Moolenbroek
351*b89261baSDavid van Moolenbroek static struct handle handle;
352*b89261baSDavid van Moolenbroek
353*b89261baSDavid van Moolenbroek caddr_t
get_process_info(struct system_info * si,struct process_select * sel,int compare_index)354*b89261baSDavid van Moolenbroek get_process_info(struct system_info *si, struct process_select *sel, int compare_index)
355*b89261baSDavid van Moolenbroek
356*b89261baSDavid van Moolenbroek {
357*b89261baSDavid van Moolenbroek int i, nproc;
358*b89261baSDavid van Moolenbroek int ptsize_util;
359*b89261baSDavid van Moolenbroek int active_procs = 0, total_procs = 0;
360*b89261baSDavid van Moolenbroek struct procsinfo *pp, **p_pref = pref;
361*b89261baSDavid van Moolenbroek unsigned long pctcpu;
362*b89261baSDavid van Moolenbroek pid_t procsindex = 0;
363*b89261baSDavid van Moolenbroek struct proc *p;
364*b89261baSDavid van Moolenbroek
365*b89261baSDavid van Moolenbroek si->procstates = process_states;
366*b89261baSDavid van Moolenbroek
367*b89261baSDavid van Moolenbroek curtime = time(0);
368*b89261baSDavid van Moolenbroek
369*b89261baSDavid van Moolenbroek /* get the procsinfo structures of all running processes */
370*b89261baSDavid van Moolenbroek nproc = getprocs(p_info, sizeof (struct procsinfo), NULL, 0,
371*b89261baSDavid van Moolenbroek &procsindex, nprocs);
372*b89261baSDavid van Moolenbroek if (nproc < 0) {
373*b89261baSDavid van Moolenbroek perror("getprocs");
374*b89261baSDavid van Moolenbroek quit(1);
375*b89261baSDavid van Moolenbroek }
376*b89261baSDavid van Moolenbroek
377*b89261baSDavid van Moolenbroek /* the swapper has no cmd-line attached */
378*b89261baSDavid van Moolenbroek strcpy(p_info[0].pi_comm, "swapper");
379*b89261baSDavid van Moolenbroek
380*b89261baSDavid van Moolenbroek /* get proc table */
381*b89261baSDavid van Moolenbroek ptsize_util = (PROCMASK(p_info[nproc-1].pi_pid)+1) * sizeof(struct proc);
382*b89261baSDavid van Moolenbroek getkval(proc_offset, (caddr_t)p_proc, ptsize_util, "proc");
383*b89261baSDavid van Moolenbroek
384*b89261baSDavid van Moolenbroek memset(process_states, 0, sizeof process_states);
385*b89261baSDavid van Moolenbroek
386*b89261baSDavid van Moolenbroek /* build a list of pointers to processes to show. walk through the
387*b89261baSDavid van Moolenbroek * list of procsinfo structures instead of the proc table since the
388*b89261baSDavid van Moolenbroek * mapping of procsinfo -> proctable is easy, the other way around
389*b89261baSDavid van Moolenbroek * is cumbersome
390*b89261baSDavid van Moolenbroek */
391*b89261baSDavid van Moolenbroek for (pp = p_info, i = 0; i < nproc; pp++, i++) {
392*b89261baSDavid van Moolenbroek
393*b89261baSDavid van Moolenbroek p = &p_proc[PROCMASK(pp->pi_pid)];
394*b89261baSDavid van Moolenbroek
395*b89261baSDavid van Moolenbroek /* AIX marks all runnable processes as ACTIVE. We want to know
396*b89261baSDavid van Moolenbroek which processes are sleeping, so check used cpu ticks and adjust
397*b89261baSDavid van Moolenbroek status field accordingly
398*b89261baSDavid van Moolenbroek */
399*b89261baSDavid van Moolenbroek if (p->p_stat == SACTIVE && p->p_cpticks == 0)
400*b89261baSDavid van Moolenbroek p->p_stat = SIDL;
401*b89261baSDavid van Moolenbroek
402*b89261baSDavid van Moolenbroek if (pp->pi_state && (sel->system || ((pp->pi_flags & SKPROC) == 0))) {
403*b89261baSDavid van Moolenbroek total_procs++;
404*b89261baSDavid van Moolenbroek process_states[p->p_stat]++;
405*b89261baSDavid van Moolenbroek if ( (pp->pi_state != SZOMB) &&
406*b89261baSDavid van Moolenbroek (sel->idle || p->p_cpticks != 0 || (p->p_stat == SACTIVE))
407*b89261baSDavid van Moolenbroek && (sel->uid == -1 || pp->pi_uid == (uid_t)sel->uid)) {
408*b89261baSDavid van Moolenbroek *p_pref++ = pp;
409*b89261baSDavid van Moolenbroek active_procs++;
410*b89261baSDavid van Moolenbroek }
411*b89261baSDavid van Moolenbroek }
412*b89261baSDavid van Moolenbroek }
413*b89261baSDavid van Moolenbroek
414*b89261baSDavid van Moolenbroek /* the pref array now holds pointers to the procsinfo structures in
415*b89261baSDavid van Moolenbroek * the p_info array that were selected for display
416*b89261baSDavid van Moolenbroek */
417*b89261baSDavid van Moolenbroek
418*b89261baSDavid van Moolenbroek /* sort if requested */
419*b89261baSDavid van Moolenbroek if (si->p_active)
420*b89261baSDavid van Moolenbroek qsort((char *)pref, active_procs, sizeof (struct procsinfo *),
421*b89261baSDavid van Moolenbroek proc_compares[compare_index]);
422*b89261baSDavid van Moolenbroek
423*b89261baSDavid van Moolenbroek si->last_pid = -1; /* no way to figure out last used pid */
424*b89261baSDavid van Moolenbroek si->p_total = total_procs;
425*b89261baSDavid van Moolenbroek si->p_active = pref_len = active_procs;
426*b89261baSDavid van Moolenbroek
427*b89261baSDavid van Moolenbroek handle.next_proc = pref;
428*b89261baSDavid van Moolenbroek handle.remaining = active_procs;
429*b89261baSDavid van Moolenbroek
430*b89261baSDavid van Moolenbroek return((caddr_t)&handle);
431*b89261baSDavid van Moolenbroek }
432*b89261baSDavid van Moolenbroek
433*b89261baSDavid van Moolenbroek char fmt[MAX_COLS]; /* static area where result is built */
434*b89261baSDavid van Moolenbroek
435*b89261baSDavid van Moolenbroek /* define what weighted cpu is. use definition of %CPU from 'man ps(1)' */
436*b89261baSDavid van Moolenbroek #define weighted_cpu(pp) (PROCTIME(pp) == 0 ? 0.0 : \
437*b89261baSDavid van Moolenbroek (((PROCTIME(pp)*100.0)/(curtime-pi->pi_start)/ncpus)))
438*b89261baSDavid van Moolenbroek #define double_pctcpu(p) ((double)p->p_pctcpu/(double)FLT_MODULO)
439*b89261baSDavid van Moolenbroek
440*b89261baSDavid van Moolenbroek char *
format_next_process(caddr_t handle,char * (* get_userid)())441*b89261baSDavid van Moolenbroek format_next_process(caddr_t handle, char *(*get_userid)())
442*b89261baSDavid van Moolenbroek
443*b89261baSDavid van Moolenbroek {
444*b89261baSDavid van Moolenbroek register struct handle *hp;
445*b89261baSDavid van Moolenbroek register struct procsinfo *pi;
446*b89261baSDavid van Moolenbroek register struct proc *p;
447*b89261baSDavid van Moolenbroek char *uname;
448*b89261baSDavid van Moolenbroek long cpu_time;
449*b89261baSDavid van Moolenbroek int proc_size, proc_ress;
450*b89261baSDavid van Moolenbroek char size_unit = 'K';
451*b89261baSDavid van Moolenbroek char ress_unit = 'K';
452*b89261baSDavid van Moolenbroek
453*b89261baSDavid van Moolenbroek hp = (struct handle *)handle;
454*b89261baSDavid van Moolenbroek if (hp->remaining == 0) { /* safe guard */
455*b89261baSDavid van Moolenbroek fmt[0] = '\0';
456*b89261baSDavid van Moolenbroek return fmt;
457*b89261baSDavid van Moolenbroek }
458*b89261baSDavid van Moolenbroek pi = *(hp->next_proc++);
459*b89261baSDavid van Moolenbroek hp->remaining--;
460*b89261baSDavid van Moolenbroek p = &p_proc[PROCMASK(pi->pi_pid)];
461*b89261baSDavid van Moolenbroek
462*b89261baSDavid van Moolenbroek cpu_time = PROCTIME(pi);
463*b89261baSDavid van Moolenbroek
464*b89261baSDavid van Moolenbroek /* we disply sizes up to 10M in KiloBytes, beyond 10M in MegaBytes */
465*b89261baSDavid van Moolenbroek if ((proc_size = (pi->pi_tsize/1024+pi->pi_dvm)*4) > 10240) {
466*b89261baSDavid van Moolenbroek proc_size /= 1024;
467*b89261baSDavid van Moolenbroek size_unit = 'M';
468*b89261baSDavid van Moolenbroek }
469*b89261baSDavid van Moolenbroek if ((proc_ress = (pi->pi_trss + pi->pi_drss)*4) > 10240) {
470*b89261baSDavid van Moolenbroek proc_ress /= 1024;
471*b89261baSDavid van Moolenbroek ress_unit = 'M';
472*b89261baSDavid van Moolenbroek }
473*b89261baSDavid van Moolenbroek
474*b89261baSDavid van Moolenbroek sprintf(fmt, Proc_format ,
475*b89261baSDavid van Moolenbroek pi->pi_pid, /* PID */
476*b89261baSDavid van Moolenbroek (*get_userid)(pi->pi_uid), /* login name */
477*b89261baSDavid van Moolenbroek getpriority(PRIO_PROCESS, pi->pi_pid),
478*b89261baSDavid van Moolenbroek EXTRACT_NICE(p), /* fixed or vari */
479*b89261baSDavid van Moolenbroek proc_size, /* size */
480*b89261baSDavid van Moolenbroek size_unit, /* K or M */
481*b89261baSDavid van Moolenbroek proc_ress, /* resident */
482*b89261baSDavid van Moolenbroek ress_unit, /* K or M */
483*b89261baSDavid van Moolenbroek state_abbrev[p->p_stat], /* process state */
484*b89261baSDavid van Moolenbroek format_time(cpu_time), /* time used */
485*b89261baSDavid van Moolenbroek weighted_cpu(pi), /* WCPU */
486*b89261baSDavid van Moolenbroek 100.0 * double_pctcpu(p), /* CPU */
487*b89261baSDavid van Moolenbroek printable(pi->pi_comm), /* COMM */
488*b89261baSDavid van Moolenbroek (pi->pi_flags & SKPROC) == 0 ? "" : " (sys)" /* kernel process? */
489*b89261baSDavid van Moolenbroek );
490*b89261baSDavid van Moolenbroek return(fmt);
491*b89261baSDavid van Moolenbroek }
492*b89261baSDavid van Moolenbroek
493*b89261baSDavid van Moolenbroek
494*b89261baSDavid van Moolenbroek /*
495*b89261baSDavid van Moolenbroek * getkval(offset, ptr, size, refstr) - get a value out of the kernel.
496*b89261baSDavid van Moolenbroek * "offset" is the byte offset into the kernel for the desired value,
497*b89261baSDavid van Moolenbroek * "ptr" points to a buffer into which the value is retrieved,
498*b89261baSDavid van Moolenbroek * "size" is the size of the buffer (and the object to retrieve),
499*b89261baSDavid van Moolenbroek * "refstr" is a reference string used when printing error meessages,
500*b89261baSDavid van Moolenbroek * if "refstr" starts with a '!', then a failure on read will not
501*b89261baSDavid van Moolenbroek * be fatal (this may seem like a silly way to do things, but I
502*b89261baSDavid van Moolenbroek * really didn't want the overhead of another argument).
503*b89261baSDavid van Moolenbroek *
504*b89261baSDavid van Moolenbroek */
505*b89261baSDavid van Moolenbroek
506*b89261baSDavid van Moolenbroek int
getkval(unsigned long offset,caddr_t ptr,int size,char * refstr)507*b89261baSDavid van Moolenbroek getkval(unsigned long offset, caddr_t ptr, int size, char *refstr)
508*b89261baSDavid van Moolenbroek
509*b89261baSDavid van Moolenbroek {
510*b89261baSDavid van Moolenbroek int upper_2gb = 0;
511*b89261baSDavid van Moolenbroek
512*b89261baSDavid van Moolenbroek /* reads above 2Gb are done by seeking to offset%2Gb, and supplying
513*b89261baSDavid van Moolenbroek * 1 (opposed to 0) as fourth parameter to readx (see 'man kmem')
514*b89261baSDavid van Moolenbroek */
515*b89261baSDavid van Moolenbroek if (offset > 1<<31) {
516*b89261baSDavid van Moolenbroek upper_2gb = 1;
517*b89261baSDavid van Moolenbroek offset &= 0x7fffffff;
518*b89261baSDavid van Moolenbroek }
519*b89261baSDavid van Moolenbroek
520*b89261baSDavid van Moolenbroek if (lseek(kmem, offset, SEEK_SET) != offset) {
521*b89261baSDavid van Moolenbroek fprintf(stderr, "top: lseek failed\n");
522*b89261baSDavid van Moolenbroek quit(2);
523*b89261baSDavid van Moolenbroek }
524*b89261baSDavid van Moolenbroek
525*b89261baSDavid van Moolenbroek if (readx(kmem, ptr, size, upper_2gb) != size) {
526*b89261baSDavid van Moolenbroek if (*refstr == '!')
527*b89261baSDavid van Moolenbroek return 0;
528*b89261baSDavid van Moolenbroek else {
529*b89261baSDavid van Moolenbroek fprintf(stderr, "top: kvm_read for %s: %s\n", refstr,
530*b89261baSDavid van Moolenbroek sys_errlist[errno]);
531*b89261baSDavid van Moolenbroek quit(2);
532*b89261baSDavid van Moolenbroek }
533*b89261baSDavid van Moolenbroek }
534*b89261baSDavid van Moolenbroek
535*b89261baSDavid van Moolenbroek return 1 ;
536*b89261baSDavid van Moolenbroek }
537*b89261baSDavid van Moolenbroek
538*b89261baSDavid van Moolenbroek /* comparison routine for qsort */
539*b89261baSDavid van Moolenbroek /*
540*b89261baSDavid van Moolenbroek * The following code is taken from the solaris module and adjusted
541*b89261baSDavid van Moolenbroek * for AIX -- JV .
542*b89261baSDavid van Moolenbroek */
543*b89261baSDavid van Moolenbroek
544*b89261baSDavid van Moolenbroek #define ORDERKEY_PCTCPU \
545*b89261baSDavid van Moolenbroek if (lresult = p2->p_pctcpu - p1->p_pctcpu, \
546*b89261baSDavid van Moolenbroek (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
547*b89261baSDavid van Moolenbroek
548*b89261baSDavid van Moolenbroek #define ORDERKEY_CPTICKS \
549*b89261baSDavid van Moolenbroek if ((result = PROCTIME(pi2) - PROCTIME(pi1)) == 0)
550*b89261baSDavid van Moolenbroek
551*b89261baSDavid van Moolenbroek
552*b89261baSDavid van Moolenbroek #define ORDERKEY_STATE \
553*b89261baSDavid van Moolenbroek if ((result = sorted_state[p2->p_stat] \
554*b89261baSDavid van Moolenbroek - sorted_state[p1->p_stat]) == 0)
555*b89261baSDavid van Moolenbroek
556*b89261baSDavid van Moolenbroek /* Nice values directly reflect the process' priority, and are always >0 ;-) */
557*b89261baSDavid van Moolenbroek #define ORDERKEY_PRIO \
558*b89261baSDavid van Moolenbroek if ((result = EXTRACT_NICE(p1) - EXTRACT_NICE(p2)) == 0)
559*b89261baSDavid van Moolenbroek
560*b89261baSDavid van Moolenbroek #define ORDERKEY_RSSIZE \
561*b89261baSDavid van Moolenbroek if ((result = PROCRESS(pi2) - PROCRESS(pi1)) == 0)
562*b89261baSDavid van Moolenbroek #define ORDERKEY_MEM \
563*b89261baSDavid van Moolenbroek if ((result = PROCSIZE(pi2) - PROCSIZE(pi1)) == 0)
564*b89261baSDavid van Moolenbroek
565*b89261baSDavid van Moolenbroek static unsigned char sorted_state[] =
566*b89261baSDavid van Moolenbroek {
567*b89261baSDavid van Moolenbroek 0, /* not used */
568*b89261baSDavid van Moolenbroek 0,
569*b89261baSDavid van Moolenbroek 0,
570*b89261baSDavid van Moolenbroek 0,
571*b89261baSDavid van Moolenbroek 3, /* sleep */
572*b89261baSDavid van Moolenbroek 1, /* zombie */
573*b89261baSDavid van Moolenbroek 4, /* stop */
574*b89261baSDavid van Moolenbroek 6, /* run */
575*b89261baSDavid van Moolenbroek 2, /* swap */
576*b89261baSDavid van Moolenbroek };
577*b89261baSDavid van Moolenbroek
578*b89261baSDavid van Moolenbroek /* compare_cpu - the comparison function for sorting by cpu percentage */
579*b89261baSDavid van Moolenbroek
580*b89261baSDavid van Moolenbroek int
compare_cpu(struct procsinfo ** ppi1,struct procsinfo ** ppi2)581*b89261baSDavid van Moolenbroek compare_cpu(struct procsinfo **ppi1, struct procsinfo **ppi2)
582*b89261baSDavid van Moolenbroek
583*b89261baSDavid van Moolenbroek {
584*b89261baSDavid van Moolenbroek register struct procsinfo *pi1 = *ppi1, *pi2 = *ppi2;
585*b89261baSDavid van Moolenbroek register struct proc *p1;
586*b89261baSDavid van Moolenbroek register struct proc *p2;
587*b89261baSDavid van Moolenbroek register int result;
588*b89261baSDavid van Moolenbroek register long lresult;
589*b89261baSDavid van Moolenbroek
590*b89261baSDavid van Moolenbroek p1 = &p_proc[PROCMASK(pi1->pi_pid)];
591*b89261baSDavid van Moolenbroek p2 = &p_proc[PROCMASK(pi2->pi_pid)];
592*b89261baSDavid van Moolenbroek
593*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
594*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
595*b89261baSDavid van Moolenbroek ORDERKEY_STATE
596*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
597*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
598*b89261baSDavid van Moolenbroek ORDERKEY_MEM
599*b89261baSDavid van Moolenbroek ;
600*b89261baSDavid van Moolenbroek
601*b89261baSDavid van Moolenbroek return result;
602*b89261baSDavid van Moolenbroek }
603*b89261baSDavid van Moolenbroek
604*b89261baSDavid van Moolenbroek
605*b89261baSDavid van Moolenbroek /* compare_size - the comparison function for sorting by total memory usage */
606*b89261baSDavid van Moolenbroek
607*b89261baSDavid van Moolenbroek int
compare_size(struct procsinfo ** ppi1,struct procsinfo ** ppi2)608*b89261baSDavid van Moolenbroek compare_size(struct procsinfo **ppi1, struct procsinfo **ppi2)
609*b89261baSDavid van Moolenbroek
610*b89261baSDavid van Moolenbroek {
611*b89261baSDavid van Moolenbroek register struct procsinfo *pi1 = *ppi1, *pi2 = *ppi2;
612*b89261baSDavid van Moolenbroek register struct proc *p1;
613*b89261baSDavid van Moolenbroek register struct proc *p2;
614*b89261baSDavid van Moolenbroek register int result;
615*b89261baSDavid van Moolenbroek register long lresult;
616*b89261baSDavid van Moolenbroek
617*b89261baSDavid van Moolenbroek p1 = &p_proc[PROCMASK(pi1->pi_pid)];
618*b89261baSDavid van Moolenbroek p2 = &p_proc[PROCMASK(pi2->pi_pid)];
619*b89261baSDavid van Moolenbroek
620*b89261baSDavid van Moolenbroek ORDERKEY_MEM
621*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
622*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
623*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
624*b89261baSDavid van Moolenbroek ORDERKEY_STATE
625*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
626*b89261baSDavid van Moolenbroek ;
627*b89261baSDavid van Moolenbroek
628*b89261baSDavid van Moolenbroek return result;
629*b89261baSDavid van Moolenbroek }
630*b89261baSDavid van Moolenbroek
631*b89261baSDavid van Moolenbroek
632*b89261baSDavid van Moolenbroek /* compare_res - the comparison function for sorting by resident set size */
633*b89261baSDavid van Moolenbroek
634*b89261baSDavid van Moolenbroek int
compare_res(struct procsinfo ** ppi1,struct procsinfo ** ppi2)635*b89261baSDavid van Moolenbroek compare_res(struct procsinfo **ppi1, struct procsinfo **ppi2)
636*b89261baSDavid van Moolenbroek
637*b89261baSDavid van Moolenbroek {
638*b89261baSDavid van Moolenbroek register struct procsinfo *pi1 = *ppi1, *pi2 = *ppi2;
639*b89261baSDavid van Moolenbroek register struct proc *p1;
640*b89261baSDavid van Moolenbroek register struct proc *p2;
641*b89261baSDavid van Moolenbroek register int result;
642*b89261baSDavid van Moolenbroek register long lresult;
643*b89261baSDavid van Moolenbroek
644*b89261baSDavid van Moolenbroek p1 = &p_proc[PROCMASK(pi1->pi_pid)];
645*b89261baSDavid van Moolenbroek p2 = &p_proc[PROCMASK(pi2->pi_pid)];
646*b89261baSDavid van Moolenbroek
647*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
648*b89261baSDavid van Moolenbroek ORDERKEY_MEM
649*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
650*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
651*b89261baSDavid van Moolenbroek ORDERKEY_STATE
652*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
653*b89261baSDavid van Moolenbroek ;
654*b89261baSDavid van Moolenbroek
655*b89261baSDavid van Moolenbroek return result;
656*b89261baSDavid van Moolenbroek }
657*b89261baSDavid van Moolenbroek
658*b89261baSDavid van Moolenbroek
659*b89261baSDavid van Moolenbroek /* compare_time - the comparison function for sorting by total cpu time */
660*b89261baSDavid van Moolenbroek
661*b89261baSDavid van Moolenbroek int
compare_time(struct procsinfo ** ppi1,struct procsinfo ** ppi2)662*b89261baSDavid van Moolenbroek compare_time(struct procsinfo **ppi1, struct procsinfo **ppi2)
663*b89261baSDavid van Moolenbroek
664*b89261baSDavid van Moolenbroek {
665*b89261baSDavid van Moolenbroek register struct procsinfo *pi1 = *ppi1, *pi2 = *ppi2;
666*b89261baSDavid van Moolenbroek register struct proc *p1;
667*b89261baSDavid van Moolenbroek register struct proc *p2;
668*b89261baSDavid van Moolenbroek register int result;
669*b89261baSDavid van Moolenbroek register long lresult;
670*b89261baSDavid van Moolenbroek
671*b89261baSDavid van Moolenbroek p1 = &p_proc[PROCMASK(pi1->pi_pid)];
672*b89261baSDavid van Moolenbroek p2 = &p_proc[PROCMASK(pi2->pi_pid)];
673*b89261baSDavid van Moolenbroek
674*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
675*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
676*b89261baSDavid van Moolenbroek ORDERKEY_STATE
677*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
678*b89261baSDavid van Moolenbroek ORDERKEY_MEM
679*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
680*b89261baSDavid van Moolenbroek ;
681*b89261baSDavid van Moolenbroek
682*b89261baSDavid van Moolenbroek return result;
683*b89261baSDavid van Moolenbroek }
684*b89261baSDavid van Moolenbroek
685*b89261baSDavid van Moolenbroek
686*b89261baSDavid van Moolenbroek /* compare_prio - the comparison function for sorting by cpu percentage */
687*b89261baSDavid van Moolenbroek
688*b89261baSDavid van Moolenbroek int
compare_prio(struct procsinfo ** ppi1,struct procsinfo ** ppi2)689*b89261baSDavid van Moolenbroek compare_prio(struct procsinfo **ppi1, struct procsinfo **ppi2)
690*b89261baSDavid van Moolenbroek
691*b89261baSDavid van Moolenbroek {
692*b89261baSDavid van Moolenbroek register struct procsinfo *pi1 = *ppi1, *pi2 = *ppi2;
693*b89261baSDavid van Moolenbroek register struct proc *p1;
694*b89261baSDavid van Moolenbroek register struct proc *p2;
695*b89261baSDavid van Moolenbroek register int result;
696*b89261baSDavid van Moolenbroek register long lresult;
697*b89261baSDavid van Moolenbroek
698*b89261baSDavid van Moolenbroek p1 = &p_proc[PROCMASK(pi1->pi_pid)];
699*b89261baSDavid van Moolenbroek p2 = &p_proc[PROCMASK(pi2->pi_pid)];
700*b89261baSDavid van Moolenbroek
701*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
702*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
703*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
704*b89261baSDavid van Moolenbroek ORDERKEY_STATE
705*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
706*b89261baSDavid van Moolenbroek ORDERKEY_MEM
707*b89261baSDavid van Moolenbroek ;
708*b89261baSDavid van Moolenbroek
709*b89261baSDavid van Moolenbroek return result;
710*b89261baSDavid van Moolenbroek }
711*b89261baSDavid van Moolenbroek
712*b89261baSDavid van Moolenbroek int
proc_owner(int pid)713*b89261baSDavid van Moolenbroek proc_owner(int pid)
714*b89261baSDavid van Moolenbroek
715*b89261baSDavid van Moolenbroek {
716*b89261baSDavid van Moolenbroek int uid;
717*b89261baSDavid van Moolenbroek register struct procsinfo **prefp = pref;
718*b89261baSDavid van Moolenbroek register int cnt = pref_len;
719*b89261baSDavid van Moolenbroek
720*b89261baSDavid van Moolenbroek while (--cnt >= 0) {
721*b89261baSDavid van Moolenbroek if ((*prefp)->pi_pid == pid)
722*b89261baSDavid van Moolenbroek return (*prefp)->pi_uid;
723*b89261baSDavid van Moolenbroek prefp++;
724*b89261baSDavid van Moolenbroek }
725*b89261baSDavid van Moolenbroek
726*b89261baSDavid van Moolenbroek return(-1);
727*b89261baSDavid van Moolenbroek }
728*b89261baSDavid van Moolenbroek
729*b89261baSDavid van Moolenbroek
730