1 /* time.c 4.3 83/02/03 */ 2 3 #include "sh.h" 4 5 /* 6 * C Shell - routines handling process timing and niceing 7 */ 8 struct tms times0; 9 struct tms timesdol; 10 11 settimes() 12 { 13 struct rusage ruch; 14 15 gettimeofday(&time0, (struct timezone *)0); 16 getrusage(RUSAGE_SELF, &ru0); 17 getrusage(RUSAGE_CHILDREN, &ruch); 18 ruadd(&ru0, &ruch); 19 } 20 21 /* 22 * dotime is only called if it is truly a builtin function and not a 23 * prefix to another command 24 */ 25 dotime() 26 { 27 struct timeval timedol; 28 struct rusage ru1, ruch; 29 30 getrusage(RUSAGE_SELF, &ru1); 31 getrusage(RUSAGE_CHILDREN, &ruch); 32 ruadd(&ru1, &ruch); 33 gettimeofday(&timedol, (struct timezone *)0); 34 prusage(&ru0, &ru1, &timedol, &time0); 35 } 36 37 /* 38 * donice is only called when it on the line by itself or with a +- value 39 */ 40 donice(v) 41 register char **v; 42 { 43 register char *cp; 44 45 v++, cp = *v++; 46 if (cp == 0) { 47 #ifndef V6 48 nice(20); 49 nice(-10); 50 #endif 51 nice(4); 52 } else if (*v == 0 && any(cp[0], "+-")) { 53 #ifndef V6 54 nice(20); 55 nice(-10); 56 #endif 57 nice(getn(cp)); 58 } 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 int i; 89 register struct varent *vp = adrof("time"); 90 int 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 putchar(*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("%d", i); 120 break; 121 122 case 'X': 123 printf("%d", t == 0 ? 0 : (r1->ru_ixrss-r0->ru_ixrss)/t); 124 break; 125 126 case 'D': 127 printf("%d", t == 0 ? 0 : 128 (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); 129 break; 130 131 case 'K': 132 printf("%d", t == 0 ? 0 : 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("%d", r1->ru_maxrss/2); 139 break; 140 141 case 'F': 142 printf("%d", r1->ru_majflt-r0->ru_majflt); 143 break; 144 145 case 'R': 146 printf("%d", r1->ru_minflt-r0->ru_minflt); 147 break; 148 149 case 'I': 150 printf("%d", r1->ru_inblock-r0->ru_inblock); 151 break; 152 153 case 'O': 154 printf("%d", r1->ru_oublock-r0->ru_oublock); 155 break; 156 } 157 putchar('\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