support for multiple : modifiers
[unix-history] / usr / src / bin / csh / time.c
CommitLineData
ecc449eb
KB
1/*-
2 * Copyright (c) 1980, 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
b79f4fa9
DF
6 */
7
f6227721 8#ifndef lint
454c2aa3 9static char sccsid[] = "@(#)time.c 5.15 (Berkeley) %G%";
ecc449eb 10#endif /* not lint */
35867765 11
b9c4f741 12#include <sys/types.h>
4df6491c
CZ
13#if __STDC__
14# include <stdarg.h>
15#else
16# include <varargs.h>
17#endif
18
4d7b2685
KB
19#include "csh.h"
20#include "extern.h"
35867765
BJ
21
22/*
23 * C Shell - routines handling process timing and niceing
24 */
ec56134b 25static void pdeltat __P((struct timeval *, struct timeval *));
35867765 26
6e37afca 27void
35867765
BJ
28settimes()
29{
6e37afca 30 struct rusage ruch;
35867765 31
b9c4f741 32 (void) gettimeofday(&time0, NULL);
6e37afca
KB
33 (void) getrusage(RUSAGE_SELF, &ru0);
34 (void) getrusage(RUSAGE_CHILDREN, &ruch);
35 ruadd(&ru0, &ruch);
35867765
BJ
36}
37
38/*
39 * dotime is only called if it is truly a builtin function and not a
40 * prefix to another command
41 */
6e37afca 42void
454c2aa3
CZ
43/*ARGSUSED*/
44dotime(v, t)
45 Char **v;
46 struct command *t;
35867765 47{
6e37afca
KB
48 struct timeval timedol;
49 struct rusage ru1, ruch;
50
51 (void) getrusage(RUSAGE_SELF, &ru1);
52 (void) getrusage(RUSAGE_CHILDREN, &ruch);
53 ruadd(&ru1, &ruch);
b9c4f741 54 (void) gettimeofday(&timedol, NULL);
6e37afca 55 prusage(&ru0, &ru1, &timedol, &time0);
35867765
BJ
56}
57
58/*
59 * donice is only called when it on the line by itself or with a +- value
60 */
6e37afca 61void
454c2aa3
CZ
62/*ARGSUSED*/
63donice(v, t)
64 Char **v;
65 struct command *t;
35867765 66{
6e37afca
KB
67 register Char *cp;
68 int nval = 0;
69
70 v++, cp = *v++;
71 if (cp == 0)
72 nval = 4;
73 else if (*v == 0 && any("+-", cp[0]))
74 nval = getn(cp);
75 (void) setpriority(PRIO_PROCESS, 0, nval);
35867765
BJ
76}
77
6e37afca 78void
ea775389 79ruadd(ru, ru2)
6e37afca 80 register struct rusage *ru, *ru2;
35867765 81{
6e37afca
KB
82 tvadd(&ru->ru_utime, &ru2->ru_utime);
83 tvadd(&ru->ru_stime, &ru2->ru_stime);
84 if (ru2->ru_maxrss > ru->ru_maxrss)
85 ru->ru_maxrss = ru2->ru_maxrss;
86
87 ru->ru_ixrss += ru2->ru_ixrss;
88 ru->ru_idrss += ru2->ru_idrss;
89 ru->ru_isrss += ru2->ru_isrss;
90 ru->ru_minflt += ru2->ru_minflt;
91 ru->ru_majflt += ru2->ru_majflt;
92 ru->ru_nswap += ru2->ru_nswap;
93 ru->ru_inblock += ru2->ru_inblock;
94 ru->ru_oublock += ru2->ru_oublock;
95 ru->ru_msgsnd += ru2->ru_msgsnd;
96 ru->ru_msgrcv += ru2->ru_msgrcv;
97 ru->ru_nsignals += ru2->ru_nsignals;
98 ru->ru_nvcsw += ru2->ru_nvcsw;
99 ru->ru_nivcsw += ru2->ru_nivcsw;
35867765
BJ
100}
101
6e37afca 102void
ae3d9709 103prusage(r0, r1, e, b)
6e37afca
KB
104 register struct rusage *r0, *r1;
105 struct timeval *e, *b;
35867765 106{
6e37afca
KB
107 register time_t t =
108 (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
109 (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
110 (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
111 (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
112 register char *cp;
113 register long i;
114 register struct varent *vp = adrof(STRtime);
115
116 int ms =
117 (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000;
118
119 cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
6e37afca
KB
120
121 if (vp && vp->vec[0] && vp->vec[1])
122 cp = short2str(vp->vec[1]);
0aec749d 123
6e37afca 124 for (; *cp; cp++)
35867765 125 if (*cp != '%')
454c2aa3 126 (void) fputc(*cp, cshout);
6e37afca
KB
127 else if (cp[1])
128 switch (*++cp) {
35867765 129
6e37afca 130 case 'U': /* user CPU time used */
ea775389 131 pdeltat(&r1->ru_utime, &r0->ru_utime);
35867765
BJ
132 break;
133
6e37afca 134 case 'S': /* system CPU time used */
ea775389 135 pdeltat(&r1->ru_stime, &r0->ru_stime);
35867765
BJ
136 break;
137
6e37afca
KB
138 case 'E': /* elapsed (wall-clock) time */
139 pcsecs((long) ms);
35867765
BJ
140 break;
141
6e37afca 142 case 'P': /* percent time spent running */
0aec749d
CZ
143 /* check if it did not run at all */
144 i = (ms == 0) ? 0 : (t * 1000 / ms);
454c2aa3
CZ
145 /* nn.n% */
146 (void) fprintf(cshout, "%ld.%01ld%%", i / 10, i % 10);
35867765
BJ
147 break;
148
6e37afca 149 case 'W': /* number of swaps */
ea775389 150 i = r1->ru_nswap - r0->ru_nswap;
454c2aa3 151 (void) fprintf(cshout, "%ld", i);
35867765
BJ
152 break;
153
6e37afca 154 case 'X': /* (average) shared text size */
454c2aa3
CZ
155 (void) fprintf(cshout, "%ld", t == 0 ? 0L :
156 (r1->ru_ixrss - r0->ru_ixrss) / t);
35867765
BJ
157 break;
158
6e37afca 159 case 'D': /* (average) unshared data size */
454c2aa3 160 (void) fprintf(cshout, "%ld", t == 0 ? 0L :
6e37afca
KB
161 (r1->ru_idrss + r1->ru_isrss -
162 (r0->ru_idrss + r0->ru_isrss)) / t);
35867765
BJ
163 break;
164
6e37afca 165 case 'K': /* (average) total data memory used */
454c2aa3 166 (void) fprintf(cshout, "%ld", t == 0 ? 0L :
6e37afca
KB
167 ((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) -
168 (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t);
35867765
BJ
169 break;
170
6e37afca 171 case 'M': /* max. Resident Set Size */
454c2aa3 172 (void) fprintf(cshout, "%ld", r1->ru_maxrss / 2L);
35867765
BJ
173 break;
174
6e37afca 175 case 'F': /* page faults */
454c2aa3 176 (void) fprintf(cshout, "%ld", r1->ru_majflt - r0->ru_majflt);
35867765
BJ
177 break;
178
6e37afca 179 case 'R': /* page reclaims */
454c2aa3 180 (void) fprintf(cshout, "%ld", r1->ru_minflt - r0->ru_minflt);
35867765
BJ
181 break;
182
6e37afca 183 case 'I': /* FS blocks in */
454c2aa3 184 (void) fprintf(cshout, "%ld", r1->ru_inblock - r0->ru_inblock);
35867765
BJ
185 break;
186
6e37afca 187 case 'O': /* FS blocks out */
454c2aa3 188 (void) fprintf(cshout, "%ld", r1->ru_oublock - r0->ru_oublock);
35867765 189 break;
6e37afca
KB
190
191 case 'r': /* socket messages recieved */
454c2aa3 192 (void) fprintf(cshout, "%ld", r1->ru_msgrcv - r0->ru_msgrcv);
6e37afca
KB
193 break;
194
195 case 's': /* socket messages sent */
454c2aa3 196 (void) fprintf(cshout, "%ld", r1->ru_msgsnd - r0->ru_msgsnd);
6e37afca
KB
197 break;
198
199 case 'k': /* number of signals recieved */
454c2aa3 200 (void) fprintf(cshout, "%ld", r1->ru_nsignals-r0->ru_nsignals);
6e37afca
KB
201 break;
202
203 case 'w': /* num. voluntary context switches (waits) */
454c2aa3 204 (void) fprintf(cshout, "%ld", r1->ru_nvcsw - r0->ru_nvcsw);
6e37afca
KB
205 break;
206
207 case 'c': /* num. involuntary context switches */
454c2aa3 208 (void) fprintf(cshout, "%ld", r1->ru_nivcsw - r0->ru_nivcsw);
6e37afca
KB
209 break;
210 }
454c2aa3 211 (void) fputc('\n', cshout);
35867765 212}
ea775389 213
6e37afca 214static void
ea775389 215pdeltat(t1, t0)
6e37afca 216 struct timeval *t1, *t0;
ea775389 217{
6e37afca 218 struct timeval td;
ea775389 219
6e37afca 220 tvsub(&td, t1, t0);
454c2aa3 221 (void) fprintf(cshout, "%d.%01d", td.tv_sec, td.tv_usec / 100000);
ea775389
SL
222}
223
6e37afca 224void
ea775389 225tvadd(tsum, t0)
6e37afca 226 struct timeval *tsum, *t0;
ea775389
SL
227{
228
6e37afca
KB
229 tsum->tv_sec += t0->tv_sec;
230 tsum->tv_usec += t0->tv_usec;
231 if (tsum->tv_usec > 1000000)
232 tsum->tv_sec++, tsum->tv_usec -= 1000000;
ea775389
SL
233}
234
6e37afca 235void
ea775389 236tvsub(tdiff, t1, t0)
6e37afca 237 struct timeval *tdiff, *t1, *t0;
ea775389
SL
238{
239
6e37afca
KB
240 tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
241 tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
242 if (tdiff->tv_usec < 0)
243 tdiff->tv_sec--, tdiff->tv_usec += 1000000;
ea775389 244}
454c2aa3
CZ
245
246#define P2DIG(i) (void) fprintf(cshout, "%d%d", (i) / 10, (i) % 10)
247
248void
249psecs(l)
250 long l;
251{
252 register int i;
253
254 i = l / 3600;
255 if (i) {
256 (void) fprintf(cshout, "%d:", i);
257 i = l % 3600;
258 P2DIG(i / 60);
259 goto minsec;
260 }
261 i = l;
262 (void) fprintf(cshout, "%d", i / 60);
263minsec:
264 i %= 60;
265 (void) fputc(':', cshout);
266 P2DIG(i);
267}
268
269void
270pcsecs(l) /* PWP: print mm:ss.dd, l is in sec*100 */
271 long l;
272{
273 register int i;
274
275 i = l / 360000;
276 if (i) {
277 (void) fprintf(cshout, "%d:", i);
278 i = (l % 360000) / 100;
279 P2DIG(i / 60);
280 goto minsec;
281 }
282 i = l / 100;
283 (void) fprintf(cshout, "%d", i / 60);
284minsec:
285 i %= 60;
286 (void) fputc(':', cshout);
287 P2DIG(i);
288 (void) fputc('.', cshout);
289 P2DIG((int) (l % 100));
290}