xref: /csrg-svn/bin/csh/time.c (revision 60765)
147823Sbostic /*-
2*60765Sbostic  * Copyright (c) 1980, 1991, 1993
3*60765Sbostic  *	The Regents of the University of California.  All rights reserved.
447823Sbostic  *
547823Sbostic  * %sccs.include.redist.c%
621943Sdist  */
721943Sdist 
814476Ssam #ifndef lint
9*60765Sbostic static char sccsid[] = "@(#)time.c	8.1 (Berkeley) 05/31/93";
1047823Sbostic #endif /* not lint */
111306Sbill 
1250028Sbostic #include <sys/types.h>
1350033Schristos #if __STDC__
1450033Schristos # include <stdarg.h>
1550033Schristos #else
1650033Schristos # include <varargs.h>
1750033Schristos #endif
1850033Schristos 
1950023Sbostic #include "csh.h"
2050023Sbostic #include "extern.h"
211306Sbill 
221306Sbill /*
231306Sbill  * C Shell - routines handling process timing and niceing
241306Sbill  */
2550026Schristos static void	pdeltat __P((struct timeval *, struct timeval *));
261306Sbill 
2749992Sbostic void
settimes()281306Sbill settimes()
291306Sbill {
3049992Sbostic     struct rusage ruch;
311306Sbill 
3250028Sbostic     (void) gettimeofday(&time0, NULL);
3349992Sbostic     (void) getrusage(RUSAGE_SELF, &ru0);
3449992Sbostic     (void) getrusage(RUSAGE_CHILDREN, &ruch);
3549992Sbostic     ruadd(&ru0, &ruch);
361306Sbill }
371306Sbill 
381306Sbill /*
391306Sbill  * dotime is only called if it is truly a builtin function and not a
401306Sbill  * prefix to another command
411306Sbill  */
4249992Sbostic void
4350439Schristos /*ARGSUSED*/
dotime(v,t)4450439Schristos dotime(v, t)
4550439Schristos     Char **v;
4650439Schristos     struct command *t;
471306Sbill {
4849992Sbostic     struct timeval timedol;
4949992Sbostic     struct rusage ru1, ruch;
501306Sbill 
5149992Sbostic     (void) getrusage(RUSAGE_SELF, &ru1);
5249992Sbostic     (void) getrusage(RUSAGE_CHILDREN, &ruch);
5349992Sbostic     ruadd(&ru1, &ruch);
5450028Sbostic     (void) gettimeofday(&timedol, NULL);
5549992Sbostic     prusage(&ru0, &ru1, &timedol, &time0);
561306Sbill }
571306Sbill 
581306Sbill /*
591306Sbill  * donice is only called when it on the line by itself or with a +- value
601306Sbill  */
6149992Sbostic void
6250439Schristos /*ARGSUSED*/
donice(v,t)6350439Schristos donice(v, t)
6450439Schristos     Char **v;
6550439Schristos     struct command *t;
661306Sbill {
6749992Sbostic     register Char *cp;
6849992Sbostic     int     nval = 0;
691306Sbill 
7049992Sbostic     v++, cp = *v++;
7149992Sbostic     if (cp == 0)
7249992Sbostic 	nval = 4;
7349992Sbostic     else if (*v == 0 && any("+-", cp[0]))
7449992Sbostic 	nval = getn(cp);
7549992Sbostic     (void) setpriority(PRIO_PROCESS, 0, nval);
761306Sbill }
771306Sbill 
7849992Sbostic void
ruadd(ru,ru2)7910036Ssam ruadd(ru, ru2)
8049992Sbostic     register struct rusage *ru, *ru2;
811306Sbill {
8249992Sbostic     tvadd(&ru->ru_utime, &ru2->ru_utime);
8349992Sbostic     tvadd(&ru->ru_stime, &ru2->ru_stime);
8449992Sbostic     if (ru2->ru_maxrss > ru->ru_maxrss)
8549992Sbostic 	ru->ru_maxrss = ru2->ru_maxrss;
861306Sbill 
8749992Sbostic     ru->ru_ixrss += ru2->ru_ixrss;
8849992Sbostic     ru->ru_idrss += ru2->ru_idrss;
8949992Sbostic     ru->ru_isrss += ru2->ru_isrss;
9049992Sbostic     ru->ru_minflt += ru2->ru_minflt;
9149992Sbostic     ru->ru_majflt += ru2->ru_majflt;
9249992Sbostic     ru->ru_nswap += ru2->ru_nswap;
9349992Sbostic     ru->ru_inblock += ru2->ru_inblock;
9449992Sbostic     ru->ru_oublock += ru2->ru_oublock;
9549992Sbostic     ru->ru_msgsnd += ru2->ru_msgsnd;
9649992Sbostic     ru->ru_msgrcv += ru2->ru_msgrcv;
9749992Sbostic     ru->ru_nsignals += ru2->ru_nsignals;
9849992Sbostic     ru->ru_nvcsw += ru2->ru_nvcsw;
9949992Sbostic     ru->ru_nivcsw += ru2->ru_nivcsw;
1001306Sbill }
1011306Sbill 
10249992Sbostic void
prusage(r0,r1,e,b)10310705Ssam prusage(r0, r1, e, b)
10449992Sbostic     register struct rusage *r0, *r1;
10549992Sbostic     struct timeval *e, *b;
1061306Sbill {
10749992Sbostic     register time_t t =
10849992Sbostic     (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
10949992Sbostic     (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
11049992Sbostic     (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
11149992Sbostic     (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
11249992Sbostic     register char *cp;
11349992Sbostic     register long i;
11449992Sbostic     register struct varent *vp = adrof(STRtime);
1151306Sbill 
11649992Sbostic     int     ms =
11749992Sbostic     (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000;
11849992Sbostic 
11949992Sbostic     cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
12049992Sbostic 
12149992Sbostic     if (vp && vp->vec[0] && vp->vec[1])
12249992Sbostic 	cp = short2str(vp->vec[1]);
12350024Schristos 
12449992Sbostic     for (; *cp; cp++)
1251306Sbill 	if (*cp != '%')
12650439Schristos 	    (void) fputc(*cp, cshout);
12749992Sbostic 	else if (cp[1])
12849992Sbostic 	    switch (*++cp) {
1291306Sbill 
13049992Sbostic 	    case 'U':		/* user CPU time used */
13110036Ssam 		pdeltat(&r1->ru_utime, &r0->ru_utime);
1321306Sbill 		break;
1331306Sbill 
13449992Sbostic 	    case 'S':		/* system CPU time used */
13510036Ssam 		pdeltat(&r1->ru_stime, &r0->ru_stime);
1361306Sbill 		break;
1371306Sbill 
13849992Sbostic 	    case 'E':		/* elapsed (wall-clock) time */
13949992Sbostic 		pcsecs((long) ms);
1401306Sbill 		break;
1411306Sbill 
14249992Sbostic 	    case 'P':		/* percent time spent running */
14350024Schristos 		/* check if it did not run at all */
14450024Schristos 		i = (ms == 0) ? 0 : (t * 1000 / ms);
14550439Schristos 		/* nn.n% */
14650439Schristos 		(void) fprintf(cshout, "%ld.%01ld%%", i / 10, i % 10);
1471306Sbill 		break;
1481306Sbill 
14949992Sbostic 	    case 'W':		/* number of swaps */
15010036Ssam 		i = r1->ru_nswap - r0->ru_nswap;
15150439Schristos 		(void) fprintf(cshout, "%ld", i);
1521306Sbill 		break;
1531306Sbill 
15449992Sbostic 	    case 'X':		/* (average) shared text size */
15550439Schristos 		(void) fprintf(cshout, "%ld", t == 0 ? 0L :
15650439Schristos 			       (r1->ru_ixrss - r0->ru_ixrss) / t);
1571306Sbill 		break;
1581306Sbill 
15949992Sbostic 	    case 'D':		/* (average) unshared data size */
16050439Schristos 		(void) fprintf(cshout, "%ld", t == 0 ? 0L :
16149992Sbostic 			(r1->ru_idrss + r1->ru_isrss -
16249992Sbostic 			 (r0->ru_idrss + r0->ru_isrss)) / t);
1631306Sbill 		break;
1641306Sbill 
16549992Sbostic 	    case 'K':		/* (average) total data memory used  */
16650439Schristos 		(void) fprintf(cshout, "%ld", t == 0 ? 0L :
16749992Sbostic 			((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) -
16849992Sbostic 			 (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t);
1691306Sbill 		break;
1701306Sbill 
17149992Sbostic 	    case 'M':		/* max. Resident Set Size */
17250439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_maxrss / 2L);
1731306Sbill 		break;
1741306Sbill 
17549992Sbostic 	    case 'F':		/* page faults */
17650439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_majflt - r0->ru_majflt);
1771306Sbill 		break;
1781306Sbill 
17949992Sbostic 	    case 'R':		/* page reclaims */
18050439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_minflt - r0->ru_minflt);
1811306Sbill 		break;
1821306Sbill 
18349992Sbostic 	    case 'I':		/* FS blocks in */
18450439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_inblock - r0->ru_inblock);
1851306Sbill 		break;
1861306Sbill 
18749992Sbostic 	    case 'O':		/* FS blocks out */
18850439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_oublock - r0->ru_oublock);
1891306Sbill 		break;
19049992Sbostic 
19149992Sbostic 	    case 'r':		/* socket messages recieved */
19250439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_msgrcv - r0->ru_msgrcv);
19349992Sbostic 		break;
19449992Sbostic 
19549992Sbostic 	    case 's':		/* socket messages sent */
19650439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_msgsnd - r0->ru_msgsnd);
19749992Sbostic 		break;
19849992Sbostic 
19949992Sbostic 	    case 'k':		/* number of signals recieved */
20050439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_nsignals-r0->ru_nsignals);
20149992Sbostic 		break;
20249992Sbostic 
20349992Sbostic 	    case 'w':		/* num. voluntary context switches (waits) */
20450439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_nvcsw - r0->ru_nvcsw);
20549992Sbostic 		break;
20649992Sbostic 
20749992Sbostic 	    case 'c':		/* num. involuntary context switches */
20850439Schristos 		(void) fprintf(cshout, "%ld", r1->ru_nivcsw - r0->ru_nivcsw);
20949992Sbostic 		break;
21049992Sbostic 	    }
21150439Schristos     (void) fputc('\n', cshout);
2121306Sbill }
21310036Ssam 
21449992Sbostic static void
pdeltat(t1,t0)21510036Ssam pdeltat(t1, t0)
21649992Sbostic     struct timeval *t1, *t0;
21710036Ssam {
21849992Sbostic     struct timeval td;
21910036Ssam 
22049992Sbostic     tvsub(&td, t1, t0);
22150439Schristos     (void) fprintf(cshout, "%d.%01d", td.tv_sec, td.tv_usec / 100000);
22210036Ssam }
22310036Ssam 
22449992Sbostic void
tvadd(tsum,t0)22510036Ssam tvadd(tsum, t0)
22649992Sbostic     struct timeval *tsum, *t0;
22710036Ssam {
22810036Ssam 
22949992Sbostic     tsum->tv_sec += t0->tv_sec;
23049992Sbostic     tsum->tv_usec += t0->tv_usec;
23149992Sbostic     if (tsum->tv_usec > 1000000)
23249992Sbostic 	tsum->tv_sec++, tsum->tv_usec -= 1000000;
23310036Ssam }
23410036Ssam 
23549992Sbostic void
tvsub(tdiff,t1,t0)23610036Ssam tvsub(tdiff, t1, t0)
23749992Sbostic     struct timeval *tdiff, *t1, *t0;
23810036Ssam {
23910036Ssam 
24049992Sbostic     tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
24149992Sbostic     tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
24249992Sbostic     if (tdiff->tv_usec < 0)
24349992Sbostic 	tdiff->tv_sec--, tdiff->tv_usec += 1000000;
24410036Ssam }
24550439Schristos 
24650439Schristos #define  P2DIG(i) (void) fprintf(cshout, "%d%d", (i) / 10, (i) % 10)
24750439Schristos 
24850439Schristos void
psecs(l)24950439Schristos psecs(l)
25050439Schristos     long    l;
25150439Schristos {
25250439Schristos     register int i;
25350439Schristos 
25450439Schristos     i = l / 3600;
25550439Schristos     if (i) {
25650439Schristos 	(void) fprintf(cshout, "%d:", i);
25750439Schristos 	i = l % 3600;
25850439Schristos 	P2DIG(i / 60);
25950439Schristos 	goto minsec;
26050439Schristos     }
26150439Schristos     i = l;
26250439Schristos     (void) fprintf(cshout, "%d", i / 60);
26350439Schristos minsec:
26450439Schristos     i %= 60;
26550439Schristos     (void) fputc(':', cshout);
26650439Schristos     P2DIG(i);
26750439Schristos }
26850439Schristos 
26950439Schristos void
pcsecs(l)27050439Schristos pcsecs(l)			/* PWP: print mm:ss.dd, l is in sec*100 */
27150439Schristos     long    l;
27250439Schristos {
27350439Schristos     register int i;
27450439Schristos 
27550439Schristos     i = l / 360000;
27650439Schristos     if (i) {
27750439Schristos 	(void) fprintf(cshout, "%d:", i);
27850439Schristos 	i = (l % 360000) / 100;
27950439Schristos 	P2DIG(i / 60);
28050439Schristos 	goto minsec;
28150439Schristos     }
28250439Schristos     i = l / 100;
28350439Schristos     (void) fprintf(cshout, "%d", i / 60);
28450439Schristos minsec:
28550439Schristos     i %= 60;
28650439Schristos     (void) fputc(':', cshout);
28750439Schristos     P2DIG(i);
28850439Schristos     (void) fputc('.', cshout);
28950439Schristos     P2DIG((int) (l % 100));
29050439Schristos }
291