sh.time.c revision 167466
1204076Spjd/* $Header: /p/tcsh/cvsroot/tcsh/sh.time.c,v 3.33 2006/03/02 18:46:44 christos Exp $ */ 2204076Spjd/* 3210886Spjd * sh.time.c: Shell time keeping and printing. 4204076Spjd */ 5204076Spjd/*- 6204076Spjd * Copyright (c) 1980, 1991 The Regents of the University of California. 7204076Spjd * All rights reserved. 8204076Spjd * 9204076Spjd * Redistribution and use in source and binary forms, with or without 10204076Spjd * modification, are permitted provided that the following conditions 11204076Spjd * are met: 12204076Spjd * 1. Redistributions of source code must retain the above copyright 13204076Spjd * notice, this list of conditions and the following disclaimer. 14204076Spjd * 2. Redistributions in binary form must reproduce the above copyright 15204076Spjd * notice, this list of conditions and the following disclaimer in the 16204076Spjd * documentation and/or other materials provided with the distribution. 17204076Spjd * 3. Neither the name of the University nor the names of its contributors 18204076Spjd * may be used to endorse or promote products derived from this software 19204076Spjd * without specific prior written permission. 20204076Spjd * 21204076Spjd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23204076Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24204076Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25204076Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27204076Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28204076Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29204076Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30204076Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31204076Spjd * SUCH DAMAGE. 32204076Spjd */ 33204076Spjd#include "sh.h" 34204076Spjd 35204076SpjdRCSID("$tcsh: sh.time.c,v 3.33 2006/03/02 18:46:44 christos Exp $") 36204076Spjd 37204076Spjd#ifdef SUNOS4 38204076Spjd# include <machine/param.h> 39204076Spjd#endif /* SUNOS4 */ 40204076Spjd 41204076Spjd/* 42204076Spjd * C Shell - routines handling process timing and niceing 43204076Spjd */ 44204076Spjd#ifdef BSDTIMES 45204076Spjd# ifndef RUSAGE_SELF 46204076Spjd# define RUSAGE_SELF 0 47204076Spjd# define RUSAGE_CHILDREN -1 48204076Spjd# endif /* RUSAGE_SELF */ 49211982Spjd#else /* BSDTIMES */ 50204076Spjdstruct tms times0; 51204076Spjd#endif /* BSDTIMES */ 52204076Spjd 53204076Spjd#if !defined(BSDTIMES) && !defined(_SEQUENT_) 54204076Spjd# ifdef POSIX 55204076Spjdstatic void pdtimet (clock_t, clock_t); 56204076Spjd# else /* ! POSIX */ 57204076Spjdstatic void pdtimet (time_t, time_t); 58204076Spjd# endif /* ! POSIX */ 59204076Spjd#else /* BSDTIMES || _SEQUENT_ */ 60204076Spjdstatic void tvadd (timeval_t *, timeval_t *); 61212038Spjdstatic void pdeltat (timeval_t *, timeval_t *); 62204076Spjd#endif /* BSDTIMES || _SEQUENT_ */ 63204076Spjd 64204076Spjdvoid 65211886Spjdsettimes(void) 66204076Spjd{ 67204076Spjd#ifdef BSDTIMES 68204076Spjd struct sysrusage ruch; 69204076Spjd#ifdef convex 70204076Spjd memset(&ru0, 0, sizeof(ru0)); 71204076Spjd memset(&ruch, 0, sizeof(ruch)); 72210886Spjd#endif /* convex */ 73210886Spjd 74210886Spjd (void) gettimeofday(&time0, NULL); 75204076Spjd (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0); 76204076Spjd (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 77204076Spjd ruadd(&ru0, &ruch); 78204076Spjd#else 79204076Spjd# ifdef _SEQUENT_ 80204076Spjd struct process_stats ruch; 81204076Spjd 82204076Spjd (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch); 83204076Spjd ruadd(&ru0, &ruch); 84204076Spjd# else /* _SEQUENT_ */ 85204076Spjd seconds0 = time(NULL); 86204076Spjd time0 = times(×0); 87204076Spjd times0.tms_stime += times0.tms_cstime; 88204076Spjd times0.tms_utime += times0.tms_cutime; 89204076Spjd times0.tms_cstime = 0; 90204076Spjd times0.tms_cutime = 0; 91204076Spjd# endif /* _SEQUENT_ */ 92204076Spjd#endif /* BSDTIMES */ 93204076Spjd} 94204076Spjd 95204076Spjd/* 96204076Spjd * dotime is only called if it is truly a builtin function and not a 97204076Spjd * prefix to another command 98204076Spjd */ 99204076Spjd/*ARGSUSED*/ 100204076Spjdvoid 101204076Spjddotime(Char **v, struct command *c) 102204076Spjd{ 103204076Spjd#ifdef BSDTIMES 104204076Spjd timeval_t timedol; 105204076Spjd struct sysrusage ru1, ruch; 106204076Spjd#ifdef convex 107204076Spjd memset(&ru1, 0, sizeof(ru1)); 108204076Spjd memset(&ruch, 0, sizeof(ruch)); 109204076Spjd#endif /* convex */ 110204076Spjd 111204076Spjd (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1); 112204076Spjd (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 113204076Spjd ruadd(&ru1, &ruch); 114204076Spjd (void) gettimeofday(&timedol, NULL); 115204076Spjd prusage(&ru0, &ru1, &timedol, &time0); 116204076Spjd#else 117204076Spjd# ifdef _SEQUENT_ 118204076Spjd timeval_t timedol; 119204076Spjd struct process_stats ru1, ruch; 120204076Spjd 121204076Spjd (void) get_process_stats(&timedol, PS_SELF, &ru1, &ruch); 122204076Spjd ruadd(&ru1, &ruch); 123204076Spjd prusage(&ru0, &ru1, &timedol, &time0); 124204076Spjd# else /* _SEQUENT_ */ 125204076Spjd# ifndef POSIX 126204076Spjd time_t timedol; 127204076Spjd# else /* POSIX */ 128204076Spjd clock_t timedol; 129204076Spjd# endif /* POSIX */ 130204076Spjd 131204076Spjd struct tms times_dol; 132204076Spjd 133204076Spjd timedol = times(×_dol); 134204076Spjd times_dol.tms_stime += times_dol.tms_cstime; 135204076Spjd times_dol.tms_utime += times_dol.tms_cutime; 136204076Spjd times_dol.tms_cstime = 0; 137204076Spjd times_dol.tms_cutime = 0; 138204076Spjd prusage(×0, ×_dol, timedol, time0); 139204076Spjd# endif /* _SEQUENT_ */ 140204076Spjd#endif /* BSDTIMES */ 141204076Spjd USE(c); 142204076Spjd USE(v); 143204076Spjd} 144204076Spjd 145204076Spjd/* 146204076Spjd * donice is only called when it on the line by itself or with a +- value 147204076Spjd */ 148204076Spjd/*ARGSUSED*/ 149204076Spjdvoid 150204076Spjddonice(Char **v, struct command *c) 151204076Spjd{ 152204076Spjd Char *cp; 153204076Spjd int nval = 0; 154204076Spjd 155211982Spjd USE(c); 156204076Spjd v++, cp = *v++; 157211982Spjd if (cp == 0) 158204076Spjd nval = 4; 159204076Spjd else if (*v == 0 && any("+-", cp[0])) 160204076Spjd nval = getn(cp); 161204076Spjd#ifdef HAVE_SETPRIORITY 162204076Spjd if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno) 163204076Spjd stderror(ERR_SYSTEM, "setpriority", strerror(errno)); 164204076Spjd#else /* !HAVE_SETPRIORITY */ 165204076Spjd (void) nice(nval); 166204076Spjd#endif /* HAVE_SETPRIORITY */ 167204076Spjd} 168204076Spjd 169204076Spjd#ifdef BSDTIMES 170204076Spjdvoid 171204076Spjdruadd(struct sysrusage *ru, struct sysrusage *ru2) 172204076Spjd{ 173204076Spjd tvadd(&ru->ru_utime, &ru2->ru_utime); 174204076Spjd tvadd(&ru->ru_stime, &ru2->ru_stime); 175204076Spjd#ifndef _OSD_POSIX 176204076Spjd if (ru2->ru_maxrss > ru->ru_maxrss) 177204076Spjd ru->ru_maxrss = ru2->ru_maxrss; 178204076Spjd 179204076Spjd ru->ru_ixrss += ru2->ru_ixrss; 180204076Spjd ru->ru_idrss += ru2->ru_idrss; 181204076Spjd ru->ru_isrss += ru2->ru_isrss; 182204076Spjd ru->ru_minflt += ru2->ru_minflt; 183214692Spjd ru->ru_majflt += ru2->ru_majflt; 184214692Spjd ru->ru_nswap += ru2->ru_nswap; 185214692Spjd ru->ru_inblock += ru2->ru_inblock; 186204076Spjd ru->ru_oublock += ru2->ru_oublock; 187214692Spjd ru->ru_msgsnd += ru2->ru_msgsnd; 188214692Spjd ru->ru_msgrcv += ru2->ru_msgrcv; 189214692Spjd ru->ru_nsignals += ru2->ru_nsignals; 190214692Spjd ru->ru_nvcsw += ru2->ru_nvcsw; 191214692Spjd ru->ru_nivcsw += ru2->ru_nivcsw; 192214692Spjd#endif /*bs2000*/ 193204076Spjd 194214692Spjd# ifdef convex 195214692Spjd tvadd(&ru->ru_exutime, &ru2->ru_exutime); 196214692Spjd ru->ru_utotal += ru2->ru_utotal; 197214692Spjd ru->ru_usamples += ru2->ru_usamples; 198204076Spjd ru->ru_stotal += ru2->ru_stotal; 199204076Spjd ru->ru_ssamples += ru2->ru_ssamples; 200204076Spjd# endif /* convex */ 201204076Spjd} 202204076Spjd 203204076Spjd#else /* BSDTIMES */ 204204076Spjd# ifdef _SEQUENT_ 205204076Spjdvoid 206204076Spjdruadd(struct process_stats *ru, struct process_stats *ru2) 207204076Spjd{ 208204076Spjd tvadd(&ru->ps_utime, &ru2->ps_utime); 209204076Spjd tvadd(&ru->ps_stime, &ru2->ps_stime); 210209183Spjd if (ru2->ps_maxrss > ru->ps_maxrss) 211209183Spjd ru->ps_maxrss = ru2->ps_maxrss; 212209183Spjd 213209183Spjd ru->ps_pagein += ru2->ps_pagein; 214204076Spjd ru->ps_reclaim += ru2->ps_reclaim; 215204076Spjd ru->ps_zerofill += ru2->ps_zerofill; 216204076Spjd ru->ps_pffincr += ru2->ps_pffincr; 217204076Spjd ru->ps_pffdecr += ru2->ps_pffdecr; 218204076Spjd ru->ps_swap += ru2->ps_swap; 219204076Spjd ru->ps_syscall += ru2->ps_syscall; 220204076Spjd ru->ps_volcsw += ru2->ps_volcsw; 221204076Spjd ru->ps_involcsw += ru2->ps_involcsw; 222204076Spjd ru->ps_signal += ru2->ps_signal; 223204076Spjd ru->ps_lread += ru2->ps_lread; 224204076Spjd ru->ps_lwrite += ru2->ps_lwrite; 225204076Spjd ru->ps_bread += ru2->ps_bread; 226204076Spjd ru->ps_bwrite += ru2->ps_bwrite; 227204076Spjd ru->ps_phread += ru2->ps_phread; 228204076Spjd ru->ps_phwrite += ru2->ps_phwrite; 229204076Spjd} 230204076Spjd 231204076Spjd# endif /* _SEQUENT_ */ 232204076Spjd#endif /* BSDTIMES */ 233204076Spjd 234204076Spjd#ifdef BSDTIMES 235204076Spjd 236211982Spjd/* 237204076Spjd * PWP: the LOG1024 and pagetok stuff taken from the top command, 238204076Spjd * written by William LeFebvre 239204076Spjd */ 240204076Spjd/* Log base 2 of 1024 is 10 (2^10 == 1024) */ 241204076Spjd#define LOG1024 10 242204076Spjd 243204076Spjd/* Convert clicks (kernel pages) to kbytes ... */ 244204076Spjd/* If there is no PGSHIFT defined, assume it is 11 */ 245204076Spjd/* Is this needed for compatability with some old flavor of 4.2 or 4.1? */ 246204076Spjd#ifdef SUNOS4 247204076Spjd# ifndef PGSHIFT 248213533Spjd# define pagetok(size) ((size) << 1) 249204076Spjd# else 250204076Spjd# if PGSHIFT>10 251204076Spjd# define pagetok(size) ((size) << (PGSHIFT - LOG1024)) 252204076Spjd# else 253213531Spjd# define pagetok(size) ((size) >> (LOG1024 - PGSHIFT)) 254213531Spjd# endif 255204076Spjd# endif 256204076Spjd#endif 257204076Spjd 258204076Spjd/* 259204076Spjd * if any other machines return wierd values in the ru_i* stuff, put 260204076Spjd * the adjusting macro here: 261204076Spjd */ 262204076Spjd#ifdef SUNOS4 263204076Spjd# define IADJUST(i) (pagetok(i)/2) 264212899Spjd#else /* SUNOS4 */ 265204076Spjd# ifdef convex 266204076Spjd /* 267204076Spjd * convex has megabytes * CLK_TCK 268204076Spjd * multiply by 100 since we use time in 100ths of a second in prusage 269204076Spjd */ 270204076Spjd# define IADJUST(i) (((i) << 10) / CLK_TCK * 100) 271204076Spjd# else /* convex */ 272204076Spjd# define IADJUST(i) (i) 273204076Spjd# endif /* convex */ 274204076Spjd#endif /* SUNOS4 */ 275204076Spjd 276204076Spjdvoid 277212899Spjdprusage(struct sysrusage *r0, struct sysrusage *r1, timeval_t *e, timeval_t *b) 278204076Spjd 279204076Spjd#else /* BSDTIMES */ 280204076Spjd# ifdef _SEQUENT_ 281204076Spjdvoid 282204076Spjdprusage(struct process_stats *r0, struct process_stats *r1, timeval_t e, 283204076Spjd timeval_t b) 284204076Spjd 285204076Spjd# else /* _SEQUENT_ */ 286204076Spjd# ifndef POSIX 287204076Spjdvoid 288204076Spjdprusage(struct tms *bs, struct tms *es, time_t e, time_t b) 289204076Spjd# else /* POSIX */ 290204076Spjdvoid 291204076Spjdprusage(struct tms *bs, struct tms *es, clock_t e, clock_t b) 292204076Spjd# endif /* POSIX */ 293204076Spjd# endif /* _SEQUENT_ */ 294204076Spjd#endif /* BSDTIMES */ 295204076Spjd{ 296204076Spjd#ifdef BSDTIMES 297204076Spjd time_t t = 298204076Spjd (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + 299204076Spjd (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + 300204076Spjd (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + 301204076Spjd (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; 302204076Spjd 303204076Spjd#else 304204076Spjd# ifdef _SEQUENT_ 305204076Spjd time_t t = 306204076Spjd (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec) * 100 + 307210881Spjd (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 + 308210881Spjd (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec) * 100 + 309210881Spjd (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000; 310210881Spjd 311210881Spjd# else /* _SEQUENT_ */ 312210881Spjd# ifndef POSIX 313210881Spjd time_t t = (es->tms_utime - bs->tms_utime + 314204076Spjd es->tms_stime - bs->tms_stime) * 100 / HZ; 315204076Spjd 316204076Spjd# else /* POSIX */ 317204076Spjd clock_t t = (es->tms_utime - bs->tms_utime + 318204076Spjd es->tms_stime - bs->tms_stime) * 100 / clk_tck; 319204076Spjd 320204076Spjd# endif /* POSIX */ 321204076Spjd# endif /* _SEQUENT_ */ 322204076Spjd#endif /* BSDTIMES */ 323204076Spjd 324204076Spjd const char *cp; 325204076Spjd long i; 326204076Spjd struct varent *vp = adrof(STRtime); 327204076Spjd 328204076Spjd#ifdef BSDTIMES 329204076Spjd# ifdef convex 330204076Spjd static struct system_information sysinfo; 331204076Spjd long long memtmp; /* let memory calculations exceede 2Gb */ 332204076Spjd# endif /* convex */ 333204076Spjd int ms = (int) 334204076Spjd ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 335204076Spjd 336204076Spjd cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 337204076Spjd#else /* !BSDTIMES */ 338204076Spjd# ifdef _SEQUENT_ 339204076Spjd int ms = (int) 340204076Spjd ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 341204076Spjd 342204076Spjd cp = "%Uu %Ss %E %P %I+%Oio %Fpf+%Ww"; 343204076Spjd# else /* !_SEQUENT_ */ 344204076Spjd# ifndef POSIX 345204076Spjd time_t ms = ((time_t)((e - b) / HZ) * 100) + 346204076Spjd (time_t)(((e - b) % HZ) * 100) / HZ; 347204076Spjd# else /* POSIX */ 348204076Spjd clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) + 349204076Spjd (clock_t)(((e - b) % clk_tck) * 100) / clk_tck; 350204076Spjd# endif /* POSIX */ 351204076Spjd 352204076Spjd cp = "%Uu %Ss %E %P"; 353204076Spjd 354204076Spjd /* 355204076Spjd * the tms stuff is not very precise, so we fudge it. 356204076Spjd * granularity fix: can't be more than 100% 357204076Spjd * this breaks in multi-processor systems... 358204076Spjd * maybe I should take it out and let people see more then 100% 359204076Spjd * utilizations. 360204076Spjd */ 361204076Spjd# if 0 362204076Spjd if (ms < t && ms != 0) 363204076Spjd ms = t; 364204076Spjd# endif 365204076Spjd# endif /*! _SEQUENT_ */ 366204076Spjd#endif /* !BSDTIMES */ 367204076Spjd#ifdef TDEBUG 368204076Spjd xprintf("es->tms_utime %lu bs->tms_utime %lu\n", 369204076Spjd es->tms_utime, bs->tms_utime); 370204076Spjd xprintf("es->tms_stime %lu bs->tms_stime %lu\n", 371204076Spjd es->tms_stime, bs->tms_stime); 372204076Spjd xprintf("ms %lu e %lu b %lu\n", ms, e, b); 373204076Spjd xprintf("t %lu\n", t); 374204076Spjd#endif /* TDEBUG */ 375204076Spjd 376204076Spjd if (vp && vp->vec && vp->vec[0] && vp->vec[1]) 377204076Spjd cp = short2str(vp->vec[1]); 378204076Spjd for (; *cp; cp++) 379204076Spjd if (*cp != '%') 380204076Spjd xputchar(*cp); 381204076Spjd else if (cp[1]) 382204076Spjd switch (*++cp) { 383204076Spjd 384204076Spjd case 'U': /* user CPU time used */ 385204076Spjd#ifdef BSDTIMES 386204076Spjd pdeltat(&r1->ru_utime, &r0->ru_utime); 387204076Spjd#else 388204076Spjd# ifdef _SEQUENT_ 389204076Spjd pdeltat(&r1->ps_utime, &r0->ps_utime); 390204076Spjd# else /* _SEQUENT_ */ 391204076Spjd# ifndef POSIX 392204076Spjd pdtimet(es->tms_utime, bs->tms_utime); 393204076Spjd# else /* POSIX */ 394204076Spjd pdtimet(es->tms_utime, bs->tms_utime); 395204076Spjd# endif /* POSIX */ 396204076Spjd# endif /* _SEQUENT_ */ 397204076Spjd#endif /* BSDTIMES */ 398204076Spjd break; 399204076Spjd 400204076Spjd case 'S': /* system CPU time used */ 401204076Spjd#ifdef BSDTIMES 402204076Spjd pdeltat(&r1->ru_stime, &r0->ru_stime); 403204076Spjd#else 404204076Spjd# ifdef _SEQUENT_ 405204076Spjd pdeltat(&r1->ps_stime, &r0->ps_stime); 406204076Spjd# else /* _SEQUENT_ */ 407204076Spjd# ifndef POSIX 408204076Spjd pdtimet(es->tms_stime, bs->tms_stime); 409204076Spjd# else /* POSIX */ 410204076Spjd pdtimet(es->tms_stime, bs->tms_stime); 411204076Spjd# endif /* POSIX */ 412204076Spjd# endif /* _SEQUENT_ */ 413204076Spjd#endif /* BSDTIMES */ 414204076Spjd break; 415204076Spjd 416204076Spjd case 'E': /* elapsed (wall-clock) time */ 417204076Spjd#ifdef BSDTIMES 418204076Spjd pcsecs((long) ms); 419204076Spjd#else /* BSDTIMES */ 420204076Spjd pcsecs(ms); 421204076Spjd#endif /* BSDTIMES */ 422204076Spjd break; 423204076Spjd 424204076Spjd case 'P': /* percent time spent running */ 425204076Spjd /* check if the process did not run */ 426204076Spjd#ifdef convex 427214284Spjd /* 428214284Spjd * scale the cpu %- ages by the number of processors 429214284Spjd * available on this machine 430214284Spjd */ 431214284Spjd if ((sysinfo.cpu_count == 0) && 432214284Spjd (getsysinfo(SYSINFO_SIZE, &sysinfo) < 0)) 433214284Spjd sysinfo.cpu_count = 1; 434214284Spjd i = (ms == 0) ? 0 : (t * 1000.0 / (ms * sysinfo.cpu_count)); 435214284Spjd#else /* convex */ 436214284Spjd i = (ms == 0) ? 0 : (long)(t * 1000.0 / ms); 437214284Spjd#endif /* convex */ 438214284Spjd xprintf("%ld.%01ld%%", i / 10, i % 10); /* nn.n% */ 439214284Spjd break; 440214284Spjd 441214284Spjd#ifdef BSDTIMES 442214284Spjd case 'W': /* number of swaps */ 443214284Spjd#ifdef _OSD_POSIX 444214284Spjd i = 0; 445204076Spjd#else 446204076Spjd i = r1->ru_nswap - r0->ru_nswap; 447204076Spjd#endif 448204076Spjd xprintf("%ld", i); 449204076Spjd break; 450204076Spjd 451204076Spjd#ifdef convex 452204076Spjd case 'X': /* (average) shared text size */ 453204076Spjd memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss - 454204076Spjd (long long)r0->ru_ixrss) / 455204076Spjd (long long)t); 456204076Spjd xprintf("%lu", (unsigned long)memtmp); 457204076Spjd break; 458204076Spjd 459204076Spjd case 'D': /* (average) unshared data size */ 460204076Spjd memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss + 461204076Spjd (long long)r1->ru_isrss - 462204076Spjd ((long long)r0->ru_idrss + 463204076Spjd (long long)r0->ru_isrss)) / 464204076Spjd (long long)t); 465204076Spjd xprintf("%lu", (unsigned long)memtmp); 466204076Spjd break; 467204076Spjd 468204076Spjd case 'K': /* (average) total data memory used */ 469204076Spjd memtmp = (t == 0 ? 0LL : IADJUST(((long long)r1->ru_ixrss + 470204076Spjd (long long)r1->ru_isrss + 471204076Spjd (long long)r1->ru_idrss) - 472204076Spjd ((long long)r0->ru_ixrss + 473204076Spjd (long long)r0->ru_idrss + 474204076Spjd (long long)r0->ru_isrss)) / 475204076Spjd (long long)t); 476209181Spjd xprintf("%lu", (unsigned long)memtmp); 477204076Spjd break; 478204076Spjd#else /* !convex */ 479204076Spjd case 'X': /* (average) shared text size */ 480214284Spjd#ifdef _OSD_POSIX 481214284Spjd xprintf("0",0); 482214284Spjd#else 483214284Spjd xprintf("%ld", t == 0 ? 0L : 484214284Spjd IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t); 485204076Spjd#endif 486204076Spjd break; 487204076Spjd 488204076Spjd case 'D': /* (average) unshared data size */ 489204076Spjd#ifdef _OSD_POSIX 490204076Spjd xprintf("0",0); 491204076Spjd#else 492205738Spjd xprintf("%ld", t == 0 ? 0L : 493205738Spjd IADJUST(r1->ru_idrss + r1->ru_isrss - 494205738Spjd (r0->ru_idrss + r0->ru_isrss)) / t); 495204076Spjd#endif 496205738Spjd break; 497204076Spjd 498204076Spjd case 'K': /* (average) total data memory used */ 499204076Spjd#ifdef _OSD_POSIX 500204076Spjd xprintf("0",0); 501204076Spjd#else 502204076Spjd xprintf("%ld", t == 0 ? 0L : 503204076Spjd IADJUST((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - 504204076Spjd (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); 505204076Spjd#endif 506205738Spjd break; 507210881Spjd#endif /* convex */ 508205738Spjd case 'M': /* max. Resident Set Size */ 509205738Spjd#ifdef SUNOS4 510211983Spjd xprintf("%ld", pagetok(r1->ru_maxrss)); 511205738Spjd#else 512204076Spjd# ifdef convex 513205738Spjd xprintf("%ld", r1->ru_maxrss * 4L); 514215331Spjd# else /* !convex */ 515215331Spjd# ifdef _OSD_POSIX 516204076Spjd xprintf("0",0); 517204076Spjd# else 518204076Spjd xprintf("%ld", r1->ru_maxrss / 2L); 519205738Spjd# endif 520204076Spjd# endif /* convex */ 521204076Spjd#endif /* SUNOS4 */ 522204076Spjd break; 523204076Spjd 524207371Spjd case 'F': /* page faults */ 525207371Spjd#ifdef _OSD_POSIX 526207371Spjd xprintf("0",0); 527204076Spjd#else 528204076Spjd xprintf("%ld", r1->ru_majflt - r0->ru_majflt); 529204076Spjd#endif 530204076Spjd break; 531204076Spjd 532204076Spjd case 'R': /* page reclaims */ 533204076Spjd#ifdef _OSD_POSIX 534204076Spjd xprintf("0",0); 535204076Spjd#else 536204076Spjd xprintf("%ld", r1->ru_minflt - r0->ru_minflt); 537204076Spjd#endif 538204076Spjd break; 539204076Spjd 540205738Spjd case 'I': /* FS blocks in */ 541204076Spjd#ifdef _OSD_POSIX 542204076Spjd xprintf("0",0); 543204076Spjd#else 544204076Spjd xprintf("%ld", r1->ru_inblock - r0->ru_inblock); 545204076Spjd#endif 546204076Spjd break; 547204076Spjd 548205738Spjd case 'O': /* FS blocks out */ 549204076Spjd#ifdef _OSD_POSIX 550204076Spjd xprintf("0",0); 551204076Spjd#else 552204076Spjd xprintf("%ld", r1->ru_oublock - r0->ru_oublock); 553204076Spjd#endif 554204076Spjd break; 555204076Spjd 556204076Spjd# ifdef convex 557204076Spjd case 'C': /* CPU parallelization factor */ 558204076Spjd if (r1->ru_usamples != 0LL) { 559204076Spjd long long parr = ((r1->ru_utotal * 100LL) / 560204076Spjd r1->ru_usamples); 561204076Spjd xprintf("%d.%02d", (int)(parr/100), (int)(parr%100)); 562204076Spjd } else 563204076Spjd xprintf("?"); 564204076Spjd break; 565204076Spjd# endif /* convex */ 566204076Spjd case 'r': /* PWP: socket messages recieved */ 567204076Spjd#ifdef _OSD_POSIX 568204076Spjd xprintf("0",0); 569204076Spjd#else 570204076Spjd xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv); 571204076Spjd#endif 572204076Spjd break; 573204076Spjd 574204076Spjd case 's': /* PWP: socket messages sent */ 575204076Spjd#ifdef _OSD_POSIX 576204076Spjd xprintf("0",0); 577204076Spjd#else 578204076Spjd xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd); 579204076Spjd#endif 580205738Spjd break; 581215331Spjd 582215331Spjd case 'k': /* PWP: signals received */ 583204076Spjd#ifdef _OSD_POSIX 584204076Spjd xprintf("0",0); 585204076Spjd#else 586205738Spjd xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals); 587204076Spjd#endif 588204076Spjd break; 589204076Spjd 590204076Spjd case 'w': /* PWP: voluntary context switches (waits) */ 591207371Spjd#ifdef _OSD_POSIX 592207371Spjd xprintf("0",0); 593207371Spjd#else 594204076Spjd xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw); 595204076Spjd#endif 596204076Spjd break; 597204076Spjd 598214284Spjd case 'c': /* PWP: involuntary context switches */ 599214284Spjd#ifdef _OSD_POSIX 600214284Spjd xprintf("0",0); 601214284Spjd#else 602214284Spjd xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw); 603214284Spjd#endif 604214284Spjd break; 605214284Spjd#else /* BSDTIMES */ 606214284Spjd# ifdef _SEQUENT_ 607214284Spjd case 'W': /* number of swaps */ 608214284Spjd i = r1->ps_swap - r0->ps_swap; 609214284Spjd xprintf("%ld", i); 610214284Spjd break; 611204076Spjd 612204076Spjd case 'M': 613204076Spjd xprintf("%ld", r1->ps_maxrss / 2); 614204076Spjd break; 615204076Spjd 616204076Spjd case 'F': 617204076Spjd xprintf("%ld", r1->ps_pagein - r0->ps_pagein); 618204076Spjd break; 619204076Spjd 620204076Spjd case 'R': 621205738Spjd xprintf("%ld", r1->ps_reclaim - r0->ps_reclaim); 622204076Spjd break; 623204076Spjd 624204076Spjd case 'I': 625204076Spjd xprintf("%ld", r1->ps_bread - r0->ps_bread); 626204076Spjd break; 627204076Spjd 628204076Spjd case 'O': 629205738Spjd xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite); 630204076Spjd break; 631204076Spjd 632204076Spjd case 'k': 633204076Spjd xprintf("%ld", r1->ps_signal - r0->ps_signal); 634204076Spjd break; 635204076Spjd 636204076Spjd case 'w': 637204076Spjd xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw); 638204076Spjd break; 639204076Spjd 640204076Spjd case 'c': 641204076Spjd xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw); 642204076Spjd break; 643204076Spjd 644204076Spjd case 'Z': 645204076Spjd xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill); 646204076Spjd break; 647204076Spjd 648204076Spjd case 'i': 649204076Spjd xprintf("%ld", r1->ps_pffincr - r0->ps_pffincr); 650204076Spjd break; 651204076Spjd 652204076Spjd case 'd': 653204076Spjd xprintf("%ld", r1->ps_pffdecr - r0->ps_pffdecr); 654204076Spjd break; 655204076Spjd 656204076Spjd case 'Y': 657204076Spjd xprintf("%ld", r1->ps_syscall - r0->ps_syscall); 658204076Spjd break; 659204076Spjd 660204076Spjd case 'l': 661204076Spjd xprintf("%ld", r1->ps_lread - r0->ps_lread); 662204076Spjd break; 663204076Spjd 664204076Spjd case 'm': 665204076Spjd xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite); 666204076Spjd break; 667204076Spjd 668204076Spjd case 'p': 669204076Spjd xprintf("%ld", r1->ps_phread - r0->ps_phread); 670204076Spjd break; 671204076Spjd 672205738Spjd case 'q': 673204076Spjd xprintf("%ld", r1->ps_phwrite - r0->ps_phwrite); 674204076Spjd break; 675204076Spjd# endif /* _SEQUENT_ */ 676204076Spjd#endif /* BSDTIMES */ 677204076Spjd default: 678204076Spjd break; 679204076Spjd } 680204076Spjd xputchar('\n'); 681204076Spjd} 682204076Spjd 683204076Spjd#if defined(BSDTIMES) || defined(_SEQUENT_) 684204076Spjdstatic void 685204076Spjdpdeltat(timeval_t *t1, timeval_t *t0) 686204076Spjd{ 687204076Spjd timeval_t td; 688204076Spjd 689204076Spjd tvsub(&td, t1, t0); 690204076Spjd xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L); 691214274Spjd} 692204076Spjd 693205738Spjdstatic void 694205738Spjdtvadd(timeval_t *tsum, timeval_t *t0) 695205738Spjd{ 696205738Spjd 697205738Spjd tsum->tv_sec += t0->tv_sec; 698205738Spjd tsum->tv_usec += t0->tv_usec; 699205738Spjd if (tsum->tv_usec >= 1000000) 700212038Spjd tsum->tv_sec++, tsum->tv_usec -= 1000000; 701205738Spjd} 702205738Spjd 703211983Spjdvoid 704212038Spjdtvsub(timeval_t *tdiff, timeval_t *t1, timeval_t *t0) 705205738Spjd{ 706205738Spjd 707205738Spjd tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 708205738Spjd tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 709205738Spjd if (tdiff->tv_usec < 0) 710205738Spjd tdiff->tv_sec--, tdiff->tv_usec += 1000000; 711205738Spjd} 712205738Spjd 713205738Spjd#else /* !BSDTIMES && !_SEQUENT_ */ 714205738Spjdstatic void 715204076Spjd#ifndef POSIX 716204076Spjdpdtimet(time_t eval, time_t bval) 717204076Spjd 718204076Spjd#else /* POSIX */ 719204076Spjdpdtimet(clock_t eval, clock_t bval) 720204076Spjd 721204076Spjd#endif /* POSIX */ 722211878Spjd{ 723211878Spjd#ifndef POSIX 724211878Spjd time_t val; 725211878Spjd 726211878Spjd#else /* POSIX */ 727211878Spjd clock_t val; 728211878Spjd 729211878Spjd#endif /* POSIX */ 730211878Spjd 731211878Spjd#ifndef POSIX 732204076Spjd val = (eval - bval) * 100 / HZ; 733204076Spjd#else /* POSIX */ 734204076Spjd val = (eval - bval) * 100 / clk_tck; 735204076Spjd#endif /* POSIX */ 736204076Spjd 737204076Spjd xprintf("%ld.%02ld", val / 100, val - (val / 100 * 100)); 738204076Spjd} 739204076Spjd#endif /* BSDTIMES || _SEQUENT_ */ 740204076Spjd