1*10036Ssam /* time.c 4.2 82/12/30 */ 21306Sbill 31306Sbill #include "sh.h" 41306Sbill 51306Sbill /* 61306Sbill * C Shell - routines handling process timing and niceing 71306Sbill */ 81306Sbill struct tms times0; 91306Sbill struct tms timesdol; 101306Sbill 111306Sbill settimes() 121306Sbill { 13*10036Ssam struct rusage ruch; 141306Sbill 151306Sbill time(&time0); 16*10036Ssam getrusage(RUSAGE_SELF, &ru0); 17*10036Ssam getrusage(RUSAGE_CHILDREN, &ruch); 18*10036Ssam ruadd(&ru0, &ruch); 191306Sbill } 201306Sbill 211306Sbill /* 221306Sbill * dotime is only called if it is truly a builtin function and not a 231306Sbill * prefix to another command 241306Sbill */ 251306Sbill dotime() 261306Sbill { 271306Sbill time_t timedol; 28*10036Ssam struct rusage ru1, ruch; 291306Sbill 30*10036Ssam getrusage(RUSAGE_SELF, &ru1); 31*10036Ssam getrusage(RUSAGE_CHILDREN, &ruch); 32*10036Ssam ruadd(&ru1, &ruch); 331306Sbill time(&timedol); 34*10036Ssam prusage(&ru0, &ru1, timedol - time0); 351306Sbill } 361306Sbill 371306Sbill /* 381306Sbill * donice is only called when it on the line by itself or with a +- value 391306Sbill */ 401306Sbill donice(v) 411306Sbill register char **v; 421306Sbill { 431306Sbill register char *cp; 441306Sbill 451306Sbill v++, cp = *v++; 461306Sbill if (cp == 0) { 471306Sbill #ifndef V6 481306Sbill nice(20); 491306Sbill nice(-10); 501306Sbill #endif 511306Sbill nice(4); 521306Sbill } else if (*v == 0 && any(cp[0], "+-")) { 531306Sbill #ifndef V6 541306Sbill nice(20); 551306Sbill nice(-10); 561306Sbill #endif 571306Sbill nice(getn(cp)); 581306Sbill } 591306Sbill } 601306Sbill 61*10036Ssam ruadd(ru, ru2) 62*10036Ssam register struct rusage *ru, *ru2; 631306Sbill { 64*10036Ssam register long *lp, *lp2; 65*10036Ssam register int cnt; 661306Sbill 67*10036Ssam tvadd(&ru->ru_utime, &ru2->ru_utime); 68*10036Ssam tvadd(&ru->ru_stime, &ru2->ru_stime); 69*10036Ssam if (ru2->ru_maxrss > ru->ru_maxrss) 70*10036Ssam ru->ru_maxrss = ru2->ru_maxrss; 71*10036Ssam cnt = &ru->ru_last - &ru->ru_first + 1; 72*10036Ssam lp = &ru->ru_first; lp2 = &ru2->ru_first; 73*10036Ssam do 74*10036Ssam *lp++ += *lp2++; 75*10036Ssam while (--cnt > 0); 761306Sbill } 771306Sbill 78*10036Ssam prusage(r0, r1, sec) 79*10036Ssam register struct rusage *r0, *r1; 801306Sbill time_t sec; 811306Sbill { 821306Sbill register time_t t = 83*10036Ssam (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+ 84*10036Ssam (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+ 85*10036Ssam (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+ 86*10036Ssam (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000; 871306Sbill register char *cp; 881306Sbill register int i; 891306Sbill register struct varent *vp = adrof("time"); 901306Sbill 911306Sbill cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 921306Sbill if (vp && vp->vec[0] && vp->vec[1]) 931306Sbill cp = vp->vec[1]; 941306Sbill for (; *cp; cp++) 951306Sbill if (*cp != '%') 961306Sbill putchar(*cp); 971306Sbill else if (cp[1]) switch(*++cp) { 981306Sbill 991306Sbill case 'U': 100*10036Ssam pdeltat(&r1->ru_utime, &r0->ru_utime); 1011306Sbill break; 1021306Sbill 1031306Sbill case 'S': 104*10036Ssam pdeltat(&r1->ru_stime, &r0->ru_stime); 1051306Sbill break; 1061306Sbill 1071306Sbill case 'E': 1081306Sbill psecs(sec); 1091306Sbill break; 1101306Sbill 1111306Sbill case 'P': 112*10036Ssam printf("%d%%", (int) (t / ((sec ? sec : 1)))); 1131306Sbill break; 1141306Sbill 1151306Sbill case 'W': 116*10036Ssam i = r1->ru_nswap - r0->ru_nswap; 1171306Sbill printf("%d", i); 1181306Sbill break; 1191306Sbill 1201306Sbill case 'X': 121*10036Ssam printf("%d", t == 0 ? 0 : (r1->ru_ixrss-r0->ru_ixrss)/t); 1221306Sbill break; 1231306Sbill 1241306Sbill case 'D': 125*10036Ssam printf("%d", t == 0 ? 0 : 126*10036Ssam (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); 1271306Sbill break; 1281306Sbill 1291306Sbill case 'K': 130*10036Ssam printf("%d", t == 0 ? 0 : 131*10036Ssam ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) - 132*10036Ssam (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t); 1331306Sbill break; 1341306Sbill 1351306Sbill case 'M': 136*10036Ssam printf("%d", r1->ru_maxrss/2); 1371306Sbill break; 1381306Sbill 1391306Sbill case 'F': 140*10036Ssam printf("%d", r1->ru_majflt-r0->ru_majflt); 1411306Sbill break; 1421306Sbill 1431306Sbill case 'R': 144*10036Ssam printf("%d", r1->ru_minflt-r0->ru_minflt); 1451306Sbill break; 1461306Sbill 1471306Sbill case 'I': 148*10036Ssam printf("%d", r1->ru_inblock-r0->ru_inblock); 1491306Sbill break; 1501306Sbill 1511306Sbill case 'O': 152*10036Ssam printf("%d", r1->ru_oublock-r0->ru_oublock); 1531306Sbill break; 1541306Sbill } 1551306Sbill putchar('\n'); 1561306Sbill } 157*10036Ssam 158*10036Ssam pdeltat(t1, t0) 159*10036Ssam struct timeval *t1, *t0; 160*10036Ssam { 161*10036Ssam struct timeval td; 162*10036Ssam 163*10036Ssam tvsub(&td, t1, t0); 164*10036Ssam printf("%d.%01d", td.tv_sec, td.tv_usec/100000); 165*10036Ssam } 166*10036Ssam 167*10036Ssam tvadd(tsum, t0) 168*10036Ssam struct timeval *tsum, *t0; 169*10036Ssam { 170*10036Ssam 171*10036Ssam tsum->tv_sec += t0->tv_sec; 172*10036Ssam tsum->tv_usec += t0->tv_usec; 173*10036Ssam if (tsum->tv_usec > 1000000) 174*10036Ssam tsum->tv_sec++, tsum->tv_usec -= 1000000; 175*10036Ssam } 176*10036Ssam 177*10036Ssam tvsub(tdiff, t1, t0) 178*10036Ssam struct timeval *tdiff, *t1, *t0; 179*10036Ssam { 180*10036Ssam 181*10036Ssam tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 182*10036Ssam tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 183*10036Ssam if (tdiff->tv_usec < 0) 184*10036Ssam tdiff->tv_sec--, tdiff->tv_usec += 1000000; 185*10036Ssam } 186