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