sh.time.c revision 59243
1210389Sgabor/* $Header: /src/pub/tcsh/sh.time.c,v 3.20 1998/11/24 18:17:38 christos Exp $ */ 2210389Sgabor/* 3210389Sgabor * sh.time.c: Shell time keeping and printing. 4210389Sgabor */ 5210389Sgabor/*- 6210389Sgabor * Copyright (c) 1980, 1991 The Regents of the University of California. 7210389Sgabor * All rights reserved. 8210389Sgabor * 9210389Sgabor * Redistribution and use in source and binary forms, with or without 10210389Sgabor * modification, are permitted provided that the following conditions 11210389Sgabor * are met: 12210389Sgabor * 1. Redistributions of source code must retain the above copyright 13210389Sgabor * notice, this list of conditions and the following disclaimer. 14210389Sgabor * 2. Redistributions in binary form must reproduce the above copyright 15210389Sgabor * notice, this list of conditions and the following disclaimer in the 16210389Sgabor * documentation and/or other materials provided with the distribution. 17210389Sgabor * 3. All advertising materials mentioning features or use of this software 18210389Sgabor * must display the following acknowledgement: 19210389Sgabor * This product includes software developed by the University of 20210389Sgabor * California, Berkeley and its contributors. 21210389Sgabor * 4. Neither the name of the University nor the names of its contributors 22210389Sgabor * may be used to endorse or promote products derived from this software 23210389Sgabor * without specific prior written permission. 24210389Sgabor * 25210389Sgabor * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26210389Sgabor * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27210389Sgabor * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28210389Sgabor * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29210389Sgabor * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30210389Sgabor * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31210389Sgabor * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32210389Sgabor * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33210389Sgabor * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34210389Sgabor * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35210389Sgabor * SUCH DAMAGE. 36210389Sgabor */ 37210389Sgabor#include "sh.h" 38210389Sgabor 39210389SgaborRCSID("$Id: sh.time.c,v 3.20 1998/11/24 18:17:38 christos Exp $") 40210389Sgabor 41210389Sgabor#ifdef SUNOS4 42210389Sgabor# include <machine/param.h> 43210389Sgabor#endif /* SUNOS4 */ 44210389Sgabor 45210389Sgabor/* 46210389Sgabor * C Shell - routines handling process timing and niceing 47210389Sgabor */ 48210389Sgabor#ifdef BSDTIMES 49210389Sgabor# ifndef RUSAGE_SELF 50210389Sgabor# define RUSAGE_SELF 0 51210389Sgabor# define RUSAGE_CHILDREN -1 52210389Sgabor# endif /* RUSAGE_SELF */ 53210389Sgabor#else /* BSDTIMES */ 54210389Sgaborstruct tms times0; 55210389Sgabor#endif /* BSDTIMES */ 56210389Sgabor 57210389Sgabor#if !defined(BSDTIMES) && !defined(_SEQUENT_) 58210389Sgabor# ifdef POSIX 59210389Sgaborstatic void pdtimet __P((clock_t, clock_t)); 60210389Sgabor# else /* ! POSIX */ 61210389Sgaborstatic void pdtimet __P((time_t, time_t)); 62210389Sgabor# endif /* ! POSIX */ 63210389Sgabor#else /* BSDTIMES || _SEQUENT_ */ 64210389Sgaborstatic void tvadd __P((timeval_t *, timeval_t *)); 65210389Sgaborstatic void pdeltat __P((timeval_t *, timeval_t *)); 66210389Sgabor#endif /* BSDTIMES || _SEQUENT_ */ 67210389Sgabor 68210389Sgaborvoid 69210389Sgaborsettimes() 70210389Sgabor{ 71210389Sgabor#ifdef BSDTIMES 72210389Sgabor struct sysrusage ruch; 73210389Sgabor#ifdef convex 74210389Sgabor memset(&ru0, 0, sizeof(ru0)); 75210389Sgabor memset(&ruch, 0, sizeof(ruch)); 76210389Sgabor#endif /* convex */ 77210389Sgabor 78210389Sgabor (void) gettimeofday(&time0, NULL); 79210389Sgabor (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0); 80210389Sgabor (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 81210389Sgabor ruadd(&ru0, &ruch); 82210389Sgabor#else 83210389Sgabor# ifdef _SEQUENT_ 84210389Sgabor struct process_stats ruch; 85210389Sgabor 86210389Sgabor (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch); 87210389Sgabor ruadd(&ru0, &ruch); 88210389Sgabor# else /* _SEQUENT_ */ 89210389Sgabor# ifndef COHERENT 90210389Sgabor time0 = times(×0); 91210389Sgabor# else /* !COHERENT */ 92210389Sgabor time0 = HZ * time(NULL); 93210389Sgabor times(×0); 94210389Sgabor# endif /* !COHERENT */ 95210389Sgabor times0.tms_stime += times0.tms_cstime; 96210389Sgabor times0.tms_utime += times0.tms_cutime; 97210389Sgabor times0.tms_cstime = 0; 98210389Sgabor times0.tms_cutime = 0; 99210389Sgabor# endif /* _SEQUENT_ */ 100210389Sgabor#endif /* BSDTIMES */ 101210389Sgabor} 102210389Sgabor 103210389Sgabor/* 104210389Sgabor * dotime is only called if it is truly a builtin function and not a 105210389Sgabor * prefix to another command 106210389Sgabor */ 107210389Sgabor/*ARGSUSED*/ 108210389Sgaborvoid 109210389Sgabordotime(v, c) 110210389Sgabor Char **v; 111210389Sgabor struct command *c; 112210389Sgabor{ 113210389Sgabor#ifdef BSDTIMES 114210389Sgabor timeval_t timedol; 115210389Sgabor struct sysrusage ru1, ruch; 116210389Sgabor#ifdef convex 117210389Sgabor memset(&ru1, 0, sizeof(ru1)); 118210389Sgabor memset(&ruch, 0, sizeof(ruch)); 119210389Sgabor#endif /* convex */ 120210389Sgabor 121210389Sgabor (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1); 122210389Sgabor (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 123210389Sgabor ruadd(&ru1, &ruch); 124210389Sgabor (void) gettimeofday(&timedol, NULL); 125210389Sgabor prusage(&ru0, &ru1, &timedol, &time0); 126210389Sgabor#else 127210389Sgabor# ifdef _SEQUENT_ 128210389Sgabor timeval_t timedol; 129210389Sgabor struct process_stats ru1, ruch; 130210389Sgabor 131210389Sgabor (void) get_process_stats(&timedol, PS_SELF, &ru1, &ruch); 132210389Sgabor ruadd(&ru1, &ruch); 133210389Sgabor prusage(&ru0, &ru1, &timedol, &time0); 134210389Sgabor# else /* _SEQUENT_ */ 135210389Sgabor# ifndef POSIX 136210389Sgabor time_t timedol; 137210389Sgabor# else /* POSIX */ 138210389Sgabor clock_t timedol; 139210389Sgabor# endif /* POSIX */ 140210389Sgabor 141210389Sgabor struct tms times_dol; 142210389Sgabor 143210389Sgabor#ifndef COHERENT 144210389Sgabor timedol = times(×_dol); 145210389Sgabor#else 146210389Sgabor timedol = HZ * time(NULL); 147210389Sgabor times(×_dol); 148210389Sgabor#endif 149210389Sgabor times_dol.tms_stime += times_dol.tms_cstime; 150210389Sgabor times_dol.tms_utime += times_dol.tms_cutime; 151210389Sgabor times_dol.tms_cstime = 0; 152210389Sgabor times_dol.tms_cutime = 0; 153210389Sgabor prusage(×0, ×_dol, timedol, time0); 154210389Sgabor# endif /* _SEQUENT_ */ 155210389Sgabor#endif /* BSDTIMES */ 156210389Sgabor USE(c); 157210389Sgabor USE(v); 158210389Sgabor} 159210389Sgabor 160210389Sgabor/* 161210389Sgabor * donice is only called when it on the line by itself or with a +- value 162210389Sgabor */ 163/*ARGSUSED*/ 164void 165donice(v, c) 166 register Char **v; 167 struct command *c; 168{ 169 register Char *cp; 170 int nval = 0; 171 172 USE(c); 173 v++, cp = *v++; 174 if (cp == 0) 175 nval = 4; 176 else if (*v == 0 && any("+-", cp[0])) 177 nval = getn(cp); 178#ifdef BSDNICE 179 (void) setpriority(PRIO_PROCESS, 0, nval); 180#else /* BSDNICE */ 181 (void) nice(nval); 182#endif /* BSDNICE */ 183} 184 185#ifdef BSDTIMES 186void 187ruadd(ru, ru2) 188 register struct sysrusage *ru, *ru2; 189{ 190 tvadd(&ru->ru_utime, &ru2->ru_utime); 191 tvadd(&ru->ru_stime, &ru2->ru_stime); 192 if (ru2->ru_maxrss > ru->ru_maxrss) 193 ru->ru_maxrss = ru2->ru_maxrss; 194 195 ru->ru_ixrss += ru2->ru_ixrss; 196 ru->ru_idrss += ru2->ru_idrss; 197 ru->ru_isrss += ru2->ru_isrss; 198 ru->ru_minflt += ru2->ru_minflt; 199 ru->ru_majflt += ru2->ru_majflt; 200 ru->ru_nswap += ru2->ru_nswap; 201 ru->ru_inblock += ru2->ru_inblock; 202 ru->ru_oublock += ru2->ru_oublock; 203 ru->ru_msgsnd += ru2->ru_msgsnd; 204 ru->ru_msgrcv += ru2->ru_msgrcv; 205 ru->ru_nsignals += ru2->ru_nsignals; 206 ru->ru_nvcsw += ru2->ru_nvcsw; 207 ru->ru_nivcsw += ru2->ru_nivcsw; 208 209# ifdef convex 210 tvadd(&ru->ru_exutime, &ru2->ru_exutime); 211 ru->ru_utotal += ru2->ru_utotal; 212 ru->ru_usamples += ru2->ru_usamples; 213 ru->ru_stotal += ru2->ru_stotal; 214 ru->ru_ssamples += ru2->ru_ssamples; 215# endif /* convex */ 216} 217 218#else /* BSDTIMES */ 219# ifdef _SEQUENT_ 220void 221ruadd(ru, ru2) 222 register struct process_stats *ru, *ru2; 223{ 224 tvadd(&ru->ps_utime, &ru2->ps_utime); 225 tvadd(&ru->ps_stime, &ru2->ps_stime); 226 if (ru2->ps_maxrss > ru->ps_maxrss) 227 ru->ps_maxrss = ru2->ps_maxrss; 228 229 ru->ps_pagein += ru2->ps_pagein; 230 ru->ps_reclaim += ru2->ps_reclaim; 231 ru->ps_zerofill += ru2->ps_zerofill; 232 ru->ps_pffincr += ru2->ps_pffincr; 233 ru->ps_pffdecr += ru2->ps_pffdecr; 234 ru->ps_swap += ru2->ps_swap; 235 ru->ps_syscall += ru2->ps_syscall; 236 ru->ps_volcsw += ru2->ps_volcsw; 237 ru->ps_involcsw += ru2->ps_involcsw; 238 ru->ps_signal += ru2->ps_signal; 239 ru->ps_lread += ru2->ps_lread; 240 ru->ps_lwrite += ru2->ps_lwrite; 241 ru->ps_bread += ru2->ps_bread; 242 ru->ps_bwrite += ru2->ps_bwrite; 243 ru->ps_phread += ru2->ps_phread; 244 ru->ps_phwrite += ru2->ps_phwrite; 245} 246 247# endif /* _SEQUENT_ */ 248#endif /* BSDTIMES */ 249 250#ifdef BSDTIMES 251 252/* 253 * PWP: the LOG1024 and pagetok stuff taken from the top command, 254 * written by William LeFebvre 255 */ 256/* Log base 2 of 1024 is 10 (2^10 == 1024) */ 257#define LOG1024 10 258 259/* Convert clicks (kernel pages) to kbytes ... */ 260/* If there is no PGSHIFT defined, assume it is 11 */ 261/* Is this needed for compatability with some old flavor of 4.2 or 4.1? */ 262#ifdef SUNOS4 263# ifndef PGSHIFT 264# define pagetok(size) ((size) << 1) 265# else 266# if PGSHIFT>10 267# define pagetok(size) ((size) << (PGSHIFT - LOG1024)) 268# else 269# define pagetok(size) ((size) >> (LOG1024 - PGSHIFT)) 270# endif 271# endif 272#endif 273 274/* 275 * if any other machines return wierd values in the ru_i* stuff, put 276 * the adjusting macro here: 277 */ 278#ifdef SUNOS4 279# define IADJUST(i) (pagetok(i)/2) 280#else /* SUNOS4 */ 281# ifdef convex 282 /* 283 * convex has megabytes * CLK_TCK 284 * multiply by 100 since we use time in 100ths of a second in prusage 285 */ 286# define IADJUST(i) (((i) << 10) / CLK_TCK * 100) 287# else /* convex */ 288# define IADJUST(i) (i) 289# endif /* convex */ 290#endif /* SUNOS4 */ 291 292void 293prusage(r0, r1, e, b) 294 register struct sysrusage *r0, *r1; 295 timeval_t *e, *b; 296 297#else /* BSDTIMES */ 298# ifdef _SEQUENT_ 299void 300prusage(r0, r1, e, b) 301 register struct process_stats *r0, *r1; 302 timeval_t *e, *b; 303 304# else /* _SEQUENT_ */ 305void 306prusage(bs, es, e, b) 307 struct tms *bs, *es; 308 309# ifndef POSIX 310 time_t e, b; 311 312# else /* POSIX */ 313 clock_t e, b; 314 315# endif /* POSIX */ 316# endif /* _SEQUENT_ */ 317#endif /* BSDTIMES */ 318{ 319#ifdef BSDTIMES 320 register time_t t = 321 (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + 322 (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + 323 (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + 324 (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; 325 326#else 327# ifdef _SEQUENT_ 328 register time_t t = 329 (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec) * 100 + 330 (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 + 331 (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec) * 100 + 332 (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000; 333 334# else /* _SEQUENT_ */ 335# ifndef POSIX 336 register time_t t = (es->tms_utime - bs->tms_utime + 337 es->tms_stime - bs->tms_stime) * 100 / HZ; 338 339# else /* POSIX */ 340 register clock_t t = (es->tms_utime - bs->tms_utime + 341 es->tms_stime - bs->tms_stime) * 100 / clk_tck; 342 343# endif /* POSIX */ 344# endif /* _SEQUENT_ */ 345#endif /* BSDTIMES */ 346 347 register char *cp; 348 register long i; 349 register struct varent *vp = adrof(STRtime); 350 351#ifdef BSDTIMES 352# ifdef convex 353 static struct system_information sysinfo; 354 long long memtmp; /* let memory calculations exceede 2Gb */ 355# endif /* convex */ 356 int ms = (int) 357 ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 358 359 cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 360#else /* !BSDTIMES */ 361# ifdef _SEQUENT_ 362 int ms = (int) 363 ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 364 365 cp = "%Uu %Ss %E %P %I+%Oio %Fpf+%Ww"; 366# else /* !_SEQUENT_ */ 367# ifndef POSIX 368 time_t ms = ((time_t)((e - b) / HZ) * 100) + 369 (time_t)(((e - b) % HZ) * 100) / HZ; 370# else /* POSIX */ 371 clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) + 372 (clock_t)(((e - b) % clk_tck) * 100) / clk_tck; 373# endif /* POSIX */ 374 375 cp = "%Uu %Ss %E %P"; 376 377 /* 378 * the tms stuff is not very precise, so we fudge it. 379 * granularity fix: can't be more than 100% 380 * this breaks in multi-processor systems... 381 * maybe I should take it out and let people see more then 100% 382 * utilizations. 383 */ 384# if 0 385 if (ms < t && ms != 0) 386 ms = t; 387# endif 388# endif /*! _SEQUENT_ */ 389#endif /* !BSDTIMES */ 390#ifdef TDEBUG 391 xprintf("es->tms_utime %lu bs->tms_utime %lu\n", 392 es->tms_utime, bs->tms_utime); 393 xprintf("es->tms_stime %lu bs->tms_stime %lu\n", 394 es->tms_stime, bs->tms_stime); 395 xprintf("ms %lu e %lu b %lu\n", ms, e, b); 396 xprintf("t %lu\n", t); 397#endif /* TDEBUG */ 398 399 if (vp && vp->vec[0] && vp->vec[1]) 400 cp = short2str(vp->vec[1]); 401 for (; *cp; cp++) 402 if (*cp != '%') 403 xputchar(*cp); 404 else if (cp[1]) 405 switch (*++cp) { 406 407 case 'U': /* user CPU time used */ 408#ifdef BSDTIMES 409 pdeltat(&r1->ru_utime, &r0->ru_utime); 410#else 411# ifdef _SEQUENT_ 412 pdeltat(&r1->ps_utime, &r0->ps_utime); 413# else /* _SEQUENT_ */ 414# ifndef POSIX 415 pdtimet(es->tms_utime, bs->tms_utime); 416# else /* POSIX */ 417 pdtimet(es->tms_utime, bs->tms_utime); 418# endif /* POSIX */ 419# endif /* _SEQUENT_ */ 420#endif /* BSDTIMES */ 421 break; 422 423 case 'S': /* system CPU time used */ 424#ifdef BSDTIMES 425 pdeltat(&r1->ru_stime, &r0->ru_stime); 426#else 427# ifdef _SEQUENT_ 428 pdeltat(&r1->ps_stime, &r0->ps_stime); 429# else /* _SEQUENT_ */ 430# ifndef POSIX 431 pdtimet(es->tms_stime, bs->tms_stime); 432# else /* POSIX */ 433 pdtimet(es->tms_stime, bs->tms_stime); 434# endif /* POSIX */ 435# endif /* _SEQUENT_ */ 436#endif /* BSDTIMES */ 437 break; 438 439 case 'E': /* elapsed (wall-clock) time */ 440#ifdef BSDTIMES 441 pcsecs((long) ms); 442#else /* BSDTIMES */ 443 pcsecs(ms); 444#endif /* BSDTIMES */ 445 break; 446 447 case 'P': /* percent time spent running */ 448 /* check if the process did not run */ 449#ifdef convex 450 /* 451 * scale the cpu %- ages by the number of processors 452 * available on this machine 453 */ 454 if ((sysinfo.cpu_count == 0) && 455 (getsysinfo(SYSINFO_SIZE, &sysinfo) < 0)) 456 sysinfo.cpu_count = 1; 457 i = (ms == 0) ? 0 : (t * 1000 / (ms * sysinfo.cpu_count)); 458#else /* convex */ 459 i = (ms == 0) ? 0 : (t * 1000 / ms); 460#endif /* convex */ 461 xprintf("%ld.%01ld%%", i / 10, i % 10); /* nn.n% */ 462 break; 463 464#ifdef BSDTIMES 465 case 'W': /* number of swaps */ 466 i = r1->ru_nswap - r0->ru_nswap; 467 xprintf("%ld", i); 468 break; 469 470#ifdef convex 471 case 'X': /* (average) shared text size */ 472 memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss - 473 (long long)r0->ru_ixrss) / 474 (long long)t); 475 xprintf("%lu", (unsigned long)memtmp); 476 477 break; 478 479 case 'D': /* (average) unshared data size */ 480 memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss + 481 (long long)r1->ru_isrss - 482 ((long long)r0->ru_idrss + 483 (long long)r0->ru_isrss)) / 484 (long long)t); 485 xprintf("%lu", (unsigned long)memtmp); 486 break; 487 488 case 'K': /* (average) total data memory used */ 489 memtmp = (t == 0 ? 0LL : IADJUST(((long long)r1->ru_ixrss + 490 (long long)r1->ru_isrss + 491 (long long)r1->ru_idrss) - 492 ((long long)r0->ru_ixrss + 493 (long long)r0->ru_idrss + 494 (long long)r0->ru_isrss)) / 495 (long long)t); 496 xprintf("%lu", (unsigned long)memtmp); 497 break; 498#else /* !convex */ 499 case 'X': /* (average) shared text size */ 500 xprintf("%ld", t == 0 ? 0L : 501 IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t); 502 break; 503 504 case 'D': /* (average) unshared data size */ 505 xprintf("%ld", t == 0 ? 0L : 506 IADJUST(r1->ru_idrss + r1->ru_isrss - 507 (r0->ru_idrss + r0->ru_isrss)) / t); 508 break; 509 510 case 'K': /* (average) total data memory used */ 511 xprintf("%ld", t == 0 ? 0L : 512 IADJUST((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - 513 (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); 514 break; 515#endif /* convex */ 516 case 'M': /* max. Resident Set Size */ 517#ifdef SUNOS4 518 xprintf("%ld", pagetok(r1->ru_maxrss)); 519#else 520# ifdef convex 521 xprintf("%ld", r1->ru_maxrss * 4L); 522# else /* !convex */ 523 xprintf("%ld", r1->ru_maxrss / 2L); 524# endif /* convex */ 525#endif /* SUNOS4 */ 526 break; 527 528 case 'F': /* page faults */ 529 xprintf("%ld", r1->ru_majflt - r0->ru_majflt); 530 break; 531 532 case 'R': /* page reclaims */ 533 xprintf("%ld", r1->ru_minflt - r0->ru_minflt); 534 break; 535 536 case 'I': /* FS blocks in */ 537 xprintf("%ld", r1->ru_inblock - r0->ru_inblock); 538 break; 539 540 case 'O': /* FS blocks out */ 541 xprintf("%ld", r1->ru_oublock - r0->ru_oublock); 542 break; 543 544# ifdef convex 545 case 'C': /* CPU parallelization factor */ 546 if (r1->ru_usamples != 0LL) { 547 long long parr = ((r1->ru_utotal * 100LL) / 548 r1->ru_usamples); 549 xprintf("%d.%02d", (int)(parr/100), (int)(parr%100)); 550 } else 551 xprintf("?"); 552 break; 553# endif /* convex */ 554 case 'r': /* PWP: socket messages recieved */ 555 xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv); 556 break; 557 558 case 's': /* PWP: socket messages sent */ 559 xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd); 560 break; 561 562 case 'k': /* PWP: signals received */ 563 xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals); 564 break; 565 566 case 'w': /* PWP: voluntary context switches (waits) */ 567 xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw); 568 break; 569 570 case 'c': /* PWP: involuntary context switches */ 571 xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw); 572 break; 573#else /* BSDTIMES */ 574# ifdef _SEQUENT_ 575 case 'W': /* number of swaps */ 576 i = r1->ps_swap - r0->ps_swap; 577 xprintf("%ld", i); 578 break; 579 580 case 'M': 581 xprintf("%ld", r1->ps_maxrss / 2); 582 break; 583 584 case 'F': 585 xprintf("%ld", r1->ps_pagein - r0->ps_pagein); 586 break; 587 588 case 'R': 589 xprintf("%ld", r1->ps_reclaim - r0->ps_reclaim); 590 break; 591 592 case 'I': 593 xprintf("%ld", r1->ps_bread - r0->ps_bread); 594 break; 595 596 case 'O': 597 xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite); 598 break; 599 600 case 'k': 601 xprintf("%ld", r1->ps_signal - r0->ps_signal); 602 break; 603 604 case 'w': 605 xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw); 606 break; 607 608 case 'c': 609 xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw); 610 break; 611 612 case 'Z': 613 xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill); 614 break; 615 616 case 'i': 617 xprintf("%ld", r1->ps_pffincr - r0->ps_pffincr); 618 break; 619 620 case 'd': 621 xprintf("%ld", r1->ps_pffdecr - r0->ps_pffdecr); 622 break; 623 624 case 'Y': 625 xprintf("%ld", r1->ps_syscall - r0->ps_syscall); 626 break; 627 628 case 'l': 629 xprintf("%ld", r1->ps_lread - r0->ps_lread); 630 break; 631 632 case 'm': 633 xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite); 634 break; 635 636 case 'p': 637 xprintf("%ld", r1->ps_phread - r0->ps_phread); 638 break; 639 640 case 'q': 641 xprintf("%ld", r1->ps_phwrite - r0->ps_phwrite); 642 break; 643# endif /* _SEQUENT_ */ 644#endif /* BSDTIMES */ 645 default: 646 break; 647 } 648 xputchar('\n'); 649} 650 651#if defined(BSDTIMES) || defined(_SEQUENT_) 652static void 653pdeltat(t1, t0) 654 timeval_t *t1, *t0; 655{ 656 timeval_t td; 657 658 tvsub(&td, t1, t0); 659 xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L); 660} 661 662static void 663tvadd(tsum, t0) 664 timeval_t *tsum, *t0; 665{ 666 667 tsum->tv_sec += t0->tv_sec; 668 tsum->tv_usec += t0->tv_usec; 669 if (tsum->tv_usec >= 1000000) 670 tsum->tv_sec++, tsum->tv_usec -= 1000000; 671} 672 673void 674tvsub(tdiff, t1, t0) 675 timeval_t *tdiff, *t1, *t0; 676{ 677 678 tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 679 tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 680 if (tdiff->tv_usec < 0) 681 tdiff->tv_sec--, tdiff->tv_usec += 1000000; 682} 683 684#else /* !BSDTIMES && !_SEQUENT_ */ 685static void 686pdtimet(eval, bval) 687#ifndef POSIX 688 time_t eval, bval; 689 690#else /* POSIX */ 691 clock_t eval, bval; 692 693#endif /* POSIX */ 694{ 695#ifndef POSIX 696 time_t val; 697 698#else /* POSIX */ 699 clock_t val; 700 701#endif /* POSIX */ 702 703#ifndef POSIX 704 val = (eval - bval) * 100 / HZ; 705#else /* POSIX */ 706 val = (eval - bval) * 100 / clk_tck; 707#endif /* POSIX */ 708 709 xprintf("%ld.%02ld", val / 100, val - (val / 100 * 100)); 710} 711#endif /* BSDTIMES || _SEQUENT_ */ 712