xref: /original-bsd/bin/csh/time.c (revision 963f8367)
1 /*-
2  * Copyright (c) 1980, 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)time.c	5.8 (Berkeley) 04/04/91";
10 #endif /* not lint */
11 
12 #include "sh.h"
13 
14 /*
15  * C Shell - routines handling process timing and niceing
16  */
17 
18 settimes()
19 {
20 	struct rusage ruch;
21 
22 	(void) gettimeofday(&time0, (struct timezone *)0);
23 	(void) getrusage(RUSAGE_SELF, &ru0);
24 	(void) getrusage(RUSAGE_CHILDREN, &ruch);
25 	ruadd(&ru0, &ruch);
26 }
27 
28 /*
29  * dotime is only called if it is truly a builtin function and not a
30  * prefix to another command
31  */
32 dotime()
33 {
34 	struct timeval timedol;
35 	struct rusage ru1, ruch;
36 
37 	(void) getrusage(RUSAGE_SELF, &ru1);
38 	(void) getrusage(RUSAGE_CHILDREN, &ruch);
39 	ruadd(&ru1, &ruch);
40 	(void) gettimeofday(&timedol, (struct timezone *)0);
41 	prusage(&ru0, &ru1, &timedol, &time0);
42 }
43 
44 /*
45  * donice is only called when it on the line by itself or with a +- value
46  */
47 donice(v)
48 	register char **v;
49 {
50 	register char *cp;
51 	int nval;
52 
53 	v++, cp = *v++;
54 	if (cp == 0)
55 		nval = 4;
56 	else if (*v == 0 && index("+-", cp[0]))
57 		nval = getn(cp);
58 	(void) setpriority(PRIO_PROCESS, 0, nval);
59 }
60 
61 ruadd(ru, ru2)
62 	register struct rusage *ru, *ru2;
63 {
64 	register long *lp, *lp2;
65 	register int cnt;
66 
67 	tvadd(&ru->ru_utime, &ru2->ru_utime);
68 	tvadd(&ru->ru_stime, &ru2->ru_stime);
69 	if (ru2->ru_maxrss > ru->ru_maxrss)
70 		ru->ru_maxrss = ru2->ru_maxrss;
71 	cnt = &ru->ru_last - &ru->ru_first + 1;
72 	lp = &ru->ru_first; lp2 = &ru2->ru_first;
73 	do
74 		*lp++ += *lp2++;
75 	while (--cnt > 0);
76 }
77 
78 prusage(r0, r1, e, b)
79 	register struct rusage *r0, *r1;
80 	struct timeval *e, *b;
81 {
82 	register time_t t =
83 	    (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+
84 	    (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+
85 	    (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+
86 	    (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000;
87 	register char *cp;
88 	register long i;
89 	register struct varent *vp = adrof("time");
90 	long ms =
91 	    (e->tv_sec-b->tv_sec)*100 + (e->tv_usec-b->tv_usec)/10000;
92 
93 	cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
94 	if (vp && vp->vec[0] && vp->vec[1])
95 		cp = vp->vec[1];
96 	for (; *cp; cp++)
97 	if (*cp != '%')
98 		cshputchar(*cp);
99 	else if (cp[1]) switch(*++cp) {
100 
101 	case 'U':
102 		pdeltat(&r1->ru_utime, &r0->ru_utime);
103 		break;
104 
105 	case 'S':
106 		pdeltat(&r1->ru_stime, &r0->ru_stime);
107 		break;
108 
109 	case 'E':
110 		psecs(ms / 100);
111 		break;
112 
113 	case 'P':
114 		printf("%d%%", (int) (t*100 / ((ms ? ms : 1))));
115 		break;
116 
117 	case 'W':
118 		i = r1->ru_nswap - r0->ru_nswap;
119 		printf("%ld", i);
120 		break;
121 
122 	case 'X':
123 		printf("%ld", t == 0 ? 0L : (r1->ru_ixrss-r0->ru_ixrss)/t);
124 		break;
125 
126 	case 'D':
127 		printf("%ld", t == 0 ? 0L :
128 		    (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t);
129 		break;
130 
131 	case 'K':
132 		printf("%ld", t == 0 ? 0L :
133 		    ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) -
134 		    (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t);
135 		break;
136 
137 	case 'M':
138 		printf("%ld", r1->ru_maxrss/2);
139 		break;
140 
141 	case 'F':
142 		printf("%ld", r1->ru_majflt-r0->ru_majflt);
143 		break;
144 
145 	case 'R':
146 		printf("%ld", r1->ru_minflt-r0->ru_minflt);
147 		break;
148 
149 	case 'I':
150 		printf("%ld", r1->ru_inblock-r0->ru_inblock);
151 		break;
152 
153 	case 'O':
154 		printf("%ld", r1->ru_oublock-r0->ru_oublock);
155 		break;
156 	}
157 	cshputchar('\n');
158 }
159 
160 pdeltat(t1, t0)
161 	struct timeval *t1, *t0;
162 {
163 	struct timeval td;
164 
165 	tvsub(&td, t1, t0);
166 	printf("%d.%01d", td.tv_sec, td.tv_usec/100000);
167 }
168 
169 tvadd(tsum, t0)
170 	struct timeval *tsum, *t0;
171 {
172 
173 	tsum->tv_sec += t0->tv_sec;
174 	tsum->tv_usec += t0->tv_usec;
175 	if (tsum->tv_usec > 1000000)
176 		tsum->tv_sec++, tsum->tv_usec -= 1000000;
177 }
178 
179 tvsub(tdiff, t1, t0)
180 	struct timeval *tdiff, *t1, *t0;
181 {
182 
183 	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
184 	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
185 	if (tdiff->tv_usec < 0)
186 		tdiff->tv_sec--, tdiff->tv_usec += 1000000;
187 }
188