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