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