sh.time.c revision 59415
1266125Sjhb/* $Header: /src/pub/tcsh/sh.time.c,v 3.21 2000/01/14 22:57:29 christos Exp $ */ 2281887Sjhb/* 3266125Sjhb * sh.time.c: Shell time keeping and printing. 4266125Sjhb */ 5266125Sjhb/*- 6266125Sjhb * Copyright (c) 1980, 1991 The Regents of the University of California. 7266125Sjhb * All rights reserved. 8266125Sjhb * 9266125Sjhb * Redistribution and use in source and binary forms, with or without 10266125Sjhb * modification, are permitted provided that the following conditions 11266125Sjhb * are met: 12266125Sjhb * 1. Redistributions of source code must retain the above copyright 13266125Sjhb * notice, this list of conditions and the following disclaimer. 14266125Sjhb * 2. Redistributions in binary form must reproduce the above copyright 15266125Sjhb * notice, this list of conditions and the following disclaimer in the 16266125Sjhb * documentation and/or other materials provided with the distribution. 17266125Sjhb * 3. All advertising materials mentioning features or use of this software 18266125Sjhb * must display the following acknowledgement: 19266125Sjhb * This product includes software developed by the University of 20266125Sjhb * California, Berkeley and its contributors. 21266125Sjhb * 4. Neither the name of the University nor the names of its contributors 22266125Sjhb * may be used to endorse or promote products derived from this software 23266125Sjhb * without specific prior written permission. 24266125Sjhb * 25266125Sjhb * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26266125Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27266125Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28266125Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29266125Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30266125Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31266125Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32266125Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33266125Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34266125Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35266125Sjhb * SUCH DAMAGE. 36266125Sjhb */ 37266125Sjhb#include "sh.h" 38266125Sjhb 39266125SjhbRCSID("$Id: sh.time.c,v 3.21 2000/01/14 22:57:29 christos Exp $") 40266125Sjhb 41266125Sjhb#ifdef SUNOS4 42266125Sjhb# include <machine/param.h> 43266125Sjhb#endif /* SUNOS4 */ 44266125Sjhb 45266125Sjhb/* 46 * C Shell - routines handling process timing and niceing 47 */ 48#ifdef BSDTIMES 49# ifndef RUSAGE_SELF 50# define RUSAGE_SELF 0 51# define RUSAGE_CHILDREN -1 52# endif /* RUSAGE_SELF */ 53#else /* BSDTIMES */ 54struct tms times0; 55#endif /* BSDTIMES */ 56 57#if !defined(BSDTIMES) && !defined(_SEQUENT_) 58# ifdef POSIX 59static void pdtimet __P((clock_t, clock_t)); 60# else /* ! POSIX */ 61static void pdtimet __P((time_t, time_t)); 62# endif /* ! POSIX */ 63#else /* BSDTIMES || _SEQUENT_ */ 64static void tvadd __P((timeval_t *, timeval_t *)); 65static void pdeltat __P((timeval_t *, timeval_t *)); 66#endif /* BSDTIMES || _SEQUENT_ */ 67 68void 69settimes() 70{ 71#ifdef BSDTIMES 72 struct sysrusage ruch; 73#ifdef convex 74 memset(&ru0, 0, sizeof(ru0)); 75 memset(&ruch, 0, sizeof(ruch)); 76#endif /* convex */ 77 78 (void) gettimeofday(&time0, NULL); 79 (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0); 80 (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 81 ruadd(&ru0, &ruch); 82#else 83# ifdef _SEQUENT_ 84 struct process_stats ruch; 85 86 (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch); 87 ruadd(&ru0, &ruch); 88# else /* _SEQUENT_ */ 89 seconds0 = time(NULL); 90# ifndef COHERENT 91 time0 = times(×0); 92# else /* !COHERENT */ 93 time0 = HZ * seconds0; 94 times(×0); 95# endif /* !COHERENT */ 96 times0.tms_stime += times0.tms_cstime; 97 times0.tms_utime += times0.tms_cutime; 98 times0.tms_cstime = 0; 99 times0.tms_cutime = 0; 100# endif /* _SEQUENT_ */ 101#endif /* BSDTIMES */ 102} 103 104/* 105 * dotime is only called if it is truly a builtin function and not a 106 * prefix to another command 107 */ 108/*ARGSUSED*/ 109void 110dotime(v, c) 111 Char **v; 112 struct command *c; 113{ 114#ifdef BSDTIMES 115 timeval_t timedol; 116 struct sysrusage ru1, ruch; 117#ifdef convex 118 memset(&ru1, 0, sizeof(ru1)); 119 memset(&ruch, 0, sizeof(ruch)); 120#endif /* convex */ 121 122 (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1); 123 (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 124 ruadd(&ru1, &ruch); 125 (void) gettimeofday(&timedol, NULL); 126 prusage(&ru0, &ru1, &timedol, &time0); 127#else 128# ifdef _SEQUENT_ 129 timeval_t timedol; 130 struct process_stats ru1, ruch; 131 132 (void) get_process_stats(&timedol, PS_SELF, &ru1, &ruch); 133 ruadd(&ru1, &ruch); 134 prusage(&ru0, &ru1, &timedol, &time0); 135# else /* _SEQUENT_ */ 136# ifndef POSIX 137 time_t timedol; 138# else /* POSIX */ 139 clock_t timedol; 140# endif /* POSIX */ 141 142 struct tms times_dol; 143 144#ifndef COHERENT 145 timedol = times(×_dol); 146#else 147 timedol = HZ * time(NULL); 148 times(×_dol); 149#endif 150 times_dol.tms_stime += times_dol.tms_cstime; 151 times_dol.tms_utime += times_dol.tms_cutime; 152 times_dol.tms_cstime = 0; 153 times_dol.tms_cutime = 0; 154 prusage(×0, ×_dol, timedol, time0); 155# endif /* _SEQUENT_ */ 156#endif /* BSDTIMES */ 157 USE(c); 158 USE(v); 159} 160 161/* 162 * donice is only called when it on the line by itself or with a +- value 163 */ 164/*ARGSUSED*/ 165void 166donice(v, c) 167 register Char **v; 168 struct command *c; 169{ 170 register Char *cp; 171 int nval = 0; 172 173 USE(c); 174 v++, cp = *v++; 175 if (cp == 0) 176 nval = 4; 177 else if (*v == 0 && any("+-", cp[0])) 178 nval = getn(cp); 179#ifdef BSDNICE 180 (void) setpriority(PRIO_PROCESS, 0, nval); 181#else /* BSDNICE */ 182 (void) nice(nval); 183#endif /* BSDNICE */ 184} 185 186#ifdef BSDTIMES 187void 188ruadd(ru, ru2) 189 register struct sysrusage *ru, *ru2; 190{ 191 tvadd(&ru->ru_utime, &ru2->ru_utime); 192 tvadd(&ru->ru_stime, &ru2->ru_stime); 193 if (ru2->ru_maxrss > ru->ru_maxrss) 194 ru->ru_maxrss = ru2->ru_maxrss; 195 196 ru->ru_ixrss += ru2->ru_ixrss; 197 ru->ru_idrss += ru2->ru_idrss; 198 ru->ru_isrss += ru2->ru_isrss; 199 ru->ru_minflt += ru2->ru_minflt; 200 ru->ru_majflt += ru2->ru_majflt; 201 ru->ru_nswap += ru2->ru_nswap; 202 ru->ru_inblock += ru2->ru_inblock; 203 ru->ru_oublock += ru2->ru_oublock; 204 ru->ru_msgsnd += ru2->ru_msgsnd; 205 ru->ru_msgrcv += ru2->ru_msgrcv; 206 ru->ru_nsignals += ru2->ru_nsignals; 207 ru->ru_nvcsw += ru2->ru_nvcsw; 208 ru->ru_nivcsw += ru2->ru_nivcsw; 209 210# ifdef convex 211 tvadd(&ru->ru_exutime, &ru2->ru_exutime); 212 ru->ru_utotal += ru2->ru_utotal; 213 ru->ru_usamples += ru2->ru_usamples; 214 ru->ru_stotal += ru2->ru_stotal; 215 ru->ru_ssamples += ru2->ru_ssamples; 216# endif /* convex */ 217} 218 219#else /* BSDTIMES */ 220# ifdef _SEQUENT_ 221void 222ruadd(ru, ru2) 223 register struct process_stats *ru, *ru2; 224{ 225 tvadd(&ru->ps_utime, &ru2->ps_utime); 226 tvadd(&ru->ps_stime, &ru2->ps_stime); 227 if (ru2->ps_maxrss > ru->ps_maxrss) 228 ru->ps_maxrss = ru2->ps_maxrss; 229 230 ru->ps_pagein += ru2->ps_pagein; 231 ru->ps_reclaim += ru2->ps_reclaim; 232 ru->ps_zerofill += ru2->ps_zerofill; 233 ru->ps_pffincr += ru2->ps_pffincr; 234 ru->ps_pffdecr += ru2->ps_pffdecr; 235 ru->ps_swap += ru2->ps_swap; 236 ru->ps_syscall += ru2->ps_syscall; 237 ru->ps_volcsw += ru2->ps_volcsw; 238 ru->ps_involcsw += ru2->ps_involcsw; 239 ru->ps_signal += ru2->ps_signal; 240 ru->ps_lread += ru2->ps_lread; 241 ru->ps_lwrite += ru2->ps_lwrite; 242 ru->ps_bread += ru2->ps_bread; 243 ru->ps_bwrite += ru2->ps_bwrite; 244 ru->ps_phread += ru2->ps_phread; 245 ru->ps_phwrite += ru2->ps_phwrite; 246} 247 248# endif /* _SEQUENT_ */ 249#endif /* BSDTIMES */ 250 251#ifdef BSDTIMES 252 253/* 254 * PWP: the LOG1024 and pagetok stuff taken from the top command, 255 * written by William LeFebvre 256 */ 257/* Log base 2 of 1024 is 10 (2^10 == 1024) */ 258#define LOG1024 10 259 260/* Convert clicks (kernel pages) to kbytes ... */ 261/* If there is no PGSHIFT defined, assume it is 11 */ 262/* Is this needed for compatability with some old flavor of 4.2 or 4.1? */ 263#ifdef SUNOS4 264# ifndef PGSHIFT 265# define pagetok(size) ((size) << 1) 266# else 267# if PGSHIFT>10 268# define pagetok(size) ((size) << (PGSHIFT - LOG1024)) 269# else 270# define pagetok(size) ((size) >> (LOG1024 - PGSHIFT)) 271# endif 272# endif 273#endif 274 275/* 276 * if any other machines return wierd values in the ru_i* stuff, put 277 * the adjusting macro here: 278 */ 279#ifdef SUNOS4 280# define IADJUST(i) (pagetok(i)/2) 281#else /* SUNOS4 */ 282# ifdef convex 283 /* 284 * convex has megabytes * CLK_TCK 285 * multiply by 100 since we use time in 100ths of a second in prusage 286 */ 287# define IADJUST(i) (((i) << 10) / CLK_TCK * 100) 288# else /* convex */ 289# define IADJUST(i) (i) 290# endif /* convex */ 291#endif /* SUNOS4 */ 292 293void 294prusage(r0, r1, e, b) 295 register struct sysrusage *r0, *r1; 296 timeval_t *e, *b; 297 298#else /* BSDTIMES */ 299# ifdef _SEQUENT_ 300void 301prusage(r0, r1, e, b) 302 register struct process_stats *r0, *r1; 303 timeval_t *e, *b; 304 305# else /* _SEQUENT_ */ 306void 307prusage(bs, es, e, b) 308 struct tms *bs, *es; 309 310# ifndef POSIX 311 time_t e, b; 312 313# else /* POSIX */ 314 clock_t e, b; 315 316# endif /* POSIX */ 317# endif /* _SEQUENT_ */ 318#endif /* BSDTIMES */ 319{ 320#ifdef BSDTIMES 321 register time_t t = 322 (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + 323 (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + 324 (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + 325 (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; 326 327#else 328# ifdef _SEQUENT_ 329 register time_t t = 330 (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec) * 100 + 331 (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 + 332 (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec) * 100 + 333 (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000; 334 335# else /* _SEQUENT_ */ 336# ifndef POSIX 337 register time_t t = (es->tms_utime - bs->tms_utime + 338 es->tms_stime - bs->tms_stime) * 100 / HZ; 339 340# else /* POSIX */ 341 register clock_t t = (es->tms_utime - bs->tms_utime + 342 es->tms_stime - bs->tms_stime) * 100 / clk_tck; 343 344# endif /* POSIX */ 345# endif /* _SEQUENT_ */ 346#endif /* BSDTIMES */ 347 348 register char *cp; 349 register long i; 350 register struct varent *vp = adrof(STRtime); 351 352#ifdef BSDTIMES 353# ifdef convex 354 static struct system_information sysinfo; 355 long long memtmp; /* let memory calculations exceede 2Gb */ 356# endif /* convex */ 357 int ms = (int) 358 ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 359 360 cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 361#else /* !BSDTIMES */ 362# ifdef _SEQUENT_ 363 int ms = (int) 364 ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 365 366 cp = "%Uu %Ss %E %P %I+%Oio %Fpf+%Ww"; 367# else /* !_SEQUENT_ */ 368# ifndef POSIX 369 time_t ms = ((time_t)((e - b) / HZ) * 100) + 370 (time_t)(((e - b) % HZ) * 100) / HZ; 371# else /* POSIX */ 372 clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) + 373 (clock_t)(((e - b) % clk_tck) * 100) / clk_tck; 374# endif /* POSIX */ 375 376 cp = "%Uu %Ss %E %P"; 377 378 /* 379 * the tms stuff is not very precise, so we fudge it. 380 * granularity fix: can't be more than 100% 381 * this breaks in multi-processor systems... 382 * maybe I should take it out and let people see more then 100% 383 * utilizations. 384 */ 385# if 0 386 if (ms < t && ms != 0) 387 ms = t; 388# endif 389# endif /*! _SEQUENT_ */ 390#endif /* !BSDTIMES */ 391#ifdef TDEBUG 392 xprintf("es->tms_utime %lu bs->tms_utime %lu\n", 393 es->tms_utime, bs->tms_utime); 394 xprintf("es->tms_stime %lu bs->tms_stime %lu\n", 395 es->tms_stime, bs->tms_stime); 396 xprintf("ms %lu e %lu b %lu\n", ms, e, b); 397 xprintf("t %lu\n", t); 398#endif /* TDEBUG */ 399 400 if (vp && vp->vec[0] && vp->vec[1]) 401 cp = short2str(vp->vec[1]); 402 for (; *cp; cp++) 403 if (*cp != '%') 404 xputchar(*cp); 405 else if (cp[1]) 406 switch (*++cp) { 407 408 case 'U': /* user CPU time used */ 409#ifdef BSDTIMES 410 pdeltat(&r1->ru_utime, &r0->ru_utime); 411#else 412# ifdef _SEQUENT_ 413 pdeltat(&r1->ps_utime, &r0->ps_utime); 414# else /* _SEQUENT_ */ 415# ifndef POSIX 416 pdtimet(es->tms_utime, bs->tms_utime); 417# else /* POSIX */ 418 pdtimet(es->tms_utime, bs->tms_utime); 419# endif /* POSIX */ 420# endif /* _SEQUENT_ */ 421#endif /* BSDTIMES */ 422 break; 423 424 case 'S': /* system CPU time used */ 425#ifdef BSDTIMES 426 pdeltat(&r1->ru_stime, &r0->ru_stime); 427#else 428# ifdef _SEQUENT_ 429 pdeltat(&r1->ps_stime, &r0->ps_stime); 430# else /* _SEQUENT_ */ 431# ifndef POSIX 432 pdtimet(es->tms_stime, bs->tms_stime); 433# else /* POSIX */ 434 pdtimet(es->tms_stime, bs->tms_stime); 435# endif /* POSIX */ 436# endif /* _SEQUENT_ */ 437#endif /* BSDTIMES */ 438 break; 439 440 case 'E': /* elapsed (wall-clock) time */ 441#ifdef BSDTIMES 442 pcsecs((long) ms); 443#else /* BSDTIMES */ 444 pcsecs(ms); 445#endif /* BSDTIMES */ 446 break; 447 448 case 'P': /* percent time spent running */ 449 /* check if the process did not run */ 450#ifdef convex 451 /* 452 * scale the cpu %- ages by the number of processors 453 * available on this machine 454 */ 455 if ((sysinfo.cpu_count == 0) && 456 (getsysinfo(SYSINFO_SIZE, &sysinfo) < 0)) 457 sysinfo.cpu_count = 1; 458 i = (ms == 0) ? 0 : (t * 1000.0 / (ms * sysinfo.cpu_count)); 459#else /* convex */ 460 i = (ms == 0) ? 0 : (t * 1000.0 / ms); 461#endif /* convex */ 462 xprintf("%ld.%01ld%%", i / 10, i % 10); /* nn.n% */ 463 break; 464 465#ifdef BSDTIMES 466 case 'W': /* number of swaps */ 467 i = r1->ru_nswap - r0->ru_nswap; 468 xprintf("%ld", i); 469 break; 470 471#ifdef convex 472 case 'X': /* (average) shared text size */ 473 memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss - 474 (long long)r0->ru_ixrss) / 475 (long long)t); 476 xprintf("%lu", (unsigned long)memtmp); 477 478 break; 479 480 case 'D': /* (average) unshared data size */ 481 memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss + 482 (long long)r1->ru_isrss - 483 ((long long)r0->ru_idrss + 484 (long long)r0->ru_isrss)) / 485 (long long)t); 486 xprintf("%lu", (unsigned long)memtmp); 487 break; 488 489 case 'K': /* (average) total data memory used */ 490 memtmp = (t == 0 ? 0LL : IADJUST(((long long)r1->ru_ixrss + 491 (long long)r1->ru_isrss + 492 (long long)r1->ru_idrss) - 493 ((long long)r0->ru_ixrss + 494 (long long)r0->ru_idrss + 495 (long long)r0->ru_isrss)) / 496 (long long)t); 497 xprintf("%lu", (unsigned long)memtmp); 498 break; 499#else /* !convex */ 500 case 'X': /* (average) shared text size */ 501 xprintf("%ld", t == 0 ? 0L : 502 IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t); 503 break; 504 505 case 'D': /* (average) unshared data size */ 506 xprintf("%ld", t == 0 ? 0L : 507 IADJUST(r1->ru_idrss + r1->ru_isrss - 508 (r0->ru_idrss + r0->ru_isrss)) / t); 509 break; 510 511 case 'K': /* (average) total data memory used */ 512 xprintf("%ld", t == 0 ? 0L : 513 IADJUST((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - 514 (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); 515 break; 516#endif /* convex */ 517 case 'M': /* max. Resident Set Size */ 518#ifdef SUNOS4 519 xprintf("%ld", pagetok(r1->ru_maxrss)); 520#else 521# ifdef convex 522 xprintf("%ld", r1->ru_maxrss * 4L); 523# else /* !convex */ 524 xprintf("%ld", r1->ru_maxrss / 2L); 525# endif /* convex */ 526#endif /* SUNOS4 */ 527 break; 528 529 case 'F': /* page faults */ 530 xprintf("%ld", r1->ru_majflt - r0->ru_majflt); 531 break; 532 533 case 'R': /* page reclaims */ 534 xprintf("%ld", r1->ru_minflt - r0->ru_minflt); 535 break; 536 537 case 'I': /* FS blocks in */ 538 xprintf("%ld", r1->ru_inblock - r0->ru_inblock); 539 break; 540 541 case 'O': /* FS blocks out */ 542 xprintf("%ld", r1->ru_oublock - r0->ru_oublock); 543 break; 544 545# ifdef convex 546 case 'C': /* CPU parallelization factor */ 547 if (r1->ru_usamples != 0LL) { 548 long long parr = ((r1->ru_utotal * 100LL) / 549 r1->ru_usamples); 550 xprintf("%d.%02d", (int)(parr/100), (int)(parr%100)); 551 } else 552 xprintf("?"); 553 break; 554# endif /* convex */ 555 case 'r': /* PWP: socket messages recieved */ 556 xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv); 557 break; 558 559 case 's': /* PWP: socket messages sent */ 560 xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd); 561 break; 562 563 case 'k': /* PWP: signals received */ 564 xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals); 565 break; 566 567 case 'w': /* PWP: voluntary context switches (waits) */ 568 xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw); 569 break; 570 571 case 'c': /* PWP: involuntary context switches */ 572 xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw); 573 break; 574#else /* BSDTIMES */ 575# ifdef _SEQUENT_ 576 case 'W': /* number of swaps */ 577 i = r1->ps_swap - r0->ps_swap; 578 xprintf("%ld", i); 579 break; 580 581 case 'M': 582 xprintf("%ld", r1->ps_maxrss / 2); 583 break; 584 585 case 'F': 586 xprintf("%ld", r1->ps_pagein - r0->ps_pagein); 587 break; 588 589 case 'R': 590 xprintf("%ld", r1->ps_reclaim - r0->ps_reclaim); 591 break; 592 593 case 'I': 594 xprintf("%ld", r1->ps_bread - r0->ps_bread); 595 break; 596 597 case 'O': 598 xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite); 599 break; 600 601 case 'k': 602 xprintf("%ld", r1->ps_signal - r0->ps_signal); 603 break; 604 605 case 'w': 606 xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw); 607 break; 608 609 case 'c': 610 xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw); 611 break; 612 613 case 'Z': 614 xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill); 615 break; 616 617 case 'i': 618 xprintf("%ld", r1->ps_pffincr - r0->ps_pffincr); 619 break; 620 621 case 'd': 622 xprintf("%ld", r1->ps_pffdecr - r0->ps_pffdecr); 623 break; 624 625 case 'Y': 626 xprintf("%ld", r1->ps_syscall - r0->ps_syscall); 627 break; 628 629 case 'l': 630 xprintf("%ld", r1->ps_lread - r0->ps_lread); 631 break; 632 633 case 'm': 634 xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite); 635 break; 636 637 case 'p': 638 xprintf("%ld", r1->ps_phread - r0->ps_phread); 639 break; 640 641 case 'q': 642 xprintf("%ld", r1->ps_phwrite - r0->ps_phwrite); 643 break; 644# endif /* _SEQUENT_ */ 645#endif /* BSDTIMES */ 646 default: 647 break; 648 } 649 xputchar('\n'); 650} 651 652#if defined(BSDTIMES) || defined(_SEQUENT_) 653static void 654pdeltat(t1, t0) 655 timeval_t *t1, *t0; 656{ 657 timeval_t td; 658 659 tvsub(&td, t1, t0); 660 xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L); 661} 662 663static void 664tvadd(tsum, t0) 665 timeval_t *tsum, *t0; 666{ 667 668 tsum->tv_sec += t0->tv_sec; 669 tsum->tv_usec += t0->tv_usec; 670 if (tsum->tv_usec >= 1000000) 671 tsum->tv_sec++, tsum->tv_usec -= 1000000; 672} 673 674void 675tvsub(tdiff, t1, t0) 676 timeval_t *tdiff, *t1, *t0; 677{ 678 679 tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 680 tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 681 if (tdiff->tv_usec < 0) 682 tdiff->tv_sec--, tdiff->tv_usec += 1000000; 683} 684 685#else /* !BSDTIMES && !_SEQUENT_ */ 686static void 687pdtimet(eval, bval) 688#ifndef POSIX 689 time_t eval, bval; 690 691#else /* POSIX */ 692 clock_t eval, bval; 693 694#endif /* POSIX */ 695{ 696#ifndef POSIX 697 time_t val; 698 699#else /* POSIX */ 700 clock_t val; 701 702#endif /* POSIX */ 703 704#ifndef POSIX 705 val = (eval - bval) * 100 / HZ; 706#else /* POSIX */ 707 val = (eval - bval) * 100 / clk_tck; 708#endif /* POSIX */ 709 710 xprintf("%ld.%02ld", val / 100, val - (val / 100 * 100)); 711} 712#endif /* BSDTIMES || _SEQUENT_ */ 713