1231990Smp/* $Header: /p/tcsh/cvsroot/tcsh/sh.time.c,v 3.35 2010/12/09 15:39:29 christos Exp $ */ 259243Sobrien/* 359243Sobrien * sh.time.c: Shell time keeping and printing. 459243Sobrien */ 559243Sobrien/*- 659243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California. 759243Sobrien * All rights reserved. 859243Sobrien * 959243Sobrien * Redistribution and use in source and binary forms, with or without 1059243Sobrien * modification, are permitted provided that the following conditions 1159243Sobrien * are met: 1259243Sobrien * 1. Redistributions of source code must retain the above copyright 1359243Sobrien * notice, this list of conditions and the following disclaimer. 1459243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1559243Sobrien * notice, this list of conditions and the following disclaimer in the 1659243Sobrien * documentation and/or other materials provided with the distribution. 17100616Smp * 3. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien#include "sh.h" 3459243Sobrien 35231990SmpRCSID("$tcsh: sh.time.c,v 3.35 2010/12/09 15:39:29 christos Exp $") 3659243Sobrien 3759243Sobrien#ifdef SUNOS4 3859243Sobrien# include <machine/param.h> 3959243Sobrien#endif /* SUNOS4 */ 4059243Sobrien 4159243Sobrien/* 4259243Sobrien * C Shell - routines handling process timing and niceing 4359243Sobrien */ 4459243Sobrien#ifdef BSDTIMES 4559243Sobrien# ifndef RUSAGE_SELF 4659243Sobrien# define RUSAGE_SELF 0 4759243Sobrien# define RUSAGE_CHILDREN -1 4859243Sobrien# endif /* RUSAGE_SELF */ 4959243Sobrien#else /* BSDTIMES */ 5059243Sobrienstruct tms times0; 5159243Sobrien#endif /* BSDTIMES */ 5259243Sobrien 5359243Sobrien#if !defined(BSDTIMES) && !defined(_SEQUENT_) 5459243Sobrien# ifdef POSIX 55167465Smpstatic void pdtimet (clock_t, clock_t); 5659243Sobrien# else /* ! POSIX */ 57167465Smpstatic void pdtimet (time_t, time_t); 5859243Sobrien# endif /* ! POSIX */ 5959243Sobrien#else /* BSDTIMES || _SEQUENT_ */ 60167465Smpstatic void tvadd (timeval_t *, timeval_t *); 61167465Smpstatic void pdeltat (timeval_t *, timeval_t *); 6259243Sobrien#endif /* BSDTIMES || _SEQUENT_ */ 6359243Sobrien 6459243Sobrienvoid 65167465Smpsettimes(void) 6659243Sobrien{ 6759243Sobrien#ifdef BSDTIMES 6859243Sobrien struct sysrusage ruch; 6959243Sobrien#ifdef convex 7059243Sobrien memset(&ru0, 0, sizeof(ru0)); 7159243Sobrien memset(&ruch, 0, sizeof(ruch)); 7259243Sobrien#endif /* convex */ 7359243Sobrien 7459243Sobrien (void) gettimeofday(&time0, NULL); 7559243Sobrien (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0); 7659243Sobrien (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 7759243Sobrien ruadd(&ru0, &ruch); 7859243Sobrien#else 7959243Sobrien# ifdef _SEQUENT_ 8059243Sobrien struct process_stats ruch; 8159243Sobrien 8259243Sobrien (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch); 8359243Sobrien ruadd(&ru0, &ruch); 8459243Sobrien# else /* _SEQUENT_ */ 8559415Sobrien seconds0 = time(NULL); 8659243Sobrien time0 = times(×0); 8759243Sobrien times0.tms_stime += times0.tms_cstime; 8859243Sobrien times0.tms_utime += times0.tms_cutime; 8959243Sobrien times0.tms_cstime = 0; 9059243Sobrien times0.tms_cutime = 0; 9159243Sobrien# endif /* _SEQUENT_ */ 9259243Sobrien#endif /* BSDTIMES */ 9359243Sobrien} 9459243Sobrien 9559243Sobrien/* 9659243Sobrien * dotime is only called if it is truly a builtin function and not a 9759243Sobrien * prefix to another command 9859243Sobrien */ 9959243Sobrien/*ARGSUSED*/ 10059243Sobrienvoid 101167465Smpdotime(Char **v, struct command *c) 10259243Sobrien{ 10359243Sobrien#ifdef BSDTIMES 10459243Sobrien timeval_t timedol; 10559243Sobrien struct sysrusage ru1, ruch; 10659243Sobrien#ifdef convex 10759243Sobrien memset(&ru1, 0, sizeof(ru1)); 10859243Sobrien memset(&ruch, 0, sizeof(ruch)); 10959243Sobrien#endif /* convex */ 11059243Sobrien 11159243Sobrien (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1); 11259243Sobrien (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 11359243Sobrien ruadd(&ru1, &ruch); 11459243Sobrien (void) gettimeofday(&timedol, NULL); 11559243Sobrien prusage(&ru0, &ru1, &timedol, &time0); 11659243Sobrien#else 11759243Sobrien# ifdef _SEQUENT_ 11859243Sobrien timeval_t timedol; 11959243Sobrien struct process_stats ru1, ruch; 12059243Sobrien 12159243Sobrien (void) get_process_stats(&timedol, PS_SELF, &ru1, &ruch); 12259243Sobrien ruadd(&ru1, &ruch); 12359243Sobrien prusage(&ru0, &ru1, &timedol, &time0); 12459243Sobrien# else /* _SEQUENT_ */ 12559243Sobrien# ifndef POSIX 12659243Sobrien time_t timedol; 12759243Sobrien# else /* POSIX */ 12859243Sobrien clock_t timedol; 12959243Sobrien# endif /* POSIX */ 13059243Sobrien 13159243Sobrien struct tms times_dol; 13259243Sobrien 13359243Sobrien timedol = times(×_dol); 13459243Sobrien times_dol.tms_stime += times_dol.tms_cstime; 13559243Sobrien times_dol.tms_utime += times_dol.tms_cutime; 13659243Sobrien times_dol.tms_cstime = 0; 13759243Sobrien times_dol.tms_cutime = 0; 13859243Sobrien prusage(×0, ×_dol, timedol, time0); 13959243Sobrien# endif /* _SEQUENT_ */ 14059243Sobrien#endif /* BSDTIMES */ 14159243Sobrien USE(c); 14259243Sobrien USE(v); 14359243Sobrien} 14459243Sobrien 14559243Sobrien/* 14659243Sobrien * donice is only called when it on the line by itself or with a +- value 14759243Sobrien */ 14859243Sobrien/*ARGSUSED*/ 14959243Sobrienvoid 150167465Smpdonice(Char **v, struct command *c) 15159243Sobrien{ 152145479Smp Char *cp; 15359243Sobrien int nval = 0; 15459243Sobrien 15559243Sobrien USE(c); 15659243Sobrien v++, cp = *v++; 15759243Sobrien if (cp == 0) 15859243Sobrien nval = 4; 15959243Sobrien else if (*v == 0 && any("+-", cp[0])) 16059243Sobrien nval = getn(cp); 161145479Smp#ifdef HAVE_SETPRIORITY 16283098Smp if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno) 16383098Smp stderror(ERR_SYSTEM, "setpriority", strerror(errno)); 164145479Smp#else /* !HAVE_SETPRIORITY */ 16559243Sobrien (void) nice(nval); 166145479Smp#endif /* HAVE_SETPRIORITY */ 16759243Sobrien} 16859243Sobrien 16959243Sobrien#ifdef BSDTIMES 17059243Sobrienvoid 171167465Smpruadd(struct sysrusage *ru, struct sysrusage *ru2) 17259243Sobrien{ 17359243Sobrien tvadd(&ru->ru_utime, &ru2->ru_utime); 17459243Sobrien tvadd(&ru->ru_stime, &ru2->ru_stime); 175145479Smp#ifndef _OSD_POSIX 17659243Sobrien if (ru2->ru_maxrss > ru->ru_maxrss) 17759243Sobrien ru->ru_maxrss = ru2->ru_maxrss; 17859243Sobrien 17959243Sobrien ru->ru_ixrss += ru2->ru_ixrss; 18059243Sobrien ru->ru_idrss += ru2->ru_idrss; 18159243Sobrien ru->ru_isrss += ru2->ru_isrss; 18259243Sobrien ru->ru_minflt += ru2->ru_minflt; 18359243Sobrien ru->ru_majflt += ru2->ru_majflt; 18459243Sobrien ru->ru_nswap += ru2->ru_nswap; 18559243Sobrien ru->ru_inblock += ru2->ru_inblock; 18659243Sobrien ru->ru_oublock += ru2->ru_oublock; 18759243Sobrien ru->ru_msgsnd += ru2->ru_msgsnd; 18859243Sobrien ru->ru_msgrcv += ru2->ru_msgrcv; 18959243Sobrien ru->ru_nsignals += ru2->ru_nsignals; 19059243Sobrien ru->ru_nvcsw += ru2->ru_nvcsw; 19159243Sobrien ru->ru_nivcsw += ru2->ru_nivcsw; 192145479Smp#endif /*bs2000*/ 19359243Sobrien 19459243Sobrien# ifdef convex 19559243Sobrien tvadd(&ru->ru_exutime, &ru2->ru_exutime); 19659243Sobrien ru->ru_utotal += ru2->ru_utotal; 19759243Sobrien ru->ru_usamples += ru2->ru_usamples; 19859243Sobrien ru->ru_stotal += ru2->ru_stotal; 19959243Sobrien ru->ru_ssamples += ru2->ru_ssamples; 20059243Sobrien# endif /* convex */ 20159243Sobrien} 20259243Sobrien 20359243Sobrien#else /* BSDTIMES */ 20459243Sobrien# ifdef _SEQUENT_ 20559243Sobrienvoid 206167465Smpruadd(struct process_stats *ru, struct process_stats *ru2) 20759243Sobrien{ 20859243Sobrien tvadd(&ru->ps_utime, &ru2->ps_utime); 20959243Sobrien tvadd(&ru->ps_stime, &ru2->ps_stime); 21059243Sobrien if (ru2->ps_maxrss > ru->ps_maxrss) 21159243Sobrien ru->ps_maxrss = ru2->ps_maxrss; 21259243Sobrien 21359243Sobrien ru->ps_pagein += ru2->ps_pagein; 21459243Sobrien ru->ps_reclaim += ru2->ps_reclaim; 21559243Sobrien ru->ps_zerofill += ru2->ps_zerofill; 21659243Sobrien ru->ps_pffincr += ru2->ps_pffincr; 21759243Sobrien ru->ps_pffdecr += ru2->ps_pffdecr; 21859243Sobrien ru->ps_swap += ru2->ps_swap; 21959243Sobrien ru->ps_syscall += ru2->ps_syscall; 22059243Sobrien ru->ps_volcsw += ru2->ps_volcsw; 22159243Sobrien ru->ps_involcsw += ru2->ps_involcsw; 22259243Sobrien ru->ps_signal += ru2->ps_signal; 22359243Sobrien ru->ps_lread += ru2->ps_lread; 22459243Sobrien ru->ps_lwrite += ru2->ps_lwrite; 22559243Sobrien ru->ps_bread += ru2->ps_bread; 22659243Sobrien ru->ps_bwrite += ru2->ps_bwrite; 22759243Sobrien ru->ps_phread += ru2->ps_phread; 22859243Sobrien ru->ps_phwrite += ru2->ps_phwrite; 22959243Sobrien} 23059243Sobrien 23159243Sobrien# endif /* _SEQUENT_ */ 23259243Sobrien#endif /* BSDTIMES */ 23359243Sobrien 23459243Sobrien#ifdef BSDTIMES 23559243Sobrien 23659243Sobrien/* 23759243Sobrien * PWP: the LOG1024 and pagetok stuff taken from the top command, 23859243Sobrien * written by William LeFebvre 23959243Sobrien */ 24059243Sobrien/* Log base 2 of 1024 is 10 (2^10 == 1024) */ 24159243Sobrien#define LOG1024 10 24259243Sobrien 24359243Sobrien/* Convert clicks (kernel pages) to kbytes ... */ 24459243Sobrien/* If there is no PGSHIFT defined, assume it is 11 */ 24559243Sobrien/* Is this needed for compatability with some old flavor of 4.2 or 4.1? */ 24659243Sobrien#ifdef SUNOS4 24759243Sobrien# ifndef PGSHIFT 24859243Sobrien# define pagetok(size) ((size) << 1) 24959243Sobrien# else 25059243Sobrien# if PGSHIFT>10 25159243Sobrien# define pagetok(size) ((size) << (PGSHIFT - LOG1024)) 25259243Sobrien# else 25359243Sobrien# define pagetok(size) ((size) >> (LOG1024 - PGSHIFT)) 25459243Sobrien# endif 25559243Sobrien# endif 25659243Sobrien#endif 25759243Sobrien 25859243Sobrien/* 25959243Sobrien * if any other machines return wierd values in the ru_i* stuff, put 26059243Sobrien * the adjusting macro here: 26159243Sobrien */ 26259243Sobrien#ifdef SUNOS4 26359243Sobrien# define IADJUST(i) (pagetok(i)/2) 26459243Sobrien#else /* SUNOS4 */ 26559243Sobrien# ifdef convex 26659243Sobrien /* 26759243Sobrien * convex has megabytes * CLK_TCK 26859243Sobrien * multiply by 100 since we use time in 100ths of a second in prusage 26959243Sobrien */ 27059243Sobrien# define IADJUST(i) (((i) << 10) / CLK_TCK * 100) 27159243Sobrien# else /* convex */ 27259243Sobrien# define IADJUST(i) (i) 27359243Sobrien# endif /* convex */ 27459243Sobrien#endif /* SUNOS4 */ 27559243Sobrien 27659243Sobrienvoid 277167465Smpprusage(struct sysrusage *r0, struct sysrusage *r1, timeval_t *e, timeval_t *b) 27859243Sobrien 27959243Sobrien#else /* BSDTIMES */ 28059243Sobrien# ifdef _SEQUENT_ 28159243Sobrienvoid 282167465Smpprusage(struct process_stats *r0, struct process_stats *r1, timeval_t e, 283167465Smp timeval_t b) 28459243Sobrien 28559243Sobrien# else /* _SEQUENT_ */ 286167465Smp# ifndef POSIX 28759243Sobrienvoid 288167465Smpprusage(struct tms *bs, struct tms *es, time_t e, time_t b) 28959243Sobrien# else /* POSIX */ 290167465Smpvoid 291167465Smpprusage(struct tms *bs, struct tms *es, clock_t e, clock_t b) 29259243Sobrien# endif /* POSIX */ 29359243Sobrien# endif /* _SEQUENT_ */ 29459243Sobrien#endif /* BSDTIMES */ 29559243Sobrien{ 29659243Sobrien#ifdef BSDTIMES 297145479Smp time_t t = 29859243Sobrien (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + 29959243Sobrien (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + 30059243Sobrien (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + 30159243Sobrien (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; 30259243Sobrien 30359243Sobrien#else 30459243Sobrien# ifdef _SEQUENT_ 305145479Smp time_t t = 30659243Sobrien (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec) * 100 + 30759243Sobrien (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 + 30859243Sobrien (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec) * 100 + 30959243Sobrien (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000; 31059243Sobrien 31159243Sobrien# else /* _SEQUENT_ */ 31259243Sobrien# ifndef POSIX 313145479Smp time_t t = (es->tms_utime - bs->tms_utime + 31459243Sobrien es->tms_stime - bs->tms_stime) * 100 / HZ; 31559243Sobrien 31659243Sobrien# else /* POSIX */ 317145479Smp clock_t t = (es->tms_utime - bs->tms_utime + 31859243Sobrien es->tms_stime - bs->tms_stime) * 100 / clk_tck; 31959243Sobrien 32059243Sobrien# endif /* POSIX */ 32159243Sobrien# endif /* _SEQUENT_ */ 32259243Sobrien#endif /* BSDTIMES */ 32359243Sobrien 324145479Smp const char *cp; 325145479Smp long i; 326145479Smp struct varent *vp = adrof(STRtime); 32759243Sobrien 32859243Sobrien#ifdef BSDTIMES 32959243Sobrien# ifdef convex 33059243Sobrien static struct system_information sysinfo; 33159243Sobrien long long memtmp; /* let memory calculations exceede 2Gb */ 33259243Sobrien# endif /* convex */ 33359243Sobrien int ms = (int) 33459243Sobrien ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 33559243Sobrien 33659243Sobrien cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 33759243Sobrien#else /* !BSDTIMES */ 33859243Sobrien# ifdef _SEQUENT_ 33959243Sobrien int ms = (int) 34059243Sobrien ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 34159243Sobrien 34259243Sobrien cp = "%Uu %Ss %E %P %I+%Oio %Fpf+%Ww"; 34359243Sobrien# else /* !_SEQUENT_ */ 34459243Sobrien# ifndef POSIX 34559243Sobrien time_t ms = ((time_t)((e - b) / HZ) * 100) + 34659243Sobrien (time_t)(((e - b) % HZ) * 100) / HZ; 34759243Sobrien# else /* POSIX */ 34859243Sobrien clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) + 34959243Sobrien (clock_t)(((e - b) % clk_tck) * 100) / clk_tck; 35059243Sobrien# endif /* POSIX */ 35159243Sobrien 35259243Sobrien cp = "%Uu %Ss %E %P"; 35359243Sobrien 35459243Sobrien /* 35559243Sobrien * the tms stuff is not very precise, so we fudge it. 35659243Sobrien * granularity fix: can't be more than 100% 35759243Sobrien * this breaks in multi-processor systems... 35859243Sobrien * maybe I should take it out and let people see more then 100% 35959243Sobrien * utilizations. 36059243Sobrien */ 36159243Sobrien# if 0 36259243Sobrien if (ms < t && ms != 0) 36359243Sobrien ms = t; 36459243Sobrien# endif 36559243Sobrien# endif /*! _SEQUENT_ */ 36659243Sobrien#endif /* !BSDTIMES */ 36759243Sobrien#ifdef TDEBUG 36859243Sobrien xprintf("es->tms_utime %lu bs->tms_utime %lu\n", 369231990Smp (unsigned long)es->tms_utime, (unsigned long)bs->tms_utime); 37059243Sobrien xprintf("es->tms_stime %lu bs->tms_stime %lu\n", 371231990Smp (unsigned long)es->tms_stime, (unsigned long)bs->tms_stime); 372231990Smp xprintf("ms %llu e %p b %p\n", (unsigned long long)ms, e, b); 373231990Smp xprintf("t %llu\n", (unsigned long long)t); 37459243Sobrien#endif /* TDEBUG */ 37559243Sobrien 376100616Smp if (vp && vp->vec && vp->vec[0] && vp->vec[1]) 37759243Sobrien cp = short2str(vp->vec[1]); 37859243Sobrien for (; *cp; cp++) 37959243Sobrien if (*cp != '%') 38059243Sobrien xputchar(*cp); 38159243Sobrien else if (cp[1]) 38259243Sobrien switch (*++cp) { 38359243Sobrien 38459243Sobrien case 'U': /* user CPU time used */ 38559243Sobrien#ifdef BSDTIMES 38659243Sobrien pdeltat(&r1->ru_utime, &r0->ru_utime); 38759243Sobrien#else 38859243Sobrien# ifdef _SEQUENT_ 38959243Sobrien pdeltat(&r1->ps_utime, &r0->ps_utime); 39059243Sobrien# else /* _SEQUENT_ */ 39159243Sobrien# ifndef POSIX 39259243Sobrien pdtimet(es->tms_utime, bs->tms_utime); 39359243Sobrien# else /* POSIX */ 39459243Sobrien pdtimet(es->tms_utime, bs->tms_utime); 39559243Sobrien# endif /* POSIX */ 39659243Sobrien# endif /* _SEQUENT_ */ 39759243Sobrien#endif /* BSDTIMES */ 39859243Sobrien break; 39959243Sobrien 40059243Sobrien case 'S': /* system CPU time used */ 40159243Sobrien#ifdef BSDTIMES 40259243Sobrien pdeltat(&r1->ru_stime, &r0->ru_stime); 40359243Sobrien#else 40459243Sobrien# ifdef _SEQUENT_ 40559243Sobrien pdeltat(&r1->ps_stime, &r0->ps_stime); 40659243Sobrien# else /* _SEQUENT_ */ 40759243Sobrien# ifndef POSIX 40859243Sobrien pdtimet(es->tms_stime, bs->tms_stime); 40959243Sobrien# else /* POSIX */ 41059243Sobrien pdtimet(es->tms_stime, bs->tms_stime); 41159243Sobrien# endif /* POSIX */ 41259243Sobrien# endif /* _SEQUENT_ */ 41359243Sobrien#endif /* BSDTIMES */ 41459243Sobrien break; 41559243Sobrien 41659243Sobrien case 'E': /* elapsed (wall-clock) time */ 41759243Sobrien#ifdef BSDTIMES 41859243Sobrien pcsecs((long) ms); 41959243Sobrien#else /* BSDTIMES */ 42059243Sobrien pcsecs(ms); 42159243Sobrien#endif /* BSDTIMES */ 42259243Sobrien break; 42359243Sobrien 42459243Sobrien case 'P': /* percent time spent running */ 42559243Sobrien /* check if the process did not run */ 42659243Sobrien#ifdef convex 42759243Sobrien /* 42859243Sobrien * scale the cpu %- ages by the number of processors 42959243Sobrien * available on this machine 43059243Sobrien */ 43159243Sobrien if ((sysinfo.cpu_count == 0) && 43259243Sobrien (getsysinfo(SYSINFO_SIZE, &sysinfo) < 0)) 43359243Sobrien sysinfo.cpu_count = 1; 43459415Sobrien i = (ms == 0) ? 0 : (t * 1000.0 / (ms * sysinfo.cpu_count)); 43559243Sobrien#else /* convex */ 43661521Sobrien i = (ms == 0) ? 0 : (long)(t * 1000.0 / ms); 43759243Sobrien#endif /* convex */ 43859243Sobrien xprintf("%ld.%01ld%%", i / 10, i % 10); /* nn.n% */ 43959243Sobrien break; 44059243Sobrien 44159243Sobrien#ifdef BSDTIMES 44259243Sobrien case 'W': /* number of swaps */ 443145479Smp#ifdef _OSD_POSIX 444145479Smp i = 0; 445145479Smp#else 44659243Sobrien i = r1->ru_nswap - r0->ru_nswap; 447145479Smp#endif 44859243Sobrien xprintf("%ld", i); 44959243Sobrien break; 45059243Sobrien 45159243Sobrien#ifdef convex 45259243Sobrien case 'X': /* (average) shared text size */ 45359243Sobrien memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss - 45459243Sobrien (long long)r0->ru_ixrss) / 45559243Sobrien (long long)t); 45659243Sobrien xprintf("%lu", (unsigned long)memtmp); 45759243Sobrien break; 45859243Sobrien 45959243Sobrien case 'D': /* (average) unshared data size */ 46059243Sobrien memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss + 46159243Sobrien (long long)r1->ru_isrss - 46259243Sobrien ((long long)r0->ru_idrss + 46359243Sobrien (long long)r0->ru_isrss)) / 46459243Sobrien (long long)t); 46559243Sobrien xprintf("%lu", (unsigned long)memtmp); 46659243Sobrien break; 46759243Sobrien 46859243Sobrien case 'K': /* (average) total data memory used */ 46959243Sobrien memtmp = (t == 0 ? 0LL : IADJUST(((long long)r1->ru_ixrss + 47059243Sobrien (long long)r1->ru_isrss + 47159243Sobrien (long long)r1->ru_idrss) - 47259243Sobrien ((long long)r0->ru_ixrss + 47359243Sobrien (long long)r0->ru_idrss + 47459243Sobrien (long long)r0->ru_isrss)) / 47559243Sobrien (long long)t); 47659243Sobrien xprintf("%lu", (unsigned long)memtmp); 47759243Sobrien break; 47859243Sobrien#else /* !convex */ 47959243Sobrien case 'X': /* (average) shared text size */ 480145479Smp#ifdef _OSD_POSIX 481145479Smp xprintf("0",0); 482145479Smp#else 483231990Smp xprintf("%lld", (long long)(t == 0 ? 0L : 484231990Smp IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t)); 485145479Smp#endif 48659243Sobrien break; 48759243Sobrien 48859243Sobrien case 'D': /* (average) unshared data size */ 489145479Smp#ifdef _OSD_POSIX 490145479Smp xprintf("0",0); 491145479Smp#else 492231990Smp xprintf("%lld", (long long)(t == 0 ? 0L : 49359243Sobrien IADJUST(r1->ru_idrss + r1->ru_isrss - 494231990Smp (r0->ru_idrss + r0->ru_isrss)) / t)); 495145479Smp#endif 49659243Sobrien break; 49759243Sobrien 49859243Sobrien case 'K': /* (average) total data memory used */ 499145479Smp#ifdef _OSD_POSIX 500145479Smp xprintf("0",0); 501145479Smp#else 502231990Smp xprintf("%lld", (long long)(t == 0 ? 0L : 50359243Sobrien IADJUST((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - 504231990Smp (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t)); 505145479Smp#endif 50659243Sobrien break; 50759243Sobrien#endif /* convex */ 50859243Sobrien case 'M': /* max. Resident Set Size */ 50959243Sobrien#ifdef SUNOS4 510231990Smp xprintf("%ld", (long)pagetok(r1->ru_maxrss)); 51159243Sobrien#else 51259243Sobrien# ifdef convex 513231990Smp xprintf("%ld", (long)(r1->ru_maxrss * 4L)); 51459243Sobrien# else /* !convex */ 515145479Smp# ifdef _OSD_POSIX 516145479Smp xprintf("0",0); 517145479Smp# else 518231990Smp xprintf("%ld", (long)r1->ru_maxrss); 519145479Smp# endif 52059243Sobrien# endif /* convex */ 52159243Sobrien#endif /* SUNOS4 */ 52259243Sobrien break; 52359243Sobrien 52459243Sobrien case 'F': /* page faults */ 525145479Smp#ifdef _OSD_POSIX 526145479Smp xprintf("0",0); 527145479Smp#else 528231990Smp xprintf("%ld", (long)(r1->ru_majflt - r0->ru_majflt)); 529145479Smp#endif 53059243Sobrien break; 53159243Sobrien 53259243Sobrien case 'R': /* page reclaims */ 533145479Smp#ifdef _OSD_POSIX 534145479Smp xprintf("0",0); 535145479Smp#else 536231990Smp xprintf("%ld", (long)(r1->ru_minflt - r0->ru_minflt)); 537145479Smp#endif 53859243Sobrien break; 53959243Sobrien 54059243Sobrien case 'I': /* FS blocks in */ 541145479Smp#ifdef _OSD_POSIX 542145479Smp xprintf("0",0); 543145479Smp#else 544231990Smp xprintf("%ld", (long)(r1->ru_inblock - r0->ru_inblock)); 545145479Smp#endif 54659243Sobrien break; 54759243Sobrien 54859243Sobrien case 'O': /* FS blocks out */ 549145479Smp#ifdef _OSD_POSIX 550145479Smp xprintf("0",0); 551145479Smp#else 552231990Smp xprintf("%ld", (long)(r1->ru_oublock - r0->ru_oublock)); 553145479Smp#endif 55459243Sobrien break; 55559243Sobrien 55659243Sobrien# ifdef convex 55759243Sobrien case 'C': /* CPU parallelization factor */ 55859243Sobrien if (r1->ru_usamples != 0LL) { 55959243Sobrien long long parr = ((r1->ru_utotal * 100LL) / 56059243Sobrien r1->ru_usamples); 56159243Sobrien xprintf("%d.%02d", (int)(parr/100), (int)(parr%100)); 56259243Sobrien } else 56359243Sobrien xprintf("?"); 56459243Sobrien break; 56559243Sobrien# endif /* convex */ 56659243Sobrien case 'r': /* PWP: socket messages recieved */ 567145479Smp#ifdef _OSD_POSIX 568145479Smp xprintf("0",0); 569145479Smp#else 570231990Smp xprintf("%ld", (long)(r1->ru_msgrcv - r0->ru_msgrcv)); 571145479Smp#endif 57259243Sobrien break; 57359243Sobrien 57459243Sobrien case 's': /* PWP: socket messages sent */ 575145479Smp#ifdef _OSD_POSIX 576145479Smp xprintf("0",0); 577145479Smp#else 578231990Smp xprintf("%ld", (long)(r1->ru_msgsnd - r0->ru_msgsnd)); 579145479Smp#endif 58059243Sobrien break; 58159243Sobrien 58259243Sobrien case 'k': /* PWP: signals received */ 583145479Smp#ifdef _OSD_POSIX 584145479Smp xprintf("0",0); 585145479Smp#else 586231990Smp xprintf("%ld", (long)(r1->ru_nsignals - r0->ru_nsignals)); 587145479Smp#endif 58859243Sobrien break; 58959243Sobrien 59059243Sobrien case 'w': /* PWP: voluntary context switches (waits) */ 591145479Smp#ifdef _OSD_POSIX 592145479Smp xprintf("0",0); 593145479Smp#else 594231990Smp xprintf("%ld", (long)(r1->ru_nvcsw - r0->ru_nvcsw)); 595145479Smp#endif 59659243Sobrien break; 59759243Sobrien 59859243Sobrien case 'c': /* PWP: involuntary context switches */ 599145479Smp#ifdef _OSD_POSIX 600145479Smp xprintf("0",0); 601145479Smp#else 602231990Smp xprintf("%ld", (long)(r1->ru_nivcsw - r0->ru_nivcsw)); 603145479Smp#endif 60459243Sobrien break; 60559243Sobrien#else /* BSDTIMES */ 60659243Sobrien# ifdef _SEQUENT_ 60759243Sobrien case 'W': /* number of swaps */ 60859243Sobrien i = r1->ps_swap - r0->ps_swap; 609231990Smp xprintf("%ld", (long)i); 61059243Sobrien break; 61159243Sobrien 61259243Sobrien case 'M': 613231990Smp xprintf("%ld", (long)r1->ps_maxrss); 61459243Sobrien break; 61559243Sobrien 61659243Sobrien case 'F': 617231990Smp xprintf("%ld", (long)(r1->ps_pagein - r0->ps_pagein)); 61859243Sobrien break; 61959243Sobrien 62059243Sobrien case 'R': 621231990Smp xprintf("%ld", (long)(r1->ps_reclaim - r0->ps_reclaim)); 62259243Sobrien break; 62359243Sobrien 62459243Sobrien case 'I': 625231990Smp xprintf("%ld", (long)(r1->ps_bread - r0->ps_bread)); 62659243Sobrien break; 62759243Sobrien 62859243Sobrien case 'O': 629231990Smp xprintf("%ld", (long)(r1->ps_bwrite - r0->ps_bwrite)); 63059243Sobrien break; 63159243Sobrien 63259243Sobrien case 'k': 633231990Smp xprintf("%ld", (long)(r1->ps_signal - r0->ps_signal)); 63459243Sobrien break; 63559243Sobrien 63659243Sobrien case 'w': 637231990Smp xprintf("%ld", (long)(r1->ps_volcsw - r0->ps_volcsw)); 63859243Sobrien break; 63959243Sobrien 64059243Sobrien case 'c': 64159243Sobrien xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw); 64259243Sobrien break; 64359243Sobrien 64459243Sobrien case 'Z': 645231990Smp xprintf("%ld", (long)(r1->ps_zerofill - r0->ps_zerofill)); 64659243Sobrien break; 64759243Sobrien 64859243Sobrien case 'i': 649231990Smp xprintf("%ld", (long)(r1->ps_pffincr - r0->ps_pffincr)); 65059243Sobrien break; 65159243Sobrien 65259243Sobrien case 'd': 653231990Smp xprintf("%ld", (long)(r1->ps_pffdecr - r0->ps_pffdecr)); 65459243Sobrien break; 65559243Sobrien 65659243Sobrien case 'Y': 657231990Smp xprintf("%ld", (long)(r1->ps_syscall - r0->ps_syscall)); 65859243Sobrien break; 65959243Sobrien 66059243Sobrien case 'l': 661231990Smp xprintf("%ld", (long)(r1->ps_lread - r0->ps_lread)); 66259243Sobrien break; 66359243Sobrien 66459243Sobrien case 'm': 665231990Smp xprintf("%ld", (long)(r1->ps_lwrite - r0->ps_lwrite)); 66659243Sobrien break; 66759243Sobrien 66859243Sobrien case 'p': 669231990Smp xprintf("%ld", (long)(r1->ps_phread - r0->ps_phread)); 67059243Sobrien break; 67159243Sobrien 67259243Sobrien case 'q': 673231990Smp xprintf("%ld", (long)(r1->ps_phwrite - r0->ps_phwrite)); 67459243Sobrien break; 67559243Sobrien# endif /* _SEQUENT_ */ 67659243Sobrien#endif /* BSDTIMES */ 67759243Sobrien default: 67859243Sobrien break; 67959243Sobrien } 68059243Sobrien xputchar('\n'); 68159243Sobrien} 68259243Sobrien 68359243Sobrien#if defined(BSDTIMES) || defined(_SEQUENT_) 68459243Sobrienstatic void 685167465Smppdeltat(timeval_t *t1, timeval_t *t0) 68659243Sobrien{ 68759243Sobrien timeval_t td; 68859243Sobrien 68959243Sobrien tvsub(&td, t1, t0); 690231990Smp xprintf("%lld.%03ld", (long long)td.tv_sec, (long)td.tv_usec / 1000L); 69159243Sobrien} 69259243Sobrien 69359243Sobrienstatic void 694167465Smptvadd(timeval_t *tsum, timeval_t *t0) 69559243Sobrien{ 69659243Sobrien 69759243Sobrien tsum->tv_sec += t0->tv_sec; 69859243Sobrien tsum->tv_usec += t0->tv_usec; 69959243Sobrien if (tsum->tv_usec >= 1000000) 70059243Sobrien tsum->tv_sec++, tsum->tv_usec -= 1000000; 70159243Sobrien} 70259243Sobrien 70359243Sobrienvoid 704167465Smptvsub(timeval_t *tdiff, timeval_t *t1, timeval_t *t0) 70559243Sobrien{ 70659243Sobrien 70759243Sobrien tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 70859243Sobrien tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 70959243Sobrien if (tdiff->tv_usec < 0) 71059243Sobrien tdiff->tv_sec--, tdiff->tv_usec += 1000000; 71159243Sobrien} 71259243Sobrien 71359243Sobrien#else /* !BSDTIMES && !_SEQUENT_ */ 71459243Sobrienstatic void 71559243Sobrien#ifndef POSIX 716167465Smppdtimet(time_t eval, time_t bval) 71759243Sobrien 71859243Sobrien#else /* POSIX */ 719167465Smppdtimet(clock_t eval, clock_t bval) 72059243Sobrien 72159243Sobrien#endif /* POSIX */ 72259243Sobrien{ 72359243Sobrien#ifndef POSIX 72459243Sobrien time_t val; 72559243Sobrien 72659243Sobrien#else /* POSIX */ 72759243Sobrien clock_t val; 72859243Sobrien 72959243Sobrien#endif /* POSIX */ 73059243Sobrien 73159243Sobrien#ifndef POSIX 73259243Sobrien val = (eval - bval) * 100 / HZ; 73359243Sobrien#else /* POSIX */ 73459243Sobrien val = (eval - bval) * 100 / clk_tck; 73559243Sobrien#endif /* POSIX */ 73659243Sobrien 737231990Smp xprintf("%lld.%02ld", (long long)(val / 100), 738231990Smp (long long)(val - (val / 100 * 100))); 73959243Sobrien} 74059243Sobrien#endif /* BSDTIMES || _SEQUENT_ */ 741