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