xref: /titanic_44/usr/src/cmd/csh/sh.time.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
8*7c478bd9Sstevel@tonic-gate 
9*7c478bd9Sstevel@tonic-gate /*
10*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
11*7c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley Software License Agreement
12*7c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
13*7c478bd9Sstevel@tonic-gate  */
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #include "sh.h"
18*7c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate void ruadd(struct rusage *ru, struct rusage *ru2);
21*7c478bd9Sstevel@tonic-gate void prusage(struct rusage *r0, struct rusage *r1, struct timeval *e,
22*7c478bd9Sstevel@tonic-gate 	struct timeval *b);
23*7c478bd9Sstevel@tonic-gate void pdeltat(struct timeval *t1, struct timeval *t0);
24*7c478bd9Sstevel@tonic-gate void tvadd(struct timeval *tsum, struct timeval *t0);
25*7c478bd9Sstevel@tonic-gate void tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0);
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * C Shell - routines handling process timing and niceing
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate void
32*7c478bd9Sstevel@tonic-gate settimes()
33*7c478bd9Sstevel@tonic-gate {
34*7c478bd9Sstevel@tonic-gate 	struct rusage ruch;
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #ifdef TRACE
37*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- settimes()\n");
38*7c478bd9Sstevel@tonic-gate #endif
39*7c478bd9Sstevel@tonic-gate 	(void) gettimeofday(&time0, (struct timezone *)0);
40*7c478bd9Sstevel@tonic-gate 	(void) getrusage(RUSAGE_SELF, &ru0);
41*7c478bd9Sstevel@tonic-gate 	(void) getrusage(RUSAGE_CHILDREN, &ruch);
42*7c478bd9Sstevel@tonic-gate 	ruadd(&ru0, &ruch);
43*7c478bd9Sstevel@tonic-gate }
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate /*
46*7c478bd9Sstevel@tonic-gate  * dotime is only called if it is truly a builtin function and not a
47*7c478bd9Sstevel@tonic-gate  * prefix to another command
48*7c478bd9Sstevel@tonic-gate  */
49*7c478bd9Sstevel@tonic-gate void
50*7c478bd9Sstevel@tonic-gate dotime()
51*7c478bd9Sstevel@tonic-gate {
52*7c478bd9Sstevel@tonic-gate 	struct timeval timedol;
53*7c478bd9Sstevel@tonic-gate 	struct rusage ru1, ruch;
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate #ifdef TRACE
56*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- dotime()\n");
57*7c478bd9Sstevel@tonic-gate #endif
58*7c478bd9Sstevel@tonic-gate 	(void) getrusage(RUSAGE_SELF, &ru1);
59*7c478bd9Sstevel@tonic-gate 	(void) getrusage(RUSAGE_CHILDREN, &ruch);
60*7c478bd9Sstevel@tonic-gate 	ruadd(&ru1, &ruch);
61*7c478bd9Sstevel@tonic-gate 	(void) gettimeofday(&timedol, (struct timezone *)0);
62*7c478bd9Sstevel@tonic-gate 	prusage(&ru0, &ru1, &timedol, &time0);
63*7c478bd9Sstevel@tonic-gate }
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate /*
66*7c478bd9Sstevel@tonic-gate  * donice is only called when it's on the line by itself or with a +- value
67*7c478bd9Sstevel@tonic-gate  */
68*7c478bd9Sstevel@tonic-gate void
69*7c478bd9Sstevel@tonic-gate donice(tchar **v)
70*7c478bd9Sstevel@tonic-gate {
71*7c478bd9Sstevel@tonic-gate 	tchar *cp;
72*7c478bd9Sstevel@tonic-gate 	int nval;
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate #ifdef TRACE
75*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- donice()\n");
76*7c478bd9Sstevel@tonic-gate #endif
77*7c478bd9Sstevel@tonic-gate 	v++;
78*7c478bd9Sstevel@tonic-gate 	cp = *v++;
79*7c478bd9Sstevel@tonic-gate 	if (cp == 0) {
80*7c478bd9Sstevel@tonic-gate 		nval = 4;
81*7c478bd9Sstevel@tonic-gate 	} else if (*v == 0 && (cp[0] == '+' || cp[0] == '-')) {
82*7c478bd9Sstevel@tonic-gate 		nval = getn(cp);
83*7c478bd9Sstevel@tonic-gate 	}
84*7c478bd9Sstevel@tonic-gate 	(void) setpriority(PRIO_PROCESS, 0, nval);
85*7c478bd9Sstevel@tonic-gate }
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate void
88*7c478bd9Sstevel@tonic-gate ruadd(struct rusage *ru, struct rusage *ru2)
89*7c478bd9Sstevel@tonic-gate {
90*7c478bd9Sstevel@tonic-gate 	long *lp, *lp2;
91*7c478bd9Sstevel@tonic-gate 	int cnt;
92*7c478bd9Sstevel@tonic-gate 	/*
93*7c478bd9Sstevel@tonic-gate 	 * The SunOS 4.x <sys/rusage.h> has ru_first and ru_last #defines
94*7c478bd9Sstevel@tonic-gate 	 * as below.
95*7c478bd9Sstevel@tonic-gate 	 * The SVR4/POSIX <sys/resource.h> does not have these defined for
96*7c478bd9Sstevel@tonic-gate 	 * struct rusage
97*7c478bd9Sstevel@tonic-gate 	 * The #defines below are here so that the original csh logic
98*7c478bd9Sstevel@tonic-gate 	 * for ruadd remains clear now that there is no longer a private copy
99*7c478bd9Sstevel@tonic-gate 	 * of the old <sys/resource.h>
100*7c478bd9Sstevel@tonic-gate 	 */
101*7c478bd9Sstevel@tonic-gate #define	ru_first ru_ixrss
102*7c478bd9Sstevel@tonic-gate #define	ru_last ru_nivcsw
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate #ifdef TRACE
105*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- ruadd()\n");
106*7c478bd9Sstevel@tonic-gate #endif
107*7c478bd9Sstevel@tonic-gate 	tvadd(&ru->ru_utime, &ru2->ru_utime);
108*7c478bd9Sstevel@tonic-gate 	tvadd(&ru->ru_stime, &ru2->ru_stime);
109*7c478bd9Sstevel@tonic-gate 	if (ru2->ru_maxrss > ru->ru_maxrss) {
110*7c478bd9Sstevel@tonic-gate 		ru->ru_maxrss = ru2->ru_maxrss;
111*7c478bd9Sstevel@tonic-gate 	}
112*7c478bd9Sstevel@tonic-gate 	cnt = &ru->ru_last - &ru->ru_first + 1;
113*7c478bd9Sstevel@tonic-gate 	lp = &ru->ru_first;
114*7c478bd9Sstevel@tonic-gate 	lp2 = &ru2->ru_first;
115*7c478bd9Sstevel@tonic-gate 	do {
116*7c478bd9Sstevel@tonic-gate 		*lp++ += *lp2++;
117*7c478bd9Sstevel@tonic-gate 	} while (--cnt > 0);
118*7c478bd9Sstevel@tonic-gate }
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate void
121*7c478bd9Sstevel@tonic-gate prusage(struct rusage *r0, struct rusage *r1, struct timeval *e,
122*7c478bd9Sstevel@tonic-gate 	struct timeval *b)
123*7c478bd9Sstevel@tonic-gate {
124*7c478bd9Sstevel@tonic-gate #define	pgtok(p)	((p * pgsize) / 1024)
125*7c478bd9Sstevel@tonic-gate 	static int	pgsize;
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	time_t t =
128*7c478bd9Sstevel@tonic-gate 	    (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
129*7c478bd9Sstevel@tonic-gate 	    (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
130*7c478bd9Sstevel@tonic-gate 	    (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
131*7c478bd9Sstevel@tonic-gate 	    (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
132*7c478bd9Sstevel@tonic-gate 	tchar *cp;
133*7c478bd9Sstevel@tonic-gate 	int i;
134*7c478bd9Sstevel@tonic-gate 	struct varent *vp = adrof(S_time);
135*7c478bd9Sstevel@tonic-gate 	int ms =
136*7c478bd9Sstevel@tonic-gate 	    (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000;
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate #ifdef TRACE
139*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- prusage()\n");
140*7c478bd9Sstevel@tonic-gate #endif
141*7c478bd9Sstevel@tonic-gate 	if (pgsize == 0) {
142*7c478bd9Sstevel@tonic-gate 		pgsize = getpagesize();
143*7c478bd9Sstevel@tonic-gate 	}
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	cp = S_USAGEFORMAT;	/* "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww" */
146*7c478bd9Sstevel@tonic-gate 	if (vp && vp->vec[0] && vp->vec[1]) {
147*7c478bd9Sstevel@tonic-gate 		cp = vp->vec[1];
148*7c478bd9Sstevel@tonic-gate 	}
149*7c478bd9Sstevel@tonic-gate 	for (; *cp; cp++) {
150*7c478bd9Sstevel@tonic-gate 		if (*cp != '%') {
151*7c478bd9Sstevel@tonic-gate 			Putchar(*cp);
152*7c478bd9Sstevel@tonic-gate 		} else if (cp[1]) {
153*7c478bd9Sstevel@tonic-gate 			switch (*++cp) {
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 			case 'U':
156*7c478bd9Sstevel@tonic-gate 				pdeltat(&r1->ru_utime, &r0->ru_utime);
157*7c478bd9Sstevel@tonic-gate 				break;
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate 			case 'S':
160*7c478bd9Sstevel@tonic-gate 				pdeltat(&r1->ru_stime, &r0->ru_stime);
161*7c478bd9Sstevel@tonic-gate 				break;
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 			case 'E':
164*7c478bd9Sstevel@tonic-gate 				psecs_int(ms / 100);
165*7c478bd9Sstevel@tonic-gate 				break;
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 			case 'P':
168*7c478bd9Sstevel@tonic-gate 				printf("%d%%", (int)(t * 100 /
169*7c478bd9Sstevel@tonic-gate 				    ((ms ? ms : 1))));
170*7c478bd9Sstevel@tonic-gate 				break;
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 			case 'W':
173*7c478bd9Sstevel@tonic-gate 				i = r1->ru_nswap - r0->ru_nswap;
174*7c478bd9Sstevel@tonic-gate 				printf("%d", i);
175*7c478bd9Sstevel@tonic-gate 				break;
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 			case 'X':
178*7c478bd9Sstevel@tonic-gate 				printf("%d", t == 0 ? 0 :
179*7c478bd9Sstevel@tonic-gate 				    pgtok((r1->ru_ixrss - r0->ru_ixrss) / t));
180*7c478bd9Sstevel@tonic-gate 				break;
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 			case 'D':
183*7c478bd9Sstevel@tonic-gate 				printf("%d", t == 0 ? 0 :
184*7c478bd9Sstevel@tonic-gate 				    pgtok((r1->ru_idrss + r1->ru_isrss-
185*7c478bd9Sstevel@tonic-gate 				    (r0->ru_idrss + r0->ru_isrss)) / t));
186*7c478bd9Sstevel@tonic-gate 				break;
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 			case 'K':
189*7c478bd9Sstevel@tonic-gate 				printf("%d", t == 0 ? 0 :
190*7c478bd9Sstevel@tonic-gate 				    pgtok(((r1->ru_ixrss + r1->ru_isrss +
191*7c478bd9Sstevel@tonic-gate 				    r1->ru_idrss) - (r0->ru_ixrss +
192*7c478bd9Sstevel@tonic-gate 				    r0->ru_idrss + r0->ru_isrss)) / t));
193*7c478bd9Sstevel@tonic-gate 				break;
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 			case 'M':
196*7c478bd9Sstevel@tonic-gate 				printf("%d", r1->ru_maxrss / 2);
197*7c478bd9Sstevel@tonic-gate 				break;
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 			case 'F':
200*7c478bd9Sstevel@tonic-gate 				printf("%d", r1->ru_majflt - r0->ru_majflt);
201*7c478bd9Sstevel@tonic-gate 				break;
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 			case 'R':
204*7c478bd9Sstevel@tonic-gate 				printf("%d", r1->ru_minflt - r0->ru_minflt);
205*7c478bd9Sstevel@tonic-gate 				break;
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 			case 'I':
208*7c478bd9Sstevel@tonic-gate 				printf("%d", r1->ru_inblock - r0->ru_inblock);
209*7c478bd9Sstevel@tonic-gate 				break;
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 			case 'O':
212*7c478bd9Sstevel@tonic-gate 				printf("%d", r1->ru_oublock - r0->ru_oublock);
213*7c478bd9Sstevel@tonic-gate 				break;
214*7c478bd9Sstevel@tonic-gate 			}
215*7c478bd9Sstevel@tonic-gate 		}
216*7c478bd9Sstevel@tonic-gate 	}
217*7c478bd9Sstevel@tonic-gate 	Putchar('\n');
218*7c478bd9Sstevel@tonic-gate #undef	pgtok
219*7c478bd9Sstevel@tonic-gate }
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate void
222*7c478bd9Sstevel@tonic-gate pdeltat(struct timeval *t1, struct timeval *t0)
223*7c478bd9Sstevel@tonic-gate {
224*7c478bd9Sstevel@tonic-gate 	struct timeval td;
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate #ifdef TRACE
227*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- pdeltat()\n");
228*7c478bd9Sstevel@tonic-gate #endif
229*7c478bd9Sstevel@tonic-gate 	tvsub(&td, t1, t0);
230*7c478bd9Sstevel@tonic-gate 	/* change printf formats */
231*7c478bd9Sstevel@tonic-gate 	printf("%d.%01d", td.tv_sec, td.tv_usec / 100000);
232*7c478bd9Sstevel@tonic-gate }
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate void
235*7c478bd9Sstevel@tonic-gate tvadd(struct timeval *tsum, struct timeval *t0)
236*7c478bd9Sstevel@tonic-gate {
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate #ifdef TRACE
239*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- tvadd()\n");
240*7c478bd9Sstevel@tonic-gate #endif
241*7c478bd9Sstevel@tonic-gate 	tsum->tv_sec += t0->tv_sec;
242*7c478bd9Sstevel@tonic-gate 	tsum->tv_usec += t0->tv_usec;
243*7c478bd9Sstevel@tonic-gate 	if (tsum->tv_usec > 1000000) {
244*7c478bd9Sstevel@tonic-gate 		tsum->tv_sec++;
245*7c478bd9Sstevel@tonic-gate 		tsum->tv_usec -= 1000000;
246*7c478bd9Sstevel@tonic-gate 	}
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate void
250*7c478bd9Sstevel@tonic-gate tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0)
251*7c478bd9Sstevel@tonic-gate {
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate #ifdef TRACE
254*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- tvsub()\n");
255*7c478bd9Sstevel@tonic-gate #endif
256*7c478bd9Sstevel@tonic-gate 	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
257*7c478bd9Sstevel@tonic-gate 	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
258*7c478bd9Sstevel@tonic-gate 	if (tdiff->tv_usec < 0) {
259*7c478bd9Sstevel@tonic-gate 		tdiff->tv_sec--;
260*7c478bd9Sstevel@tonic-gate 		tdiff->tv_usec += 1000000;
261*7c478bd9Sstevel@tonic-gate 	}
262*7c478bd9Sstevel@tonic-gate }
263