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