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: Intel based System V Release 4
37*b89261baSDavid van Moolenbroek *
38*b89261baSDavid van Moolenbroek * DESCRIPTION:
39*b89261baSDavid van Moolenbroek * System V release 4.0.x for i486
40*b89261baSDavid van Moolenbroek * System V release 4 for Okidata M88100
41*b89261baSDavid van Moolenbroek * System V release 4 for NCR 3000 series OS Rel 1.00 to 2.02
42*b89261baSDavid van Moolenbroek * System V release 4 for NCR 3000 series OS Rel 02.03.00 and above
43*b89261baSDavid van Moolenbroek * and probably other svr4 ports
44*b89261baSDavid van Moolenbroek *
45*b89261baSDavid van Moolenbroek * LIBS: -lelf
46*b89261baSDavid van Moolenbroek *
47*b89261baSDavid van Moolenbroek * AUTHORS: Andrew Herbert <andrew@werple.apana.org.au>
48*b89261baSDavid van Moolenbroek * Robert Boucher <boucher@sofkin.ca>
49*b89261baSDavid van Moolenbroek * Ported to System 3000 Release 2.03 by:
50*b89261baSDavid van Moolenbroek * Jeff Janvrin <jeff.janvrinColumbiaSC.NCR.COM>
51*b89261baSDavid van Moolenbroek */
52*b89261baSDavid van Moolenbroek
53*b89261baSDavid van Moolenbroek #include "top.h"
54*b89261baSDavid van Moolenbroek #include "machine.h"
55*b89261baSDavid van Moolenbroek #include "utils.h"
56*b89261baSDavid van Moolenbroek #include <stdio.h>
57*b89261baSDavid van Moolenbroek #include <fcntl.h>
58*b89261baSDavid van Moolenbroek #include <unistd.h>
59*b89261baSDavid van Moolenbroek #include <stdlib.h>
60*b89261baSDavid van Moolenbroek #include <errno.h>
61*b89261baSDavid van Moolenbroek #include <dirent.h>
62*b89261baSDavid van Moolenbroek #include <nlist.h>
63*b89261baSDavid van Moolenbroek #include <string.h>
64*b89261baSDavid van Moolenbroek #if TIME_WITH_SYS_TIME
65*b89261baSDavid van Moolenbroek # include <sys/time.h>
66*b89261baSDavid van Moolenbroek # include <time.h>
67*b89261baSDavid van Moolenbroek #else
68*b89261baSDavid van Moolenbroek # if HAVE_SYS_TIME_H
69*b89261baSDavid van Moolenbroek # include <sys/time.h>
70*b89261baSDavid van Moolenbroek # else
71*b89261baSDavid van Moolenbroek # include <time.h>
72*b89261baSDavid van Moolenbroek # endif
73*b89261baSDavid van Moolenbroek #endif
74*b89261baSDavid van Moolenbroek #include <sys/types.h>
75*b89261baSDavid van Moolenbroek #include <sys/stat.h>
76*b89261baSDavid van Moolenbroek #include <sys/param.h>
77*b89261baSDavid van Moolenbroek #include <sys/procfs.h>
78*b89261baSDavid van Moolenbroek #include <sys/sysinfo.h>
79*b89261baSDavid van Moolenbroek #include <sys/sysmacros.h>
80*b89261baSDavid van Moolenbroek #include <sys/vmmeter.h>
81*b89261baSDavid van Moolenbroek #include <vm/anon.h>
82*b89261baSDavid van Moolenbroek #include <sys/priocntl.h>
83*b89261baSDavid van Moolenbroek #include <sys/rtpriocntl.h>
84*b89261baSDavid van Moolenbroek #include <sys/tspriocntl.h>
85*b89261baSDavid van Moolenbroek #include <sys/procset.h>
86*b89261baSDavid van Moolenbroek #include <sys/var.h>
87*b89261baSDavid van Moolenbroek
88*b89261baSDavid van Moolenbroek #define UNIX "/stand/unix"
89*b89261baSDavid van Moolenbroek #define KMEM "/dev/kmem"
90*b89261baSDavid van Moolenbroek #define PROCFS "/proc"
91*b89261baSDavid van Moolenbroek #define CPUSTATES 5
92*b89261baSDavid van Moolenbroek
93*b89261baSDavid van Moolenbroek #ifndef PRIO_MAX
94*b89261baSDavid van Moolenbroek #define PRIO_MAX 20
95*b89261baSDavid van Moolenbroek #endif
96*b89261baSDavid van Moolenbroek #ifndef PRIO_MIN
97*b89261baSDavid van Moolenbroek #define PRIO_MIN -20
98*b89261baSDavid van Moolenbroek #endif
99*b89261baSDavid van Moolenbroek
100*b89261baSDavid van Moolenbroek #ifndef FSCALE
101*b89261baSDavid van Moolenbroek #define FSHIFT 8 /* bits to right of fixed binary point */
102*b89261baSDavid van Moolenbroek #define FSCALE (1<<FSHIFT)
103*b89261baSDavid van Moolenbroek #endif
104*b89261baSDavid van Moolenbroek
105*b89261baSDavid van Moolenbroek #define loaddouble(x) ((double)(x) / FSCALE)
106*b89261baSDavid van Moolenbroek #define percent_cpu(x) ((double)(x)->pr_cpu / FSCALE)
107*b89261baSDavid van Moolenbroek #define weighted_cpu(pct, pp) ( ((pp)->pr_time.tv_sec) == 0 ? 0.0 : \
108*b89261baSDavid van Moolenbroek ((pp)->pr_cpu) / ((pp)->pr_time.tv_sec) )
109*b89261baSDavid van Moolenbroek #define pagetok(size) ctob(size) >> LOG1024
110*b89261baSDavid van Moolenbroek
111*b89261baSDavid van Moolenbroek /* definitions for the index in the nlist array */
112*b89261baSDavid van Moolenbroek #define X_AVENRUN 0
113*b89261baSDavid van Moolenbroek #define X_MPID 1
114*b89261baSDavid van Moolenbroek #define X_V 2
115*b89261baSDavid van Moolenbroek #define X_NPROC 3
116*b89261baSDavid van Moolenbroek #define X_ANONINFO 4
117*b89261baSDavid van Moolenbroek #define X_TOTAL 5
118*b89261baSDavid van Moolenbroek #define X_SYSINFO 6
119*b89261baSDavid van Moolenbroek
120*b89261baSDavid van Moolenbroek static struct nlist nlst[] =
121*b89261baSDavid van Moolenbroek {
122*b89261baSDavid van Moolenbroek {"avenrun"}, /* 0 */
123*b89261baSDavid van Moolenbroek {"mpid"}, /* 1 */
124*b89261baSDavid van Moolenbroek {"v"}, /* 2 */
125*b89261baSDavid van Moolenbroek {"nproc"}, /* 3 */
126*b89261baSDavid van Moolenbroek {"anoninfo"}, /* 4 */
127*b89261baSDavid van Moolenbroek {"total"}, /* 5 */
128*b89261baSDavid van Moolenbroek {"sysinfo"}, /* 6 */
129*b89261baSDavid van Moolenbroek {NULL}
130*b89261baSDavid van Moolenbroek };
131*b89261baSDavid van Moolenbroek
132*b89261baSDavid van Moolenbroek static unsigned long avenrun_offset;
133*b89261baSDavid van Moolenbroek static unsigned long mpid_offset;
134*b89261baSDavid van Moolenbroek static unsigned long nproc_offset;
135*b89261baSDavid van Moolenbroek static unsigned long anoninfo_offset;
136*b89261baSDavid van Moolenbroek static unsigned long total_offset;
137*b89261baSDavid van Moolenbroek static unsigned long sysinfo_offset;
138*b89261baSDavid van Moolenbroek
139*b89261baSDavid van Moolenbroek /* get_process_info passes back a handle. This is what it looks like: */
140*b89261baSDavid van Moolenbroek
141*b89261baSDavid van Moolenbroek struct handle
142*b89261baSDavid van Moolenbroek {
143*b89261baSDavid van Moolenbroek struct prpsinfo **next_proc;/* points to next valid proc pointer */
144*b89261baSDavid van Moolenbroek int remaining; /* number of pointers remaining */
145*b89261baSDavid van Moolenbroek };
146*b89261baSDavid van Moolenbroek
147*b89261baSDavid van Moolenbroek /*
148*b89261baSDavid van Moolenbroek * These definitions control the format of the per-process area
149*b89261baSDavid van Moolenbroek */
150*b89261baSDavid van Moolenbroek
151*b89261baSDavid van Moolenbroek static char header[] =
152*b89261baSDavid van Moolenbroek " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND";
153*b89261baSDavid van Moolenbroek /* 0123456 -- field to fill in starts at header+6 */
154*b89261baSDavid van Moolenbroek #define UNAME_START 6
155*b89261baSDavid van Moolenbroek #define Proc_format \
156*b89261baSDavid van Moolenbroek "%5d %-8.8s %3d %4d %5s %5s %-5s %6s %3d.0%% %5.2f%% %.16s"
157*b89261baSDavid van Moolenbroek
158*b89261baSDavid van Moolenbroek char *state_abbrev[] =
159*b89261baSDavid van Moolenbroek {"", "sleep", "run", "zombie", "stop", "start", "cpu", "swap"};
160*b89261baSDavid van Moolenbroek
161*b89261baSDavid van Moolenbroek int process_states[8];
162*b89261baSDavid van Moolenbroek char *procstatenames[] =
163*b89261baSDavid van Moolenbroek {
164*b89261baSDavid van Moolenbroek "", " sleeping, ", " running, ", " zombie, ", " stopped, ",
165*b89261baSDavid van Moolenbroek " starting, ", " on cpu, ", " swapped, ",
166*b89261baSDavid van Moolenbroek NULL
167*b89261baSDavid van Moolenbroek };
168*b89261baSDavid van Moolenbroek
169*b89261baSDavid van Moolenbroek int cpu_states[CPUSTATES];
170*b89261baSDavid van Moolenbroek char *cpustatenames[] =
171*b89261baSDavid van Moolenbroek {"idle", "user", "kernel", "wait", "swap", NULL};
172*b89261baSDavid van Moolenbroek
173*b89261baSDavid van Moolenbroek /* these are for detailing the memory statistics */
174*b89261baSDavid van Moolenbroek
175*b89261baSDavid van Moolenbroek long memory_stats[5];
176*b89261baSDavid van Moolenbroek char *memorynames[] =
177*b89261baSDavid van Moolenbroek {"K real, ", "K active, ", "K free, ", "K swap, ", "K free swap", NULL};
178*b89261baSDavid van Moolenbroek
179*b89261baSDavid van Moolenbroek /* forward reference for qsort comparison function */
180*b89261baSDavid van Moolenbroek int proc_compare();
181*b89261baSDavid van Moolenbroek
182*b89261baSDavid van Moolenbroek static int kmem = -1;
183*b89261baSDavid van Moolenbroek static int nproc;
184*b89261baSDavid van Moolenbroek static int bytes;
185*b89261baSDavid van Moolenbroek static int use_stats = 0;
186*b89261baSDavid van Moolenbroek static struct prpsinfo *pbase;
187*b89261baSDavid van Moolenbroek static struct prpsinfo **pref;
188*b89261baSDavid van Moolenbroek static DIR *proc_dir;
189*b89261baSDavid van Moolenbroek
190*b89261baSDavid van Moolenbroek /* useful externals */
191*b89261baSDavid van Moolenbroek extern int errno;
192*b89261baSDavid van Moolenbroek extern char *sys_errlist[];
193*b89261baSDavid van Moolenbroek extern char *myname;
194*b89261baSDavid van Moolenbroek extern int check_nlist ();
195*b89261baSDavid van Moolenbroek extern int getkval ();
196*b89261baSDavid van Moolenbroek extern void perror ();
197*b89261baSDavid van Moolenbroek extern void getptable ();
198*b89261baSDavid van Moolenbroek extern void quit ();
199*b89261baSDavid van Moolenbroek extern int nlist ();
200*b89261baSDavid van Moolenbroek
201*b89261baSDavid van Moolenbroek int
machine_init(struct statics * statics)202*b89261baSDavid van Moolenbroek machine_init (struct statics *statics)
203*b89261baSDavid van Moolenbroek {
204*b89261baSDavid van Moolenbroek static struct var v;
205*b89261baSDavid van Moolenbroek
206*b89261baSDavid van Moolenbroek /* fill in the statics information */
207*b89261baSDavid van Moolenbroek statics->procstate_names = procstatenames;
208*b89261baSDavid van Moolenbroek statics->cpustate_names = cpustatenames;
209*b89261baSDavid van Moolenbroek statics->memory_names = memorynames;
210*b89261baSDavid van Moolenbroek
211*b89261baSDavid van Moolenbroek /* get the list of symbols we want to access in the kernel */
212*b89261baSDavid van Moolenbroek if (nlist (UNIX, nlst))
213*b89261baSDavid van Moolenbroek {
214*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "Unable to nlist %s\n", UNIX);
215*b89261baSDavid van Moolenbroek return (-1);
216*b89261baSDavid van Moolenbroek }
217*b89261baSDavid van Moolenbroek
218*b89261baSDavid van Moolenbroek /* make sure they were all found */
219*b89261baSDavid van Moolenbroek if (check_nlist (nlst) > 0)
220*b89261baSDavid van Moolenbroek return (-1);
221*b89261baSDavid van Moolenbroek
222*b89261baSDavid van Moolenbroek /* open kernel memory */
223*b89261baSDavid van Moolenbroek if ((kmem = open (KMEM, O_RDONLY)) == -1)
224*b89261baSDavid van Moolenbroek {
225*b89261baSDavid van Moolenbroek perror (KMEM);
226*b89261baSDavid van Moolenbroek return (-1);
227*b89261baSDavid van Moolenbroek }
228*b89261baSDavid van Moolenbroek
229*b89261baSDavid van Moolenbroek /* get the symbol values out of kmem */
230*b89261baSDavid van Moolenbroek /* NPROC Tuning parameter for max number of processes */
231*b89261baSDavid van Moolenbroek (void) getkval (nlst[X_V].n_value, &v, sizeof (struct var), nlst[X_V].n_name);
232*b89261baSDavid van Moolenbroek nproc = v.v_proc;
233*b89261baSDavid van Moolenbroek
234*b89261baSDavid van Moolenbroek /* stash away certain offsets for later use */
235*b89261baSDavid van Moolenbroek mpid_offset = nlst[X_MPID].n_value;
236*b89261baSDavid van Moolenbroek nproc_offset = nlst[X_NPROC].n_value;
237*b89261baSDavid van Moolenbroek avenrun_offset = nlst[X_AVENRUN].n_value;
238*b89261baSDavid van Moolenbroek anoninfo_offset = nlst[X_ANONINFO].n_value;
239*b89261baSDavid van Moolenbroek total_offset = nlst[X_TOTAL].n_value;
240*b89261baSDavid van Moolenbroek /* JJ this may need to be changed */
241*b89261baSDavid van Moolenbroek sysinfo_offset = nlst[X_SYSINFO].n_value;
242*b89261baSDavid van Moolenbroek
243*b89261baSDavid van Moolenbroek /* allocate space for proc structure array and array of pointers */
244*b89261baSDavid van Moolenbroek bytes = nproc * sizeof (struct prpsinfo);
245*b89261baSDavid van Moolenbroek pbase = (struct prpsinfo *) malloc (bytes);
246*b89261baSDavid van Moolenbroek pref = (struct prpsinfo **) malloc (nproc * sizeof (struct prpsinfo *));
247*b89261baSDavid van Moolenbroek
248*b89261baSDavid van Moolenbroek /* Just in case ... */
249*b89261baSDavid van Moolenbroek if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL)
250*b89261baSDavid van Moolenbroek {
251*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: can't allocate sufficient memory\n", myname);
252*b89261baSDavid van Moolenbroek return (-1);
253*b89261baSDavid van Moolenbroek }
254*b89261baSDavid van Moolenbroek
255*b89261baSDavid van Moolenbroek if (!(proc_dir = opendir (PROCFS)))
256*b89261baSDavid van Moolenbroek {
257*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "Unable to open %s\n", PROCFS);
258*b89261baSDavid van Moolenbroek return (-1);
259*b89261baSDavid van Moolenbroek }
260*b89261baSDavid van Moolenbroek
261*b89261baSDavid van Moolenbroek if (chdir (PROCFS))
262*b89261baSDavid van Moolenbroek { /* handy for later on when we're reading it */
263*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "Unable to chdir to %s\n", PROCFS);
264*b89261baSDavid van Moolenbroek return (-1);
265*b89261baSDavid van Moolenbroek }
266*b89261baSDavid van Moolenbroek
267*b89261baSDavid van Moolenbroek /* all done! */
268*b89261baSDavid van Moolenbroek return (0);
269*b89261baSDavid van Moolenbroek }
270*b89261baSDavid van Moolenbroek
271*b89261baSDavid van Moolenbroek char *
format_header(char * uname_field)272*b89261baSDavid van Moolenbroek format_header (char *uname_field)
273*b89261baSDavid van Moolenbroek {
274*b89261baSDavid van Moolenbroek register char *ptr;
275*b89261baSDavid van Moolenbroek
276*b89261baSDavid van Moolenbroek ptr = header + UNAME_START;
277*b89261baSDavid van Moolenbroek while (*uname_field != '\0')
278*b89261baSDavid van Moolenbroek *ptr++ = *uname_field++;
279*b89261baSDavid van Moolenbroek
280*b89261baSDavid van Moolenbroek return (header);
281*b89261baSDavid van Moolenbroek }
282*b89261baSDavid van Moolenbroek
283*b89261baSDavid van Moolenbroek void
get_system_info(struct system_info * si)284*b89261baSDavid van Moolenbroek get_system_info (struct system_info *si)
285*b89261baSDavid van Moolenbroek {
286*b89261baSDavid van Moolenbroek long avenrun[3];
287*b89261baSDavid van Moolenbroek struct sysinfo sysinfo;
288*b89261baSDavid van Moolenbroek static struct sysinfo *mpinfo = NULL; /* array, per-processor sysinfo structures. */
289*b89261baSDavid van Moolenbroek struct vmtotal total;
290*b89261baSDavid van Moolenbroek struct anoninfo anoninfo;
291*b89261baSDavid van Moolenbroek static long cp_old[CPUSTATES];
292*b89261baSDavid van Moolenbroek static long cp_diff[CPUSTATES]; /* for cpu state percentages */
293*b89261baSDavid van Moolenbroek static int num_cpus;
294*b89261baSDavid van Moolenbroek static int fd_cpu = 0;
295*b89261baSDavid van Moolenbroek register int i;
296*b89261baSDavid van Moolenbroek
297*b89261baSDavid van Moolenbroek if ( use_stats == 1) {
298*b89261baSDavid van Moolenbroek if ( fd_cpu == 0 ) {
299*b89261baSDavid van Moolenbroek if ((fd_cpu = open("/stats/cpuinfo", O_RDONLY)) == -1) {
300*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: Open of /stats/cpuinfo failed\n", myname);
301*b89261baSDavid van Moolenbroek quit(2);
302*b89261baSDavid van Moolenbroek }
303*b89261baSDavid van Moolenbroek if (read(fd_cpu, &num_cpus, sizeof(int)) != sizeof(int)) {
304*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: Read of /stats/cpuinfo failed\n", myname);
305*b89261baSDavid van Moolenbroek quit(2);
306*b89261baSDavid van Moolenbroek }
307*b89261baSDavid van Moolenbroek close(fd_cpu);
308*b89261baSDavid van Moolenbroek }
309*b89261baSDavid van Moolenbroek if (mpinfo == NULL) {
310*b89261baSDavid van Moolenbroek mpinfo = (struct sysinfo *)calloc(num_cpus, sizeof(mpinfo[0]));
311*b89261baSDavid van Moolenbroek if (mpinfo == NULL) {
312*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: can't allocate space for per-processor sysinfos\n", myname);
313*b89261baSDavid van Moolenbroek quit(12);
314*b89261baSDavid van Moolenbroek }
315*b89261baSDavid van Moolenbroek }
316*b89261baSDavid van Moolenbroek /* Read the per cpu sysinfo structures into mpinfo struct. */
317*b89261baSDavid van Moolenbroek read_sysinfos(num_cpus, mpinfo);
318*b89261baSDavid van Moolenbroek /* Add up all of the percpu sysinfos to get global sysinfo */
319*b89261baSDavid van Moolenbroek sysinfo_data(num_cpus, &sysinfo, mpinfo);
320*b89261baSDavid van Moolenbroek } else {
321*b89261baSDavid van Moolenbroek (void) getkval (sysinfo_offset, &sysinfo, sizeof (struct sysinfo), "sysinfo");
322*b89261baSDavid van Moolenbroek }
323*b89261baSDavid van Moolenbroek
324*b89261baSDavid van Moolenbroek /* convert cp_time counts to percentages */
325*b89261baSDavid van Moolenbroek (void) percentages (CPUSTATES, cpu_states, sysinfo.cpu, cp_old, cp_diff);
326*b89261baSDavid van Moolenbroek
327*b89261baSDavid van Moolenbroek /* get mpid -- process id of last process */
328*b89261baSDavid van Moolenbroek (void) getkval (mpid_offset, &(si->last_pid), sizeof (si->last_pid),
329*b89261baSDavid van Moolenbroek "mpid");
330*b89261baSDavid van Moolenbroek
331*b89261baSDavid van Moolenbroek /* get load average array */
332*b89261baSDavid van Moolenbroek (void) getkval (avenrun_offset, (int *) avenrun, sizeof (avenrun), "avenrun");
333*b89261baSDavid van Moolenbroek
334*b89261baSDavid van Moolenbroek /* convert load averages to doubles */
335*b89261baSDavid van Moolenbroek for (i = 0; i < 3; i++)
336*b89261baSDavid van Moolenbroek si->load_avg[i] = loaddouble (avenrun[i]);
337*b89261baSDavid van Moolenbroek
338*b89261baSDavid van Moolenbroek /* get total -- systemwide main memory usage structure */
339*b89261baSDavid van Moolenbroek (void) getkval (total_offset, (int *) (&total), sizeof (total), "total");
340*b89261baSDavid van Moolenbroek /* convert memory stats to Kbytes */
341*b89261baSDavid van Moolenbroek memory_stats[0] = pagetok (total.t_rm);
342*b89261baSDavid van Moolenbroek memory_stats[1] = pagetok (total.t_arm);
343*b89261baSDavid van Moolenbroek memory_stats[2] = pagetok (total.t_free);
344*b89261baSDavid van Moolenbroek (void) getkval (anoninfo_offset, (int *) (&anoninfo), sizeof (anoninfo),
345*b89261baSDavid van Moolenbroek "anoninfo");
346*b89261baSDavid van Moolenbroek memory_stats[3] = pagetok (anoninfo.ani_max - anoninfo.ani_free);
347*b89261baSDavid van Moolenbroek memory_stats[4] = pagetok (anoninfo.ani_max - anoninfo.ani_resv);
348*b89261baSDavid van Moolenbroek
349*b89261baSDavid van Moolenbroek /* set arrays and strings */
350*b89261baSDavid van Moolenbroek si->cpustates = cpu_states;
351*b89261baSDavid van Moolenbroek si->memory = memory_stats;
352*b89261baSDavid van Moolenbroek }
353*b89261baSDavid van Moolenbroek
354*b89261baSDavid van Moolenbroek static struct handle handle;
355*b89261baSDavid van Moolenbroek
356*b89261baSDavid van Moolenbroek caddr_t
get_process_info(struct system_info * si,struct process_select * sel,int x)357*b89261baSDavid van Moolenbroek get_process_info (
358*b89261baSDavid van Moolenbroek struct system_info *si,
359*b89261baSDavid van Moolenbroek struct process_select *sel,
360*b89261baSDavid van Moolenbroek int x)
361*b89261baSDavid van Moolenbroek {
362*b89261baSDavid van Moolenbroek register int i;
363*b89261baSDavid van Moolenbroek register int total_procs;
364*b89261baSDavid van Moolenbroek register int active_procs;
365*b89261baSDavid van Moolenbroek register struct prpsinfo **prefp;
366*b89261baSDavid van Moolenbroek register struct prpsinfo *pp;
367*b89261baSDavid van Moolenbroek
368*b89261baSDavid van Moolenbroek /* these are copied out of sel for speed */
369*b89261baSDavid van Moolenbroek int show_idle;
370*b89261baSDavid van Moolenbroek int show_system;
371*b89261baSDavid van Moolenbroek int show_uid;
372*b89261baSDavid van Moolenbroek
373*b89261baSDavid van Moolenbroek /* Get current number of processes */
374*b89261baSDavid van Moolenbroek (void) getkval (nproc_offset, (int *) (&nproc), sizeof (nproc), "nproc");
375*b89261baSDavid van Moolenbroek
376*b89261baSDavid van Moolenbroek /* read all the proc structures */
377*b89261baSDavid van Moolenbroek getptable (pbase);
378*b89261baSDavid van Moolenbroek
379*b89261baSDavid van Moolenbroek /* get a pointer to the states summary array */
380*b89261baSDavid van Moolenbroek si->procstates = process_states;
381*b89261baSDavid van Moolenbroek
382*b89261baSDavid van Moolenbroek /* set up flags which define what we are going to select */
383*b89261baSDavid van Moolenbroek show_idle = sel->idle;
384*b89261baSDavid van Moolenbroek show_system = sel->system;
385*b89261baSDavid van Moolenbroek show_uid = sel->uid != -1;
386*b89261baSDavid van Moolenbroek
387*b89261baSDavid van Moolenbroek /* count up process states and get pointers to interesting procs */
388*b89261baSDavid van Moolenbroek total_procs = 0;
389*b89261baSDavid van Moolenbroek active_procs = 0;
390*b89261baSDavid van Moolenbroek (void) memset (process_states, 0, sizeof (process_states));
391*b89261baSDavid van Moolenbroek prefp = pref;
392*b89261baSDavid van Moolenbroek
393*b89261baSDavid van Moolenbroek for (pp = pbase, i = 0; i < nproc; pp++, i++)
394*b89261baSDavid van Moolenbroek {
395*b89261baSDavid van Moolenbroek /*
396*b89261baSDavid van Moolenbroek * Place pointers to each valid proc structure in pref[].
397*b89261baSDavid van Moolenbroek * Process slots that are actually in use have a non-zero
398*b89261baSDavid van Moolenbroek * status field. Processes with SSYS set are system
399*b89261baSDavid van Moolenbroek * processes---these get ignored unless show_sysprocs is set.
400*b89261baSDavid van Moolenbroek */
401*b89261baSDavid van Moolenbroek if (pp->pr_state != 0 &&
402*b89261baSDavid van Moolenbroek (show_system || ((pp->pr_flag & SSYS) == 0)))
403*b89261baSDavid van Moolenbroek {
404*b89261baSDavid van Moolenbroek total_procs++;
405*b89261baSDavid van Moolenbroek process_states[pp->pr_state]++;
406*b89261baSDavid van Moolenbroek if ((!pp->pr_zomb) &&
407*b89261baSDavid van Moolenbroek (show_idle || (pp->pr_state == SRUN) || (pp->pr_state == SONPROC)) &&
408*b89261baSDavid van Moolenbroek (!show_uid || pp->pr_uid == (uid_t) sel->uid))
409*b89261baSDavid van Moolenbroek {
410*b89261baSDavid van Moolenbroek *prefp++ = pp;
411*b89261baSDavid van Moolenbroek active_procs++;
412*b89261baSDavid van Moolenbroek }
413*b89261baSDavid van Moolenbroek }
414*b89261baSDavid van Moolenbroek }
415*b89261baSDavid van Moolenbroek
416*b89261baSDavid van Moolenbroek /* if requested, sort the "interesting" processes */
417*b89261baSDavid van Moolenbroek qsort ((char *) pref, active_procs, sizeof (struct prpsinfo *), proc_compare);
418*b89261baSDavid van Moolenbroek
419*b89261baSDavid van Moolenbroek /* remember active and total counts */
420*b89261baSDavid van Moolenbroek si->p_total = total_procs;
421*b89261baSDavid van Moolenbroek si->p_active = active_procs;
422*b89261baSDavid van Moolenbroek
423*b89261baSDavid van Moolenbroek /* pass back a handle */
424*b89261baSDavid van Moolenbroek handle.next_proc = pref;
425*b89261baSDavid van Moolenbroek handle.remaining = active_procs;
426*b89261baSDavid van Moolenbroek return ((caddr_t) & handle);
427*b89261baSDavid van Moolenbroek }
428*b89261baSDavid van Moolenbroek
429*b89261baSDavid van Moolenbroek char fmt[MAX_COLS]; /* static area where result is built */
430*b89261baSDavid van Moolenbroek
431*b89261baSDavid van Moolenbroek char *
format_next_process(caddr_t handle,char * (* get_userid)())432*b89261baSDavid van Moolenbroek format_next_process (
433*b89261baSDavid van Moolenbroek caddr_t handle,
434*b89261baSDavid van Moolenbroek char *(*get_userid) ())
435*b89261baSDavid van Moolenbroek {
436*b89261baSDavid van Moolenbroek register struct prpsinfo *pp;
437*b89261baSDavid van Moolenbroek struct handle *hp;
438*b89261baSDavid van Moolenbroek register long cputime;
439*b89261baSDavid van Moolenbroek register double pctcpu;
440*b89261baSDavid van Moolenbroek
441*b89261baSDavid van Moolenbroek /* find and remember the next proc structure */
442*b89261baSDavid van Moolenbroek hp = (struct handle *) handle;
443*b89261baSDavid van Moolenbroek pp = *(hp->next_proc++);
444*b89261baSDavid van Moolenbroek hp->remaining--;
445*b89261baSDavid van Moolenbroek
446*b89261baSDavid van Moolenbroek /* get the cpu usage and calculate the cpu percentages */
447*b89261baSDavid van Moolenbroek cputime = pp->pr_time.tv_sec;
448*b89261baSDavid van Moolenbroek pctcpu = percent_cpu (pp);
449*b89261baSDavid van Moolenbroek
450*b89261baSDavid van Moolenbroek /* format this entry */
451*b89261baSDavid van Moolenbroek (void) sprintf (fmt,
452*b89261baSDavid van Moolenbroek Proc_format,
453*b89261baSDavid van Moolenbroek pp->pr_pid,
454*b89261baSDavid van Moolenbroek (*get_userid) (pp->pr_uid),
455*b89261baSDavid van Moolenbroek pp->pr_pri - PZERO,
456*b89261baSDavid van Moolenbroek pp->pr_nice - NZERO,
457*b89261baSDavid van Moolenbroek format_k(pagetok (pp->pr_size)),
458*b89261baSDavid van Moolenbroek format_k(pagetok (pp->pr_rssize)),
459*b89261baSDavid van Moolenbroek state_abbrev[pp->pr_state],
460*b89261baSDavid van Moolenbroek format_time(cputime),
461*b89261baSDavid van Moolenbroek (pp->pr_cpu & 0377),
462*b89261baSDavid van Moolenbroek 100.0 * pctcpu,
463*b89261baSDavid van Moolenbroek printable(pp->pr_fname));
464*b89261baSDavid van Moolenbroek
465*b89261baSDavid van Moolenbroek /* return the result */
466*b89261baSDavid van Moolenbroek return (fmt);
467*b89261baSDavid van Moolenbroek }
468*b89261baSDavid van Moolenbroek
469*b89261baSDavid van Moolenbroek /*
470*b89261baSDavid van Moolenbroek * check_nlist(nlst) - checks the nlist to see if any symbols were not
471*b89261baSDavid van Moolenbroek * found. For every symbol that was not found, a one-line
472*b89261baSDavid van Moolenbroek * message is printed to stderr. The routine returns the
473*b89261baSDavid van Moolenbroek * number of symbols NOT found.
474*b89261baSDavid van Moolenbroek */
475*b89261baSDavid van Moolenbroek int
check_nlist(register struct nlist * nlst)476*b89261baSDavid van Moolenbroek check_nlist (register struct nlist *nlst)
477*b89261baSDavid van Moolenbroek {
478*b89261baSDavid van Moolenbroek register int i;
479*b89261baSDavid van Moolenbroek struct stat stat_buf;
480*b89261baSDavid van Moolenbroek
481*b89261baSDavid van Moolenbroek /* check to see if we got ALL the symbols we requested */
482*b89261baSDavid van Moolenbroek /* this will write one line to stderr for every symbol not found */
483*b89261baSDavid van Moolenbroek
484*b89261baSDavid van Moolenbroek i = 0;
485*b89261baSDavid van Moolenbroek while (nlst->n_name != NULL)
486*b89261baSDavid van Moolenbroek {
487*b89261baSDavid van Moolenbroek if (nlst->n_type == 0)
488*b89261baSDavid van Moolenbroek {
489*b89261baSDavid van Moolenbroek if (strcmp("sysinfo", nlst->n_name) == 0)
490*b89261baSDavid van Moolenbroek {
491*b89261baSDavid van Moolenbroek /* check to see if /stats file system exists. If so, */
492*b89261baSDavid van Moolenbroek /* ignore error. */
493*b89261baSDavid van Moolenbroek if ( !((stat("/stats/sysinfo", &stat_buf) == 0) &&
494*b89261baSDavid van Moolenbroek (stat_buf.st_mode & S_IFREG)) )
495*b89261baSDavid van Moolenbroek {
496*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "kernel: no symbol named `%s'\n", nlst->n_name);
497*b89261baSDavid van Moolenbroek i = 1;
498*b89261baSDavid van Moolenbroek } else {
499*b89261baSDavid van Moolenbroek use_stats = 1;
500*b89261baSDavid van Moolenbroek }
501*b89261baSDavid van Moolenbroek } else {
502*b89261baSDavid van Moolenbroek
503*b89261baSDavid van Moolenbroek /* this one wasn't found */
504*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "kernel: no symbol named `%s'\n", nlst->n_name);
505*b89261baSDavid van Moolenbroek i = 1;
506*b89261baSDavid van Moolenbroek }
507*b89261baSDavid van Moolenbroek }
508*b89261baSDavid van Moolenbroek nlst++;
509*b89261baSDavid van Moolenbroek }
510*b89261baSDavid van Moolenbroek return (i);
511*b89261baSDavid van Moolenbroek }
512*b89261baSDavid van Moolenbroek
513*b89261baSDavid van Moolenbroek
514*b89261baSDavid van Moolenbroek /*
515*b89261baSDavid van Moolenbroek * getkval(offset, ptr, size, refstr) - get a value out of the kernel.
516*b89261baSDavid van Moolenbroek * "offset" is the byte offset into the kernel for the desired value,
517*b89261baSDavid van Moolenbroek * "ptr" points to a buffer into which the value is retrieved,
518*b89261baSDavid van Moolenbroek * "size" is the size of the buffer (and the object to retrieve),
519*b89261baSDavid van Moolenbroek * "refstr" is a reference string used when printing error meessages,
520*b89261baSDavid van Moolenbroek * if "refstr" starts with a '!', then a failure on read will not
521*b89261baSDavid van Moolenbroek * be fatal (this may seem like a silly way to do things, but I
522*b89261baSDavid van Moolenbroek * really didn't want the overhead of another argument).
523*b89261baSDavid van Moolenbroek *
524*b89261baSDavid van Moolenbroek */
525*b89261baSDavid van Moolenbroek int
getkval(unsigned long offset,int * ptr,int size,char * refstr)526*b89261baSDavid van Moolenbroek getkval (
527*b89261baSDavid van Moolenbroek unsigned long offset,
528*b89261baSDavid van Moolenbroek int *ptr,
529*b89261baSDavid van Moolenbroek int size,
530*b89261baSDavid van Moolenbroek char *refstr)
531*b89261baSDavid van Moolenbroek {
532*b89261baSDavid van Moolenbroek #ifdef MIPS
533*b89261baSDavid van Moolenbroek if (lseek (kmem, (long) (offset & 0x7fffffff), 0) == -1)
534*b89261baSDavid van Moolenbroek #else
535*b89261baSDavid van Moolenbroek if (lseek (kmem, (long) offset, 0) == -1)
536*b89261baSDavid van Moolenbroek #endif
537*b89261baSDavid van Moolenbroek {
538*b89261baSDavid van Moolenbroek if (*refstr == '!')
539*b89261baSDavid van Moolenbroek refstr++;
540*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: lseek to %s: %s\n",
541*b89261baSDavid van Moolenbroek myname, refstr, sys_errlist[errno]);
542*b89261baSDavid van Moolenbroek quit (22);
543*b89261baSDavid van Moolenbroek }
544*b89261baSDavid van Moolenbroek if (read (kmem, (char *) ptr, size) == -1)
545*b89261baSDavid van Moolenbroek if (*refstr == '!')
546*b89261baSDavid van Moolenbroek /* we lost the race with the kernel, process isn't in memory */
547*b89261baSDavid van Moolenbroek return (0);
548*b89261baSDavid van Moolenbroek else
549*b89261baSDavid van Moolenbroek {
550*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: reading %s: %s\n",
551*b89261baSDavid van Moolenbroek myname, refstr, sys_errlist[errno]);
552*b89261baSDavid van Moolenbroek quit (23);
553*b89261baSDavid van Moolenbroek }
554*b89261baSDavid van Moolenbroek return (1);
555*b89261baSDavid van Moolenbroek }
556*b89261baSDavid van Moolenbroek
557*b89261baSDavid van Moolenbroek /* comparison routine for qsort */
558*b89261baSDavid van Moolenbroek
559*b89261baSDavid van Moolenbroek /*
560*b89261baSDavid van Moolenbroek * proc_compare - comparison function for "qsort"
561*b89261baSDavid van Moolenbroek * Compares the resource consumption of two processes using five
562*b89261baSDavid van Moolenbroek * distinct keys. The keys (in descending order of importance) are:
563*b89261baSDavid van Moolenbroek * percent cpu, cpu ticks, state, resident set size, total virtual
564*b89261baSDavid van Moolenbroek * memory usage. The process states are ordered as follows (from least
565*b89261baSDavid van Moolenbroek * to most important): WAIT, zombie, sleep, stop, start, run. The
566*b89261baSDavid van Moolenbroek * array declaration below maps a process state index into a number
567*b89261baSDavid van Moolenbroek * that reflects this ordering.
568*b89261baSDavid van Moolenbroek */
569*b89261baSDavid van Moolenbroek
570*b89261baSDavid van Moolenbroek
571*b89261baSDavid van Moolenbroek unsigned char sorted_state[] =
572*b89261baSDavid van Moolenbroek {
573*b89261baSDavid van Moolenbroek 0, /* not used */
574*b89261baSDavid van Moolenbroek 3, /* sleep */
575*b89261baSDavid van Moolenbroek 6, /* run */
576*b89261baSDavid van Moolenbroek 2, /* zombie */
577*b89261baSDavid van Moolenbroek 4, /* stop */
578*b89261baSDavid van Moolenbroek 5, /* start */
579*b89261baSDavid van Moolenbroek 7, /* run on a processor */
580*b89261baSDavid van Moolenbroek 1 /* being swapped (WAIT) */
581*b89261baSDavid van Moolenbroek };
582*b89261baSDavid van Moolenbroek
583*b89261baSDavid van Moolenbroek int
proc_compare(struct prpsinfo ** pp1,struct prpsinfo ** pp2)584*b89261baSDavid van Moolenbroek proc_compare (
585*b89261baSDavid van Moolenbroek struct prpsinfo **pp1,
586*b89261baSDavid van Moolenbroek struct prpsinfo **pp2)
587*b89261baSDavid van Moolenbroek {
588*b89261baSDavid van Moolenbroek register struct prpsinfo *p1;
589*b89261baSDavid van Moolenbroek register struct prpsinfo *p2;
590*b89261baSDavid van Moolenbroek register long result;
591*b89261baSDavid van Moolenbroek
592*b89261baSDavid van Moolenbroek /* remove one level of indirection */
593*b89261baSDavid van Moolenbroek p1 = *pp1;
594*b89261baSDavid van Moolenbroek p2 = *pp2;
595*b89261baSDavid van Moolenbroek
596*b89261baSDavid van Moolenbroek /* compare percent cpu (pctcpu) */
597*b89261baSDavid van Moolenbroek if ((result = (long) (p2->pr_cpu - p1->pr_cpu)) == 0)
598*b89261baSDavid van Moolenbroek {
599*b89261baSDavid van Moolenbroek /* use cpticks to break the tie */
600*b89261baSDavid van Moolenbroek if ((result = p2->pr_time.tv_sec - p1->pr_time.tv_sec) == 0)
601*b89261baSDavid van Moolenbroek {
602*b89261baSDavid van Moolenbroek /* use process state to break the tie */
603*b89261baSDavid van Moolenbroek if ((result = (long) (sorted_state[p2->pr_state] -
604*b89261baSDavid van Moolenbroek sorted_state[p1->pr_state])) == 0)
605*b89261baSDavid van Moolenbroek {
606*b89261baSDavid van Moolenbroek /* use priority to break the tie */
607*b89261baSDavid van Moolenbroek if ((result = p2->pr_oldpri - p1->pr_oldpri) == 0)
608*b89261baSDavid van Moolenbroek {
609*b89261baSDavid van Moolenbroek /* use resident set size (rssize) to break the tie */
610*b89261baSDavid van Moolenbroek if ((result = p2->pr_rssize - p1->pr_rssize) == 0)
611*b89261baSDavid van Moolenbroek {
612*b89261baSDavid van Moolenbroek /* use total memory to break the tie */
613*b89261baSDavid van Moolenbroek result = (p2->pr_size - p1->pr_size);
614*b89261baSDavid van Moolenbroek }
615*b89261baSDavid van Moolenbroek }
616*b89261baSDavid van Moolenbroek }
617*b89261baSDavid van Moolenbroek }
618*b89261baSDavid van Moolenbroek }
619*b89261baSDavid van Moolenbroek return (result);
620*b89261baSDavid van Moolenbroek }
621*b89261baSDavid van Moolenbroek
622*b89261baSDavid van Moolenbroek /*
623*b89261baSDavid van Moolenbroek get process table
624*b89261baSDavid van Moolenbroek */
625*b89261baSDavid van Moolenbroek void
getptable(struct prpsinfo * baseptr)626*b89261baSDavid van Moolenbroek getptable (struct prpsinfo *baseptr)
627*b89261baSDavid van Moolenbroek {
628*b89261baSDavid van Moolenbroek struct prpsinfo *currproc; /* pointer to current proc structure */
629*b89261baSDavid van Moolenbroek int numprocs = 0;
630*b89261baSDavid van Moolenbroek struct dirent *direntp;
631*b89261baSDavid van Moolenbroek
632*b89261baSDavid van Moolenbroek for (rewinddir (proc_dir); direntp = readdir (proc_dir);)
633*b89261baSDavid van Moolenbroek {
634*b89261baSDavid van Moolenbroek int fd;
635*b89261baSDavid van Moolenbroek
636*b89261baSDavid van Moolenbroek if ((fd = open (direntp->d_name, O_RDONLY)) < 0)
637*b89261baSDavid van Moolenbroek continue;
638*b89261baSDavid van Moolenbroek
639*b89261baSDavid van Moolenbroek currproc = &baseptr[numprocs];
640*b89261baSDavid van Moolenbroek if (ioctl (fd, PIOCPSINFO, currproc) < 0)
641*b89261baSDavid van Moolenbroek {
642*b89261baSDavid van Moolenbroek (void) close (fd);
643*b89261baSDavid van Moolenbroek continue;
644*b89261baSDavid van Moolenbroek }
645*b89261baSDavid van Moolenbroek
646*b89261baSDavid van Moolenbroek numprocs++;
647*b89261baSDavid van Moolenbroek (void) close (fd);
648*b89261baSDavid van Moolenbroek }
649*b89261baSDavid van Moolenbroek
650*b89261baSDavid van Moolenbroek if (nproc != numprocs)
651*b89261baSDavid van Moolenbroek nproc = numprocs;
652*b89261baSDavid van Moolenbroek }
653*b89261baSDavid van Moolenbroek
654*b89261baSDavid van Moolenbroek /* return the owner of the specified process, for use in commands.c as we're
655*b89261baSDavid van Moolenbroek running setuid root */
656*b89261baSDavid van Moolenbroek int
proc_owner(int pid)657*b89261baSDavid van Moolenbroek proc_owner (int pid)
658*b89261baSDavid van Moolenbroek {
659*b89261baSDavid van Moolenbroek register struct prpsinfo *p;
660*b89261baSDavid van Moolenbroek int i;
661*b89261baSDavid van Moolenbroek for (i = 0, p = pbase; i < nproc; i++, p++)
662*b89261baSDavid van Moolenbroek if (p->pr_pid == (pid_t)pid)
663*b89261baSDavid van Moolenbroek return (p->pr_uid);
664*b89261baSDavid van Moolenbroek
665*b89261baSDavid van Moolenbroek return (-1);
666*b89261baSDavid van Moolenbroek }
667*b89261baSDavid van Moolenbroek
668*b89261baSDavid van Moolenbroek #ifndef HAVE_SETPRIORITY
669*b89261baSDavid van Moolenbroek int
setpriority(int dummy,int who,int niceval)670*b89261baSDavid van Moolenbroek setpriority (int dummy, int who, int niceval)
671*b89261baSDavid van Moolenbroek {
672*b89261baSDavid van Moolenbroek int scale;
673*b89261baSDavid van Moolenbroek int prio;
674*b89261baSDavid van Moolenbroek pcinfo_t pcinfo;
675*b89261baSDavid van Moolenbroek pcparms_t pcparms;
676*b89261baSDavid van Moolenbroek tsparms_t *tsparms;
677*b89261baSDavid van Moolenbroek
678*b89261baSDavid van Moolenbroek strcpy (pcinfo.pc_clname, "TS");
679*b89261baSDavid van Moolenbroek if (priocntl (0, 0, PC_GETCID, (caddr_t) & pcinfo) == -1)
680*b89261baSDavid van Moolenbroek return (-1);
681*b89261baSDavid van Moolenbroek
682*b89261baSDavid van Moolenbroek prio = niceval;
683*b89261baSDavid van Moolenbroek if (prio > PRIO_MAX)
684*b89261baSDavid van Moolenbroek prio = PRIO_MAX;
685*b89261baSDavid van Moolenbroek else if (prio < PRIO_MIN)
686*b89261baSDavid van Moolenbroek prio = PRIO_MIN;
687*b89261baSDavid van Moolenbroek
688*b89261baSDavid van Moolenbroek tsparms = (tsparms_t *) pcparms.pc_clparms;
689*b89261baSDavid van Moolenbroek scale = ((tsinfo_t *) pcinfo.pc_clinfo)->ts_maxupri;
690*b89261baSDavid van Moolenbroek tsparms->ts_uprilim = tsparms->ts_upri = -(scale * prio) / 20;
691*b89261baSDavid van Moolenbroek pcparms.pc_cid = pcinfo.pc_cid;
692*b89261baSDavid van Moolenbroek
693*b89261baSDavid van Moolenbroek if (priocntl (P_PID, who, PC_SETPARMS, (caddr_t) & pcparms) == -1)
694*b89261baSDavid van Moolenbroek return (-1);
695*b89261baSDavid van Moolenbroek
696*b89261baSDavid van Moolenbroek return (0);
697*b89261baSDavid van Moolenbroek }
698*b89261baSDavid van Moolenbroek #endif
699*b89261baSDavid van Moolenbroek
700*b89261baSDavid van Moolenbroek /****************************************************************
701*b89261baSDavid van Moolenbroek * read_sysinfos() - *
702*b89261baSDavid van Moolenbroek * Read all of the CPU specific sysinfo sturctures in from *
703*b89261baSDavid van Moolenbroek * the /stats file system. *
704*b89261baSDavid van Moolenbroek ****************************************************************/
read_sysinfos(num_cpus,buf)705*b89261baSDavid van Moolenbroek read_sysinfos(num_cpus, buf)
706*b89261baSDavid van Moolenbroek int num_cpus;
707*b89261baSDavid van Moolenbroek struct sysinfo *buf;
708*b89261baSDavid van Moolenbroek {
709*b89261baSDavid van Moolenbroek
710*b89261baSDavid van Moolenbroek static int fd1=0; /* file descriptor for /stats/sysinfo */
711*b89261baSDavid van Moolenbroek int read_sz;
712*b89261baSDavid van Moolenbroek
713*b89261baSDavid van Moolenbroek /* Open /stats/sysinfo one time only and leave it open */
714*b89261baSDavid van Moolenbroek if (fd1==0) {
715*b89261baSDavid van Moolenbroek if ((fd1 = open("/stats/sysinfo", O_RDONLY)) == -1)
716*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: Open of /stats/sysinfo failed\n", myname);
717*b89261baSDavid van Moolenbroek }
718*b89261baSDavid van Moolenbroek /* reset the read pointer to the beginning of the file */
719*b89261baSDavid van Moolenbroek if (lseek(fd1, 0L, SEEK_SET) == -1)
720*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: lseek to beginning of /stats/sysinfo failed\n", myname);
721*b89261baSDavid van Moolenbroek read_sz = num_cpus * sizeof(buf[0]);
722*b89261baSDavid van Moolenbroek if (read(fd1, buf, read_sz) != read_sz)
723*b89261baSDavid van Moolenbroek (void) fprintf (stderr, "%s: Read of /stats/sysinfo failed\n", myname);
724*b89261baSDavid van Moolenbroek }
725*b89261baSDavid van Moolenbroek
726*b89261baSDavid van Moolenbroek /****************************************************************
727*b89261baSDavid van Moolenbroek * sysinfo_data() - *
728*b89261baSDavid van Moolenbroek * Add up all of the CPU specific sysinfo sturctures to *
729*b89261baSDavid van Moolenbroek * make the GLOBAL sysinfo. *
730*b89261baSDavid van Moolenbroek ****************************************************************/
sysinfo_data(num_cpus,global_si,percpu_si)731*b89261baSDavid van Moolenbroek sysinfo_data(num_cpus, global_si, percpu_si)
732*b89261baSDavid van Moolenbroek int num_cpus;
733*b89261baSDavid van Moolenbroek struct sysinfo *global_si;
734*b89261baSDavid van Moolenbroek struct sysinfo *percpu_si;
735*b89261baSDavid van Moolenbroek {
736*b89261baSDavid van Moolenbroek struct sysinfo *percpu_p;
737*b89261baSDavid van Moolenbroek int cpu, i, *global, *src;
738*b89261baSDavid van Moolenbroek
739*b89261baSDavid van Moolenbroek /* null out the global statistics from last sample */
740*b89261baSDavid van Moolenbroek memset(global_si, 0, sizeof(struct sysinfo));
741*b89261baSDavid van Moolenbroek
742*b89261baSDavid van Moolenbroek percpu_p = (struct sysinfo *)percpu_si;
743*b89261baSDavid van Moolenbroek for(cpu = 0; cpu < num_cpus; cpu++) {
744*b89261baSDavid van Moolenbroek global = (int *)global_si;
745*b89261baSDavid van Moolenbroek src = (int *)percpu_p;
746*b89261baSDavid van Moolenbroek
747*b89261baSDavid van Moolenbroek /* assume sysinfo ends on an int boundary */
748*b89261baSDavid van Moolenbroek /* Currently, all of the struct sysinfo members are the same
749*b89261baSDavid van Moolenbroek * size as an int. If that changes, we may not be able to
750*b89261baSDavid van Moolenbroek * do this. But this should be safe.
751*b89261baSDavid van Moolenbroek */
752*b89261baSDavid van Moolenbroek for(i=0; i<sizeof(struct sysinfo)/sizeof(int); i++) {
753*b89261baSDavid van Moolenbroek *global++ += *src++;
754*b89261baSDavid van Moolenbroek }
755*b89261baSDavid van Moolenbroek percpu_p++;
756*b89261baSDavid van Moolenbroek }
757*b89261baSDavid van Moolenbroek }
758