xref: /csrg-svn/bin/csh/time.c (revision 10036)
1*10036Ssam /*	time.c	4.2	82/12/30	*/
21306Sbill 
31306Sbill #include "sh.h"
41306Sbill 
51306Sbill /*
61306Sbill  * C Shell - routines handling process timing and niceing
71306Sbill  */
81306Sbill struct	tms times0;
91306Sbill struct	tms timesdol;
101306Sbill 
111306Sbill settimes()
121306Sbill {
13*10036Ssam 	struct rusage ruch;
141306Sbill 
151306Sbill 	time(&time0);
16*10036Ssam 	getrusage(RUSAGE_SELF, &ru0);
17*10036Ssam 	getrusage(RUSAGE_CHILDREN, &ruch);
18*10036Ssam 	ruadd(&ru0, &ruch);
191306Sbill }
201306Sbill 
211306Sbill /*
221306Sbill  * dotime is only called if it is truly a builtin function and not a
231306Sbill  * prefix to another command
241306Sbill  */
251306Sbill dotime()
261306Sbill {
271306Sbill 	time_t timedol;
28*10036Ssam 	struct rusage ru1, ruch;
291306Sbill 
30*10036Ssam 	getrusage(RUSAGE_SELF, &ru1);
31*10036Ssam 	getrusage(RUSAGE_CHILDREN, &ruch);
32*10036Ssam 	ruadd(&ru1, &ruch);
331306Sbill 	time(&timedol);
34*10036Ssam 	prusage(&ru0, &ru1, timedol - time0);
351306Sbill }
361306Sbill 
371306Sbill /*
381306Sbill  * donice is only called when it on the line by itself or with a +- value
391306Sbill  */
401306Sbill donice(v)
411306Sbill 	register char **v;
421306Sbill {
431306Sbill 	register char *cp;
441306Sbill 
451306Sbill 	v++, cp = *v++;
461306Sbill 	if (cp == 0) {
471306Sbill #ifndef V6
481306Sbill 		nice(20);
491306Sbill 		nice(-10);
501306Sbill #endif
511306Sbill 		nice(4);
521306Sbill 	} else if (*v == 0 && any(cp[0], "+-")) {
531306Sbill #ifndef V6
541306Sbill 		nice(20);
551306Sbill 		nice(-10);
561306Sbill #endif
571306Sbill 		nice(getn(cp));
581306Sbill 	}
591306Sbill }
601306Sbill 
61*10036Ssam ruadd(ru, ru2)
62*10036Ssam 	register struct rusage *ru, *ru2;
631306Sbill {
64*10036Ssam 	register long *lp, *lp2;
65*10036Ssam 	register int cnt;
661306Sbill 
67*10036Ssam 	tvadd(&ru->ru_utime, &ru2->ru_utime);
68*10036Ssam 	tvadd(&ru->ru_stime, &ru2->ru_stime);
69*10036Ssam 	if (ru2->ru_maxrss > ru->ru_maxrss)
70*10036Ssam 		ru->ru_maxrss = ru2->ru_maxrss;
71*10036Ssam 	cnt = &ru->ru_last - &ru->ru_first + 1;
72*10036Ssam 	lp = &ru->ru_first; lp2 = &ru2->ru_first;
73*10036Ssam 	do
74*10036Ssam 		*lp++ += *lp2++;
75*10036Ssam 	while (--cnt > 0);
761306Sbill }
771306Sbill 
78*10036Ssam prusage(r0, r1, sec)
79*10036Ssam 	register struct rusage *r0, *r1;
801306Sbill 	time_t sec;
811306Sbill {
821306Sbill 	register time_t t =
83*10036Ssam 	    (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+
84*10036Ssam 	    (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+
85*10036Ssam 	    (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+
86*10036Ssam 	    (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000;
871306Sbill 	register char *cp;
881306Sbill 	register int i;
891306Sbill 	register struct varent *vp = adrof("time");
901306Sbill 
911306Sbill 	cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
921306Sbill 	if (vp && vp->vec[0] && vp->vec[1])
931306Sbill 		cp = vp->vec[1];
941306Sbill 	for (; *cp; cp++)
951306Sbill 	if (*cp != '%')
961306Sbill 		putchar(*cp);
971306Sbill 	else if (cp[1]) switch(*++cp) {
981306Sbill 
991306Sbill 	case 'U':
100*10036Ssam 		pdeltat(&r1->ru_utime, &r0->ru_utime);
1011306Sbill 		break;
1021306Sbill 
1031306Sbill 	case 'S':
104*10036Ssam 		pdeltat(&r1->ru_stime, &r0->ru_stime);
1051306Sbill 		break;
1061306Sbill 
1071306Sbill 	case 'E':
1081306Sbill 		psecs(sec);
1091306Sbill 		break;
1101306Sbill 
1111306Sbill 	case 'P':
112*10036Ssam 		printf("%d%%", (int) (t / ((sec ? sec : 1))));
1131306Sbill 		break;
1141306Sbill 
1151306Sbill 	case 'W':
116*10036Ssam 		i = r1->ru_nswap - r0->ru_nswap;
1171306Sbill 		printf("%d", i);
1181306Sbill 		break;
1191306Sbill 
1201306Sbill 	case 'X':
121*10036Ssam 		printf("%d", t == 0 ? 0 : (r1->ru_ixrss-r0->ru_ixrss)/t);
1221306Sbill 		break;
1231306Sbill 
1241306Sbill 	case 'D':
125*10036Ssam 		printf("%d", t == 0 ? 0 :
126*10036Ssam 		    (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t);
1271306Sbill 		break;
1281306Sbill 
1291306Sbill 	case 'K':
130*10036Ssam 		printf("%d", t == 0 ? 0 :
131*10036Ssam 		    ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) -
132*10036Ssam 		    (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t);
1331306Sbill 		break;
1341306Sbill 
1351306Sbill 	case 'M':
136*10036Ssam 		printf("%d", r1->ru_maxrss/2);
1371306Sbill 		break;
1381306Sbill 
1391306Sbill 	case 'F':
140*10036Ssam 		printf("%d", r1->ru_majflt-r0->ru_majflt);
1411306Sbill 		break;
1421306Sbill 
1431306Sbill 	case 'R':
144*10036Ssam 		printf("%d", r1->ru_minflt-r0->ru_minflt);
1451306Sbill 		break;
1461306Sbill 
1471306Sbill 	case 'I':
148*10036Ssam 		printf("%d", r1->ru_inblock-r0->ru_inblock);
1491306Sbill 		break;
1501306Sbill 
1511306Sbill 	case 'O':
152*10036Ssam 		printf("%d", r1->ru_oublock-r0->ru_oublock);
1531306Sbill 		break;
1541306Sbill 	}
1551306Sbill 	putchar('\n');
1561306Sbill }
157*10036Ssam 
158*10036Ssam pdeltat(t1, t0)
159*10036Ssam 	struct timeval *t1, *t0;
160*10036Ssam {
161*10036Ssam 	struct timeval td;
162*10036Ssam 
163*10036Ssam 	tvsub(&td, t1, t0);
164*10036Ssam 	printf("%d.%01d", td.tv_sec, td.tv_usec/100000);
165*10036Ssam }
166*10036Ssam 
167*10036Ssam tvadd(tsum, t0)
168*10036Ssam 	struct timeval *tsum, *t0;
169*10036Ssam {
170*10036Ssam 
171*10036Ssam 	tsum->tv_sec += t0->tv_sec;
172*10036Ssam 	tsum->tv_usec += t0->tv_usec;
173*10036Ssam 	if (tsum->tv_usec > 1000000)
174*10036Ssam 		tsum->tv_sec++, tsum->tv_usec -= 1000000;
175*10036Ssam }
176*10036Ssam 
177*10036Ssam tvsub(tdiff, t1, t0)
178*10036Ssam 	struct timeval *tdiff, *t1, *t0;
179*10036Ssam {
180*10036Ssam 
181*10036Ssam 	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
182*10036Ssam 	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
183*10036Ssam 	if (tdiff->tv_usec < 0)
184*10036Ssam 		tdiff->tv_sec--, tdiff->tv_usec += 1000000;
185*10036Ssam }
186