1*47823Sbostic /*- 2*47823Sbostic * Copyright (c) 1980, 1991 The Regents of the University of California. 3*47823Sbostic * All rights reserved. 4*47823Sbostic * 5*47823Sbostic * %sccs.include.redist.c% 621943Sdist */ 721943Sdist 814476Ssam #ifndef lint 9*47823Sbostic static char sccsid[] = "@(#)time.c 5.8 (Berkeley) 04/04/91"; 10*47823Sbostic #endif /* not lint */ 111306Sbill 121306Sbill #include "sh.h" 131306Sbill 141306Sbill /* 151306Sbill * C Shell - routines handling process timing and niceing 161306Sbill */ 171306Sbill 181306Sbill settimes() 191306Sbill { 2010036Ssam struct rusage ruch; 211306Sbill 2217508Sedward (void) gettimeofday(&time0, (struct timezone *)0); 2317508Sedward (void) getrusage(RUSAGE_SELF, &ru0); 2417508Sedward (void) getrusage(RUSAGE_CHILDREN, &ruch); 2510036Ssam ruadd(&ru0, &ruch); 261306Sbill } 271306Sbill 281306Sbill /* 291306Sbill * dotime is only called if it is truly a builtin function and not a 301306Sbill * prefix to another command 311306Sbill */ 321306Sbill dotime() 331306Sbill { 3410705Ssam struct timeval timedol; 3510036Ssam struct rusage ru1, ruch; 361306Sbill 3717508Sedward (void) getrusage(RUSAGE_SELF, &ru1); 3817508Sedward (void) getrusage(RUSAGE_CHILDREN, &ruch); 3910036Ssam ruadd(&ru1, &ruch); 4017508Sedward (void) gettimeofday(&timedol, (struct timezone *)0); 4110705Ssam prusage(&ru0, &ru1, &timedol, &time0); 421306Sbill } 431306Sbill 441306Sbill /* 451306Sbill * donice is only called when it on the line by itself or with a +- value 461306Sbill */ 471306Sbill donice(v) 481306Sbill register char **v; 491306Sbill { 501306Sbill register char *cp; 5125851Slepreau int nval; 521306Sbill 531306Sbill v++, cp = *v++; 5417251Ssam if (cp == 0) 5525851Slepreau nval = 4; 5647421Sbostic else if (*v == 0 && index("+-", cp[0])) 5725851Slepreau nval = getn(cp); 5828052Slepreau (void) setpriority(PRIO_PROCESS, 0, nval); 591306Sbill } 601306Sbill 6110036Ssam ruadd(ru, ru2) 6210036Ssam register struct rusage *ru, *ru2; 631306Sbill { 6410036Ssam register long *lp, *lp2; 6510036Ssam register int cnt; 661306Sbill 6710036Ssam tvadd(&ru->ru_utime, &ru2->ru_utime); 6810036Ssam tvadd(&ru->ru_stime, &ru2->ru_stime); 6910036Ssam if (ru2->ru_maxrss > ru->ru_maxrss) 7010036Ssam ru->ru_maxrss = ru2->ru_maxrss; 7110036Ssam cnt = &ru->ru_last - &ru->ru_first + 1; 7210036Ssam lp = &ru->ru_first; lp2 = &ru2->ru_first; 7310036Ssam do 7410036Ssam *lp++ += *lp2++; 7510036Ssam while (--cnt > 0); 761306Sbill } 771306Sbill 7810705Ssam prusage(r0, r1, e, b) 7910036Ssam register struct rusage *r0, *r1; 8010705Ssam struct timeval *e, *b; 811306Sbill { 821306Sbill register time_t t = 8310036Ssam (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+ 8410036Ssam (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+ 8510036Ssam (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+ 8610036Ssam (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000; 871306Sbill register char *cp; 8831685Sbostic register long i; 891306Sbill register struct varent *vp = adrof("time"); 9031685Sbostic long ms = 9110705Ssam (e->tv_sec-b->tv_sec)*100 + (e->tv_usec-b->tv_usec)/10000; 921306Sbill 931306Sbill cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 941306Sbill if (vp && vp->vec[0] && vp->vec[1]) 951306Sbill cp = vp->vec[1]; 961306Sbill for (; *cp; cp++) 971306Sbill if (*cp != '%') 9834340Sbostic cshputchar(*cp); 991306Sbill else if (cp[1]) switch(*++cp) { 1001306Sbill 1011306Sbill case 'U': 10210036Ssam pdeltat(&r1->ru_utime, &r0->ru_utime); 1031306Sbill break; 1041306Sbill 1051306Sbill case 'S': 10610036Ssam pdeltat(&r1->ru_stime, &r0->ru_stime); 1071306Sbill break; 1081306Sbill 1091306Sbill case 'E': 11031685Sbostic psecs(ms / 100); 1111306Sbill break; 1121306Sbill 1131306Sbill case 'P': 11410705Ssam printf("%d%%", (int) (t*100 / ((ms ? ms : 1)))); 1151306Sbill break; 1161306Sbill 1171306Sbill case 'W': 11810036Ssam i = r1->ru_nswap - r0->ru_nswap; 11931685Sbostic printf("%ld", i); 1201306Sbill break; 1211306Sbill 1221306Sbill case 'X': 12331685Sbostic printf("%ld", t == 0 ? 0L : (r1->ru_ixrss-r0->ru_ixrss)/t); 1241306Sbill break; 1251306Sbill 1261306Sbill case 'D': 12731685Sbostic printf("%ld", t == 0 ? 0L : 12810036Ssam (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); 1291306Sbill break; 1301306Sbill 1311306Sbill case 'K': 13231685Sbostic printf("%ld", t == 0 ? 0L : 13310036Ssam ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) - 13410036Ssam (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t); 1351306Sbill break; 1361306Sbill 1371306Sbill case 'M': 13831685Sbostic printf("%ld", r1->ru_maxrss/2); 1391306Sbill break; 1401306Sbill 1411306Sbill case 'F': 14231685Sbostic printf("%ld", r1->ru_majflt-r0->ru_majflt); 1431306Sbill break; 1441306Sbill 1451306Sbill case 'R': 14631685Sbostic printf("%ld", r1->ru_minflt-r0->ru_minflt); 1471306Sbill break; 1481306Sbill 1491306Sbill case 'I': 15031685Sbostic printf("%ld", r1->ru_inblock-r0->ru_inblock); 1511306Sbill break; 1521306Sbill 1531306Sbill case 'O': 15431685Sbostic printf("%ld", r1->ru_oublock-r0->ru_oublock); 1551306Sbill break; 1561306Sbill } 15734340Sbostic cshputchar('\n'); 1581306Sbill } 15910036Ssam 16010036Ssam pdeltat(t1, t0) 16110036Ssam struct timeval *t1, *t0; 16210036Ssam { 16310036Ssam struct timeval td; 16410036Ssam 16510036Ssam tvsub(&td, t1, t0); 16610036Ssam printf("%d.%01d", td.tv_sec, td.tv_usec/100000); 16710036Ssam } 16810036Ssam 16910036Ssam tvadd(tsum, t0) 17010036Ssam struct timeval *tsum, *t0; 17110036Ssam { 17210036Ssam 17310036Ssam tsum->tv_sec += t0->tv_sec; 17410036Ssam tsum->tv_usec += t0->tv_usec; 17510036Ssam if (tsum->tv_usec > 1000000) 17610036Ssam tsum->tv_sec++, tsum->tv_usec -= 1000000; 17710036Ssam } 17810036Ssam 17910036Ssam tvsub(tdiff, t1, t0) 18010036Ssam struct timeval *tdiff, *t1, *t0; 18110036Ssam { 18210036Ssam 18310036Ssam tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 18410036Ssam tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 18510036Ssam if (tdiff->tv_usec < 0) 18610036Ssam tdiff->tv_sec--, tdiff->tv_usec += 1000000; 18710036Ssam } 188