1 #ifndef lint 2 static char *sccsid = "@(#)time.c 4.6 (Berkeley) 12/13/84"; 3 #endif 4 5 #include "sh.h" 6 7 /* 8 * C Shell - routines handling process timing and niceing 9 */ 10 11 settimes() 12 { 13 struct rusage ruch; 14 15 (void) gettimeofday(&time0, (struct timezone *)0); 16 (void) getrusage(RUSAGE_SELF, &ru0); 17 (void) 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 (void) getrusage(RUSAGE_SELF, &ru1); 31 (void) getrusage(RUSAGE_CHILDREN, &ruch); 32 ruadd(&ru1, &ruch); 33 (void) 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 (void) setpriority(PRIO_PROCESS, 0, 4); 48 else if (*v == 0 && any(cp[0], "+-")) 49 (void) setpriority(PRIO_PROCESS, 0, 50 getpriority(PRIO_PROCESS, 0) + getn(cp)); 51 } 52 53 ruadd(ru, ru2) 54 register struct rusage *ru, *ru2; 55 { 56 register long *lp, *lp2; 57 register int cnt; 58 59 tvadd(&ru->ru_utime, &ru2->ru_utime); 60 tvadd(&ru->ru_stime, &ru2->ru_stime); 61 if (ru2->ru_maxrss > ru->ru_maxrss) 62 ru->ru_maxrss = ru2->ru_maxrss; 63 cnt = &ru->ru_last - &ru->ru_first + 1; 64 lp = &ru->ru_first; lp2 = &ru2->ru_first; 65 do 66 *lp++ += *lp2++; 67 while (--cnt > 0); 68 } 69 70 prusage(r0, r1, e, b) 71 register struct rusage *r0, *r1; 72 struct timeval *e, *b; 73 { 74 register time_t t = 75 (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+ 76 (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+ 77 (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+ 78 (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000; 79 register char *cp; 80 register int i; 81 register struct varent *vp = adrof("time"); 82 int ms = 83 (e->tv_sec-b->tv_sec)*100 + (e->tv_usec-b->tv_usec)/10000; 84 85 cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 86 if (vp && vp->vec[0] && vp->vec[1]) 87 cp = vp->vec[1]; 88 for (; *cp; cp++) 89 if (*cp != '%') 90 putchar(*cp); 91 else if (cp[1]) switch(*++cp) { 92 93 case 'U': 94 pdeltat(&r1->ru_utime, &r0->ru_utime); 95 break; 96 97 case 'S': 98 pdeltat(&r1->ru_stime, &r0->ru_stime); 99 break; 100 101 case 'E': 102 psecs((long)(ms / 100)); 103 break; 104 105 case 'P': 106 printf("%d%%", (int) (t*100 / ((ms ? ms : 1)))); 107 break; 108 109 case 'W': 110 i = r1->ru_nswap - r0->ru_nswap; 111 printf("%d", i); 112 break; 113 114 case 'X': 115 printf("%d", t == 0 ? 0 : (r1->ru_ixrss-r0->ru_ixrss)/t); 116 break; 117 118 case 'D': 119 printf("%d", t == 0 ? 0 : 120 (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); 121 break; 122 123 case 'K': 124 printf("%d", t == 0 ? 0 : 125 ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) - 126 (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t); 127 break; 128 129 case 'M': 130 printf("%d", r1->ru_maxrss/2); 131 break; 132 133 case 'F': 134 printf("%d", r1->ru_majflt-r0->ru_majflt); 135 break; 136 137 case 'R': 138 printf("%d", r1->ru_minflt-r0->ru_minflt); 139 break; 140 141 case 'I': 142 printf("%d", r1->ru_inblock-r0->ru_inblock); 143 break; 144 145 case 'O': 146 printf("%d", r1->ru_oublock-r0->ru_oublock); 147 break; 148 } 149 putchar('\n'); 150 } 151 152 pdeltat(t1, t0) 153 struct timeval *t1, *t0; 154 { 155 struct timeval td; 156 157 tvsub(&td, t1, t0); 158 printf("%d.%01d", td.tv_sec, td.tv_usec/100000); 159 } 160 161 tvadd(tsum, t0) 162 struct timeval *tsum, *t0; 163 { 164 165 tsum->tv_sec += t0->tv_sec; 166 tsum->tv_usec += t0->tv_usec; 167 if (tsum->tv_usec > 1000000) 168 tsum->tv_sec++, tsum->tv_usec -= 1000000; 169 } 170 171 tvsub(tdiff, t1, t0) 172 struct timeval *tdiff, *t1, *t0; 173 { 174 175 tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 176 tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 177 if (tdiff->tv_usec < 0) 178 tdiff->tv_sec--, tdiff->tv_usec += 1000000; 179 } 180