1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30
31 #pragma ident "%Z%%M% %I% %E% SMI"
32
33 /*
34 * acctcms [-a] [-c] [-j] [-n] [-s] [-p] [-o] [-t] [file...]
35 * summarize per-process accounting
36 * -a output in ascii, rather than [pt]cms.h format
37 * -c sort by total cpu, rather than total kcore-minutes
38 * -j anything used only once -> ***other
39 * -n sort by number of processes
40 * -s any following files already in pcms.h format
41 * -p output prime time command summary (only with -a)
42 * -o output non-prime time (offshift) command summary (only
43 * with -a option)
44 * -t process records in total (old) style (tcms.h) format
45 * file file in [pt]cms.h (if -s seen already) or acct.h (if not)
46 * expected use:
47 * acctcms /var/adm/pacct? > today; acctcms -s old today >new
48 * cp new old; rm new
49 * acctcms -a today; acctcms -a old
50 */
51 #include <stdio.h>
52 #include <sys/types.h>
53 #include <sys/param.h>
54 #include "acctdef.h"
55 #include <ctype.h>
56 #include <string.h>
57 #include <sys/acct.h>
58 #include <stdlib.h>
59
60 int csize = CSIZE;
61
62 /*
63 * Total cms records format
64 */
65 struct tcms {
66 char tcm_comm[8]; /* command name */
67 long tcm_pc; /* number of processes */
68 float tcm_cpu; /* cpu time(min) */
69 float tcm_real; /* real time(min) */
70 float tcm_kcore; /* kcore-minutes */
71 ulong_t tcm_io; /* chars transferred */
72 ulong_t tcm_rw; /* blocks read */
73 } ;
74 struct tcms *tcm;
75 /*
76 * prime/nonprime CMS record format
77 */
78 struct pcms {
79 char pcm_comm[8]; /* command name */
80 long pcm_pc[2]; /* number of processes */
81 float pcm_cpu[2]; /* cpu time(min) */
82 float pcm_real[2]; /* real time(min) */
83 float pcm_kcore[2]; /* kcore-minutes */
84 float pcm_io[2]; /* chars transferred */
85 float pcm_rw[2]; /* blocks read */
86 } ;
87 struct pcms *pcm;
88 struct tcms tcmtmp = {{'*','*','*','o','t','h','e','r'}};
89 struct pcms pcmtmp = {{'*','*','*','o','t','h','e','r'}};
90 int aflg;
91 int cflg;
92 int jflg;
93 int nflg;
94 int sflg;
95 int pflg;
96 int oflg;
97 int tflg;
98 int errflg;
99
100 #ifdef uts
101 float expand();
102 #else
103 ulong_t expand();
104 #endif
105
106 void outputc(void);
107 void totprnt(struct pcms *);
108 void pprint(struct pcms *);
109 void prnt(struct pcms *, int);
110 void print(struct pcms *);
111 void outputa(void);
112 void toutptc(void);
113 void tprint(struct tcms *);
114 void toutpta(void);
115 int ncmp(struct pcms *, struct pcms *);
116 int tncmp(struct tcms *, struct tcms *);
117 int tccmp(struct tcms *, struct tcms *);
118 int tkcmp(struct tcms *, struct tcms *);
119 int ccmp(struct pcms *, struct pcms *);
120 int kcmp(struct pcms *, struct pcms *);
121 void tdofile(char *);
122 void dofile(char *);
123 void tfixjunk(void);
124 void fixjunk(void);
125 void tcmadd(struct tcms *, struct tcms *);
126 void pcmadd(struct pcms *, struct pcms *);
127 void tsqueeze(void);
128 void squeeze(void);
129
130 /* Format specification for ASCII printing */
131
132 char *fmtcmd = "%-8.8s",
133 *fmtcnt = "%8ld",
134 *fmtkcore = " %11.2f",
135 *fmtcpu = " %9.2f",
136 *fmtreal = " %12.2f",
137 *fmtmsz = " %7.2f",
138 *fmtmcpu = " %6.2f",
139 *fmthog = " %5.2f",
140 *fmtcharx = " %12.0f",
141 *fmtblkx = " %10.0f" ;
142
143 int
main(int argc,char ** argv)144 main(int argc, char **argv)
145 {
146 int c;
147
148 while((c = getopt(argc, argv, "acjnspot")) != EOF)
149 switch(c) {
150 case 'a':
151 aflg++;
152 continue;
153 case 'c':
154 cflg++;
155 continue;
156 case 'j':
157 jflg++;
158 continue;
159 case 'n':
160 nflg++;
161 continue;
162 case 's':
163 sflg++;
164 continue;
165 case 'p':
166 pflg++;
167 continue;
168 case 'o':
169 oflg++;
170 continue;
171 case 't':
172 tflg++;
173 continue;
174 default:
175 errflg++;
176 continue;
177 }
178 if(errflg){
179 fprintf(stderr, "Usage: %s [-acjnspot] [file ...]\n", argv[0]);
180 exit(1);
181 }
182 if(tflg) {
183 if( (tcm = (struct tcms *)calloc(CSIZE, sizeof(struct tcms))) == NULL) {
184 fprintf(stderr, "%s: Cannot allocate memory\n", argv[0]);
185 exit(5);
186 }
187 for(; optind < argc; optind++)
188 tdofile(argv[optind]);
189 if (jflg)
190 tfixjunk();
191 tsqueeze();
192 qsort(tcm, csize, sizeof(tcm[0]),
193 (int (*)(const void *, const void *))
194 ( nflg ? tncmp: (cflg? tccmp: tkcmp)));
195 if (aflg)
196 toutpta();
197 else
198 toutptc();
199 } else {
200 if( (pcm = (struct pcms *)calloc(CSIZE, sizeof(struct pcms))) == NULL) {
201 fprintf(stderr, "%s: Cannot allocate memory\n", argv[0]);
202 exit(6);
203 }
204 for(; optind < argc; optind++)
205 dofile(argv[optind]);
206 if (jflg)
207 fixjunk();
208 squeeze();
209 qsort(pcm, csize, sizeof(pcm[0]),
210 (int (*)(const void *, const void *))
211 (nflg? ncmp: (cflg? ccmp: kcmp)));
212 if (aflg)
213 outputa();
214 else
215 outputc();
216 }
217 exit(0);
218
219 }
220
221 void
tdofile(char * fname)222 tdofile(char *fname)
223 {
224 struct tcms cmt;
225 union {
226 struct acct ab; /* SVR4 acct structure */
227 struct o_acct oab; /* SVR3 acct structure */
228 } acct;
229 int ver = 0;
230 ulong_t mem;
231 ulong_t cpu;
232 ulong_t real;
233
234 if (freopen(fname, "r", stdin) == NULL) {
235 fprintf(stderr, "acctcms: cannot open %s\n", fname);
236 return;
237 }
238
239 if (sflg)
240 while (fread(&cmt, sizeof(cmt), 1, stdin) == 1)
241 tenter(&cmt);
242 else {
243 if (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1)
244 /* check for expanded account structure flag */
245 if (acct.ab.ac_flag & AEXPND)
246 ver = 2; /* 4.0 acct file */
247 else
248 ver = 1; /* SVR3.x acct file */
249
250 rewind(stdin); /* reset file pointer */
251
252 switch(ver) {
253
254 default:
255 /* this can't happen */
256 fprintf(stderr, "acctcms: encountered bad version number\n");
257 return;
258 case 1 :
259 while (fread(&acct.oab, sizeof(acct.oab), 1, stdin) == 1) {
260 CPYN(cmt.tcm_comm, acct.oab.ac_comm);
261 cmt.tcm_pc = 1;
262 cpu = expand(acct.oab.ac_stime)+
263 expand(acct.oab.ac_utime);
264 cmt.tcm_cpu = MINT(cpu);
265 real = expand(acct.oab.ac_etime);
266 cmt.tcm_real = MINT(real);
267 mem = expand(acct.oab.ac_mem);
268 cmt.tcm_kcore = MINT(KCORE(mem));
269 cmt.tcm_io = expand(acct.oab.ac_io);
270 cmt.tcm_rw = expand(acct.oab.ac_rw);
271 tenter(&cmt);
272 }
273 break;
274 case 2 :
275
276 while (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1) {
277 CPYN(cmt.tcm_comm, acct.ab.ac_comm);
278 cmt.tcm_pc = 1;
279 cpu = expand(acct.oab.ac_stime)+
280 expand(acct.oab.ac_utime);
281 cmt.tcm_cpu = MINT(cpu);
282 real = expand(acct.ab.ac_etime);
283 cmt.tcm_real = MINT(real);
284 mem = expand(acct.ab.ac_mem);
285 cmt.tcm_kcore = MINT(KCORE(mem));
286 cmt.tcm_io = expand(acct.ab.ac_io);
287 cmt.tcm_rw = expand(acct.ab.ac_rw);
288 tenter(&cmt);
289 }
290 break;
291 }
292 }
293 }
294
295 void
dofile(char * fname)296 dofile(char *fname)
297 {
298 union {
299 struct acct ab;
300 struct o_acct oab;
301 } acct;
302 struct pcms pcmt;
303 double ratio;
304 long elaps[2];
305 ulong_t etime;
306 double dtmp;
307 unsigned long ltmp;
308 ulong_t mem;
309 ulong_t cpu;
310 ulong_t real;
311
312 if (freopen(fname, "r", stdin) == NULL) {
313 fprintf(stderr, "acctcms: cannot open %s\n", fname);
314 return;
315 }
316
317 if (sflg)
318 while (fread(&pcmt, sizeof(pcmt), 1, stdin) == 1)
319 enter(&pcmt);
320 else {
321 int ver = 0;
322
323 if (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1)
324 /* check for expanded account structure flag */
325 if (acct.ab.ac_flag & AEXPND)
326 ver = 2; /* 4.0 acct file */
327 else
328 ver = 1; /* SVR3.x acct file */
329
330 rewind(stdin); /* reset file pointer */
331
332 switch(ver) {
333
334 default :
335 /* this can't happen */
336 fprintf(stderr, "acctcms: encountered bad version number\n");
337 return;
338 case 1 :
339
340 while (fread(&acct.oab, sizeof(acct.oab), 1, stdin) == 1) {
341 CPYN(pcmt.pcm_comm, acct.oab.ac_comm);
342 /*
343 ** Approximate P/NP split as same as elapsed time
344 */
345 if((etime = SECS(expand(acct.oab.ac_etime))) == 0)
346 etime = 1;
347 if (pnpsplit(acct.oab.ac_btime, etime, elaps)
348 == 0) {
349 (void) fprintf(stderr, "acctcms: could "
350 "not calculate prime/non-prime "
351 "hours\n");
352 exit(1);
353 }
354 ratio = (double)elaps[PRIME]/(double)etime;
355 if(elaps[PRIME] > elaps[NONPRIME]) {
356 pcmt.pcm_pc[PRIME] = 1;
357 pcmt.pcm_pc[NONPRIME] = 0;
358 } else {
359 pcmt.pcm_pc[PRIME] = 0;
360 pcmt.pcm_pc[NONPRIME] = 1;
361 }
362 cpu = expand(acct.oab.ac_stime)+
363 expand(acct.oab.ac_utime);
364 dtmp = MINT(cpu);
365 pcmt.pcm_cpu[PRIME] = dtmp * ratio;
366 pcmt.pcm_cpu[NONPRIME] = (ratio == 1.0) ? 0.0 :
367 (dtmp - pcmt.pcm_cpu[PRIME]);
368 real = expand(acct.oab.ac_etime);
369 dtmp = MINT(real);
370 pcmt.pcm_real[PRIME] = dtmp * ratio;
371 pcmt.pcm_real[NONPRIME] = (ratio == 1.0) ? 0.0 :
372 (dtmp - pcmt.pcm_real[PRIME]);
373 mem = expand(acct.oab.ac_mem);
374 dtmp = MINT(KCORE(mem));
375 pcmt.pcm_kcore[PRIME] = dtmp * ratio;
376 pcmt.pcm_kcore[NONPRIME] = (ratio == 1.0) ? 0.0 :
377 (dtmp - pcmt.pcm_kcore[PRIME]);
378 ltmp = expand(acct.oab.ac_io);
379 pcmt.pcm_io[PRIME] = (double)ltmp * ratio;
380 pcmt.pcm_io[NONPRIME] = (ratio == 1.0) ? 0.0 :
381 ((double)ltmp - pcmt.pcm_io[PRIME]);
382 ltmp = expand(acct.oab.ac_rw);
383 pcmt.pcm_rw[PRIME] = (double)ltmp * ratio;
384 pcmt.pcm_rw[NONPRIME] = (ratio == 1.0) ? 0.0 :
385 ((double)ltmp - pcmt.pcm_rw[PRIME]);
386 enter(&pcmt);
387 }
388
389 break;
390 case 2 :
391 while (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1) {
392 CPYN(pcmt.pcm_comm, acct.ab.ac_comm);
393 /*
394 ** Approximate P/NP split as same as elapsed time
395 */
396 if((etime = SECS(expand(acct.ab.ac_etime))) == 0)
397 etime = 1;
398 if(pnpsplit(acct.ab.ac_btime, etime, elaps) == 0) {
399 fprintf(stderr, "acctcms: could not calculate prime/non-prime hours\n");
400 exit(1);
401 }
402 ratio = (double)elaps[PRIME]/(double)etime;
403 if(elaps[PRIME] > elaps[NONPRIME]) {
404 pcmt.pcm_pc[PRIME] = 1;
405 pcmt.pcm_pc[NONPRIME] = 0;
406 } else {
407 pcmt.pcm_pc[PRIME] = 0;
408 pcmt.pcm_pc[NONPRIME] = 1;
409 }
410 cpu = expand(acct.ab.ac_stime)+
411 expand(acct.ab.ac_utime);
412 dtmp = MINT(cpu);
413 pcmt.pcm_cpu[PRIME] = dtmp * ratio;
414 pcmt.pcm_cpu[NONPRIME] = (ratio == 1.0) ? 0.0 :
415 (dtmp - pcmt.pcm_cpu[PRIME]);
416 real = expand(acct.ab.ac_etime);
417 dtmp = MINT(real);
418 pcmt.pcm_real[PRIME] = dtmp * ratio;
419 pcmt.pcm_real[NONPRIME] = (ratio == 1.0) ? 0.0 :
420 (dtmp - pcmt.pcm_real[PRIME]);
421 mem = expand(acct.ab.ac_mem);
422 dtmp = MINT(KCORE(mem));
423 pcmt.pcm_kcore[PRIME] = dtmp * ratio;
424 pcmt.pcm_kcore[NONPRIME] = (ratio == 1.0) ? 0.0 :
425 (dtmp - pcmt.pcm_kcore[PRIME]);
426 ltmp = expand(acct.ab.ac_io);
427 pcmt.pcm_io[PRIME] = (double)ltmp * ratio;
428 pcmt.pcm_io[NONPRIME] = (ratio == 1.0) ? 0.0 :
429 ((double)ltmp - pcmt.pcm_io[PRIME]);
430 ltmp = expand(acct.ab.ac_rw);
431 pcmt.pcm_rw[PRIME] = (double)ltmp * ratio;
432 pcmt.pcm_rw[NONPRIME] = (ratio == 1.0) ? 0.0 :
433 ((double)ltmp - pcmt.pcm_rw[PRIME]);
434 enter(&pcmt);
435 }
436
437 break;
438 }
439 }
440 }
441
442 int
tenter(struct tcms * p)443 tenter(struct tcms *p)
444 {
445 int i;
446 int j;
447 struct tcms *ntcm;
448 for (i = j = 0; j < sizeof(p->tcm_comm); j++) {
449 if (p->tcm_comm[j] && p->tcm_comm[j] <= 037)
450 p->tcm_comm[j] = '?';
451 i = i*7 + p->tcm_comm[j]; /* hash function */
452 }
453 if (i < 0)
454 i = -i;
455 for (i %= csize, j = 0; tcm[i].tcm_comm[0] && j != csize; i = (i+1)%csize, j++)
456 if (EQN(p->tcm_comm, tcm[i].tcm_comm))
457 break;
458 if(j == csize) {
459 if ((ntcm = (struct tcms *) realloc(tcm,
460 (csize + CSIZE - 1) * sizeof (struct tcms))) == NULL) {
461 fprintf(stderr,
462 "acctcms: Cannot reallocate memory (tcm)\n");
463 return(-1);
464 } else {
465 memset(&ntcm[csize], 0, CSIZE - 1);
466 tcm = ntcm;
467 if (!EQN(p->tcm_comm, tcm[i].tcm_comm))
468 i = csize;
469 csize = csize + CSIZE - 1;
470 }
471 }
472 if (tcm[i].tcm_comm[0] == 0)
473 CPYN(tcm[i].tcm_comm, p->tcm_comm);
474 tcmadd(&tcm[i], p);
475 return(i);
476 }
477
478 int
enter(struct pcms * p)479 enter(struct pcms *p)
480 {
481 int i;
482 int j;
483 struct pcms *npcm;
484 for (i = j = 0; j < sizeof(p->pcm_comm); j++) {
485 if (p->pcm_comm[j] && p->pcm_comm[j] <= 037)
486 p->pcm_comm[j] = '?';
487 i = i*7 + p->pcm_comm[j]; /* hash function */
488 }
489 if (i < 0)
490 i = -i;
491 for (i %= csize, j = 0; pcm[i].pcm_comm[0] && j != csize; i = (i+1)%csize, j++)
492 if (EQN(p->pcm_comm, pcm[i].pcm_comm))
493 break;
494 if(j == csize) {
495 if ((npcm = (struct pcms *) realloc(pcm,
496 (csize + CSIZE - 1) * sizeof (struct pcms))) == NULL) {
497 fprintf(stderr,
498 "acctcms: Cannot reallocate memory (pcm)\n");
499 return(-1);
500 } else {
501 memset(&npcm[csize], 0, CSIZE - 1);
502 pcm = npcm;
503 if (!EQN(p->pcm_comm, pcm[i].pcm_comm))
504 i = csize;
505 csize = csize + CSIZE - 1;
506 }
507 }
508 if (pcm[i].pcm_comm[0] == 0)
509 CPYN(pcm[i].pcm_comm, p->pcm_comm);
510 pcmadd(&pcm[i], p);
511 return(i);
512 }
513
514 void
tfixjunk(void)515 tfixjunk(void) /* combine commands used only once */
516 {
517 int i, j;
518 j = tenter(&tcmtmp);
519 for (i = 0; i < csize; i++)
520 if (i != j && tcm[i].tcm_comm[0] && tcm[i].tcm_pc <= 1) {
521 tcmadd(&tcm[j], &tcm[i]);
522 tcm[i].tcm_comm[0] = 0;
523 }
524 }
525
526 void
fixjunk(void)527 fixjunk(void) /* combine commands used only once */
528 {
529 int i, j;
530 j = enter(&pcmtmp);
531 for (i = 0; i < csize; i++)
532 if (i != j && pcm[i].pcm_comm[0] && (pcm[i].pcm_pc[PRIME] + pcm[i].pcm_pc[NONPRIME]) <= 1) {
533 pcmadd(&pcm[j], &pcm[i]);
534 pcm[i].pcm_comm[0] = 0;
535 }
536 }
537
538 void
tcmadd(struct tcms * p1,struct tcms * p2)539 tcmadd(struct tcms *p1, struct tcms *p2)
540 {
541 p1->tcm_pc += p2->tcm_pc;
542 p1->tcm_cpu = p1->tcm_cpu + p2->tcm_cpu;
543 p1->tcm_real = p1->tcm_real + p2->tcm_real;
544 p1->tcm_kcore = p1->tcm_kcore + p2->tcm_kcore;
545 p1->tcm_io += p2->tcm_io;
546 p1->tcm_rw += p2->tcm_rw;
547 }
548
549 void
pcmadd(struct pcms * p1,struct pcms * p2)550 pcmadd(struct pcms *p1, struct pcms *p2)
551 {
552 p1->pcm_pc[PRIME] += p2->pcm_pc[PRIME];
553 p1->pcm_pc[NONPRIME] += p2->pcm_pc[NONPRIME];
554 p1->pcm_cpu[PRIME] += p2->pcm_cpu[PRIME];
555 p1->pcm_cpu[NONPRIME] += p2->pcm_cpu[NONPRIME];
556 p1->pcm_real[PRIME] += p2->pcm_real[PRIME];
557 p1->pcm_real[NONPRIME] += p2->pcm_real[NONPRIME];
558 p1->pcm_kcore[PRIME] += p2->pcm_kcore[PRIME];
559 p1->pcm_kcore[NONPRIME] += p2->pcm_kcore[NONPRIME];
560 p1->pcm_io[PRIME] += p2->pcm_io[PRIME];
561 p1->pcm_io[NONPRIME] += p2->pcm_io[NONPRIME];
562 p1->pcm_rw[PRIME] += p2->pcm_rw[PRIME];
563 p1->pcm_rw[NONPRIME] += p2->pcm_rw[NONPRIME];
564 }
565
566 void
tsqueeze(void)567 tsqueeze(void) /* get rid of holes in hash table */
568 {
569 int i, k;
570
571 for (i = k = 0; i < csize; i++)
572 if (tcm[i].tcm_comm[0]) {
573 CPYN(tcm[k].tcm_comm, tcm[i].tcm_comm);
574 tcm[k].tcm_pc = tcm[i].tcm_pc;
575 tcm[k].tcm_cpu = tcm[i].tcm_cpu;
576 tcm[k].tcm_real = tcm[i].tcm_real;
577 tcm[k].tcm_kcore = tcm[i].tcm_kcore;
578 tcm[k].tcm_io = tcm[i].tcm_io;
579 tcm[k].tcm_rw = tcm[i].tcm_rw;
580 k++;
581 }
582 csize = k;
583 }
584
585 void
squeeze(void)586 squeeze(void) /* get rid of holes in hash table */
587 {
588 int i, k;
589
590 for (i = k = 0; i < csize; i++)
591 if (pcm[i].pcm_comm[0]) {
592 CPYN(pcm[k].pcm_comm, pcm[i].pcm_comm);
593 pcm[k].pcm_pc[PRIME] = pcm[i].pcm_pc[PRIME];
594 pcm[k].pcm_pc[NONPRIME] = pcm[i].pcm_pc[NONPRIME];
595 pcm[k].pcm_cpu[PRIME] = pcm[i].pcm_cpu[PRIME];
596 pcm[k].pcm_cpu[NONPRIME] = pcm[i].pcm_cpu[NONPRIME];
597 pcm[k].pcm_real[PRIME] = pcm[i].pcm_real[PRIME];
598 pcm[k].pcm_real[NONPRIME] = pcm[i].pcm_real[NONPRIME];
599 pcm[k].pcm_kcore[PRIME] = pcm[i].pcm_kcore[PRIME];
600 pcm[k].pcm_kcore[NONPRIME] = pcm[i].pcm_kcore[NONPRIME];
601 pcm[k].pcm_io[PRIME] = pcm[i].pcm_io[PRIME];
602 pcm[k].pcm_io[NONPRIME] = pcm[i].pcm_io[NONPRIME];
603 pcm[k].pcm_rw[PRIME] = pcm[i].pcm_rw[PRIME];
604 pcm[k].pcm_rw[NONPRIME] = pcm[i].pcm_rw[NONPRIME];
605 k++;
606 }
607 csize = k;
608 }
609
610 int
tccmp(struct tcms * p1,struct tcms * p2)611 tccmp(struct tcms *p1, struct tcms *p2)
612 {
613 if (p1->tcm_cpu == p2->tcm_cpu)
614 return(0);
615 return ((p2->tcm_cpu > p1->tcm_cpu)? 1 : -1);
616 }
617
618 int
ccmp(struct pcms * p1,struct pcms * p2)619 ccmp(struct pcms *p1, struct pcms *p2)
620 {
621 int index;
622
623 if( (pflg && oflg) || (!pflg && !oflg) ) {
624 if (p1->pcm_cpu[PRIME] + p1->pcm_cpu[NONPRIME] == p2->pcm_cpu[PRIME] + p2->pcm_cpu[NONPRIME])
625 return(0);
626 return ((p2->pcm_cpu[PRIME] + p2->pcm_cpu[NONPRIME] > p1->pcm_cpu[PRIME] + p1->pcm_cpu[NONPRIME])? 1 : -1);
627 }
628 index = pflg ? PRIME : NONPRIME;
629 if (p1->pcm_cpu[index] == p2->pcm_cpu[index])
630 return(0);
631 return ((p2->pcm_cpu[index] > p1->pcm_cpu[index])? 1 : -1);
632 }
633
634 int
tkcmp(struct tcms * p1,struct tcms * p2)635 tkcmp(struct tcms *p1, struct tcms *p2)
636 {
637 if (p1->tcm_kcore == p2->tcm_kcore)
638 return(0);
639 return ((p2->tcm_kcore > p1->tcm_kcore)? 1 : -1);
640 }
641
642 int
kcmp(struct pcms * p1,struct pcms * p2)643 kcmp(struct pcms *p1, struct pcms *p2)
644 {
645 int index;
646
647 if( (pflg && oflg) || (!pflg && !pflg) ){
648 if (p1->pcm_kcore[PRIME] + p1->pcm_kcore[NONPRIME] == p2->pcm_kcore[PRIME] + p2->pcm_kcore[NONPRIME])
649 return(0);
650 return ((p2->pcm_kcore[PRIME] + p2->pcm_kcore[NONPRIME] > p1->pcm_kcore[PRIME] + p1->pcm_kcore[NONPRIME])? 1 : -1);
651 }
652 index = pflg ? PRIME : NONPRIME;
653 if (p1->pcm_kcore[index] == p2->pcm_kcore[index])
654 return(0);
655 return ((p2->pcm_kcore[index] > p1->pcm_kcore[index])? 1 : -1);
656 }
657
658 int
tncmp(struct tcms * p1,struct tcms * p2)659 tncmp(struct tcms *p1, struct tcms *p2)
660 {
661 if (p1->tcm_pc == p2->tcm_pc)
662 return(0);
663 return ((p2->tcm_pc > p1->tcm_pc)? 1 : -1);
664 }
665
666 int
ncmp(struct pcms * p1,struct pcms * p2)667 ncmp(struct pcms *p1, struct pcms *p2)
668 {
669 int index;
670
671 if( (pflg && oflg) || (!pflg && !oflg) ) {
672 if (p1->pcm_pc[PRIME] + p1->pcm_pc[NONPRIME] == p2->pcm_pc[PRIME] + p2->pcm_pc[NONPRIME])
673 return(0);
674 return ((p2->pcm_pc[PRIME] + p2->pcm_pc[NONPRIME] > p1->pcm_pc[PRIME] + p1->pcm_pc[NONPRIME])? 1 : -1);
675 }
676 index = pflg ? PRIME : NONPRIME;
677 if (p1->pcm_pc[index] == p2->pcm_pc[index])
678 return(0);
679 return ((p2->pcm_pc[index] > p1->pcm_pc[index])? 1 : -1);
680 }
681
682 char thd1[] =
683 "COMMAND NUMBER TOTAL TOTAL TOTAL MEAN MEAN HOG CHARS BLOCKS\n";
684 char thd2[] =
685 "NAME CMDS KCOREMIN CPU-MIN REAL-MIN SIZE-K CPU-MIN FACTOR TRNSFD READ\n";
686
687 void
toutpta(void)688 toutpta(void)
689 {
690 int i;
691
692 printf(thd1);
693 printf(thd2);
694 printf("\n");
695 for (i = 0; i < csize; i++)
696 tcmadd(&tcmtmp, &tcm[i]);
697 CPYN(tcmtmp.tcm_comm, "TOTALS");
698 tprint(&tcmtmp);
699 printf("\n");
700 for (i = 0; i < csize; i++)
701 tprint(&tcm[i]);
702 }
703
704 void
tprint(struct tcms * p)705 tprint(struct tcms *p)
706 {
707 printf("%-8.8s", p->tcm_comm);
708 printf(" %7ld", p->tcm_pc);
709 printf(" %11.2f", p->tcm_kcore);
710 printf(" %10.2f", p->tcm_cpu);
711 printf(" %12.2f", p->tcm_real);
712 if(p->tcm_cpu == 0) p->tcm_cpu = 1;
713 printf(" %6.2f", p->tcm_kcore/p->tcm_cpu);
714 if(p->tcm_pc == 0) p->tcm_pc = 1;
715 printf(" %7.2f", p->tcm_cpu/p->tcm_pc);
716 if (p->tcm_real == 0)
717 p->tcm_real = 1;
718 printf(" %8.2f", p->tcm_cpu/p->tcm_real);
719 printf(" %11lu", p->tcm_io);
720 printf(" %11lu\n", p->tcm_rw);
721 }
722
723 void
toutptc(void)724 toutptc(void)
725 {
726 int i;
727
728 for (i = 0; i < csize; i++)
729 fwrite(&tcm[i], sizeof(tcm[i]), 1, stdout);
730 }
731
732 char hd1[] =
733 "COMMAND NUMBER TOTAL TOTAL TOTAL MEAN MEAN HOG CHARS BLOCKS\n";
734 char hd2[] =
735 "NAME CMDS KCOREMIN CPU-MIN REAL-MIN SIZE-K CPU-MIN FACTOR TRNSFD READ\n";
736 char hd3[] =
737 "COMMAND NUMBER TOTAL CPU-MIN REAL-MIN MEAN MEAN HOG CHARS BLOCKS\n";
738 char hd4[] =
739 "NAME (P) (NP) KCOREMIN (P) (NP) (P) (NP) SIZE-K CPU-MIN FACTOR TRNSFD READ\n";
740 char hdprime[] =
741 " PRIME TIME COMMAND SUMMARY\n";
742 char hdnonprime[] =
743 " NON-PRIME TIME COMMAND SUMMARY\n";
744 char hdtot[] =
745 " TOTAL COMMAND SUMMARY\n";
746 char hdp[] =
747 " PRIME/NON-PRIME TIME COMMAND SUMMARY\n";
748
749 void
outputa(void)750 outputa(void)
751 {
752 int i;
753
754 if( pflg && oflg ) printf(hdp);
755 else if(pflg) printf(hdprime);
756 else if(oflg) printf(hdnonprime);
757 else printf(hdtot);
758 if( (!pflg && !oflg) || (pflg ^ oflg)) {
759 printf(hd1);
760 printf(hd2);
761 }
762 else {
763 printf(hd3);
764 printf(hd4);
765 }
766 printf("\n");
767 for (i = 0; i < csize; i++)
768 pcmadd(&pcmtmp, &pcm[i]);
769 CPYN(pcmtmp.pcm_comm, "TOTALS");
770 print(&pcmtmp);
771 printf("\n");
772 for (i = 0; i < csize; i++)
773 print(&pcm[i]);
774 }
775
776 void
print(struct pcms * p)777 print(struct pcms *p)
778 {
779 if(pflg && oflg) pprint(p);
780 else if(pflg || oflg) prnt(p, pflg ? PRIME : NONPRIME);
781 else totprnt(p);
782 }
783
784 void
prnt(struct pcms * p,int hr)785 prnt(struct pcms *p, int hr)
786 {
787 if(p->pcm_pc[hr] == 0) return;
788 printf(fmtcmd, p->pcm_comm);
789 printf(fmtcnt, p->pcm_pc[hr]);
790 printf(fmtkcore, p->pcm_kcore[hr]);
791 printf(fmtcpu, p->pcm_cpu[hr]);
792 printf(fmtreal, p->pcm_real[hr]);
793 if(p->pcm_cpu[hr] == 0) p->pcm_cpu[hr] = 1;
794 printf(fmtmsz, p->pcm_kcore[hr]/p->pcm_cpu[hr]);
795 if(p->pcm_pc[hr] == 0) p->pcm_pc[hr] = 1;
796 printf(fmtmcpu, p->pcm_cpu[hr]/p->pcm_pc[hr]);
797 if (p->pcm_real[hr] == 0)
798 p->pcm_real[hr] = 1;
799 printf(fmthog, p->pcm_cpu[hr]/p->pcm_real[hr]);
800 printf(fmtcharx,p->pcm_io[hr]);
801 printf(fmtblkx,p->pcm_rw[hr]);
802 printf("\n");
803 }
804
805 void
pprint(struct pcms * p)806 pprint(struct pcms *p)
807 {
808 printf(fmtcmd, p->pcm_comm);
809 printf(fmtcnt, p->pcm_pc[PRIME]);
810 printf(fmtcnt, p->pcm_pc[NONPRIME]);
811 printf(fmtkcore, TOTAL(p->pcm_kcore));
812 printf(fmtcpu, p->pcm_cpu[PRIME]);
813 printf(fmtcpu, p->pcm_cpu[NONPRIME]);
814 printf(fmtreal, p->pcm_real[PRIME]);
815 printf(fmtreal, p->pcm_real[NONPRIME]);
816 if(TOTAL(p->pcm_cpu) == 0) p->pcm_cpu[PRIME] = 1;
817 printf(fmtmsz, TOTAL(p->pcm_kcore)/TOTAL(p->pcm_cpu));
818 if(TOTAL(p->pcm_pc) == 0) p->pcm_pc[PRIME] = 1;
819 printf(fmtmcpu, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_pc));
820 if ( TOTAL(p->pcm_real) == 0)
821 p->pcm_real[PRIME] = 1;
822 printf(fmthog, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_real));
823 printf(fmtcharx,TOTAL(p->pcm_io));
824 printf(fmtblkx, TOTAL(p->pcm_rw));
825 printf("\n");
826 }
827
828 void
totprnt(struct pcms * p)829 totprnt(struct pcms *p)
830 {
831 printf(fmtcmd, p->pcm_comm);
832 printf(fmtcnt, TOTAL(p->pcm_pc));
833 printf(fmtkcore, TOTAL(p->pcm_kcore));
834 printf(fmtcpu, TOTAL(p->pcm_cpu));
835 printf(fmtreal, TOTAL(p->pcm_real));
836 if(TOTAL(p->pcm_cpu) == 0) p->pcm_cpu[PRIME] = 1;
837 printf(fmtmsz, TOTAL(p->pcm_kcore)/TOTAL(p->pcm_cpu));
838 if(TOTAL(p->pcm_pc) == 0) p->pcm_pc[PRIME] = 1;
839 printf(fmtmcpu, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_pc));
840 if (TOTAL(p->pcm_real) == 0)
841 p->pcm_real[PRIME] = 1;
842 printf(fmthog, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_real));
843 printf(fmtcharx,TOTAL(p->pcm_io));
844 printf(fmtblkx,TOTAL(p->pcm_rw));
845 printf("\n");
846 }
847
848 void
outputc(void)849 outputc(void)
850 {
851 int i;
852
853 for (i = 0; i < csize; i++)
854 fwrite(&pcm[i], sizeof(pcm[i]), 1, stdout);
855 }
856