sh.time.c revision 100616
1100616Smp/* $Header: /src/pub/tcsh/sh.time.c,v 3.25 2002/06/25 19:02:11 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 35100616SmpRCSID("$Id: sh.time.c,v 3.25 2002/06/25 19:02:11 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 5559243Sobrienstatic void pdtimet __P((clock_t, clock_t)); 5659243Sobrien# else /* ! POSIX */ 5759243Sobrienstatic void pdtimet __P((time_t, time_t)); 5859243Sobrien# endif /* ! POSIX */ 5959243Sobrien#else /* BSDTIMES || _SEQUENT_ */ 6059243Sobrienstatic void tvadd __P((timeval_t *, timeval_t *)); 6159243Sobrienstatic void pdeltat __P((timeval_t *, timeval_t *)); 6259243Sobrien#endif /* BSDTIMES || _SEQUENT_ */ 6359243Sobrien 6459243Sobrienvoid 6559243Sobriensettimes() 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# ifndef COHERENT 8759243Sobrien time0 = times(×0); 8859243Sobrien# else /* !COHERENT */ 8959415Sobrien time0 = HZ * seconds0; 9059243Sobrien times(×0); 9159243Sobrien# endif /* !COHERENT */ 9259243Sobrien times0.tms_stime += times0.tms_cstime; 9359243Sobrien times0.tms_utime += times0.tms_cutime; 9459243Sobrien times0.tms_cstime = 0; 9559243Sobrien times0.tms_cutime = 0; 9659243Sobrien# endif /* _SEQUENT_ */ 9759243Sobrien#endif /* BSDTIMES */ 9859243Sobrien} 9959243Sobrien 10059243Sobrien/* 10159243Sobrien * dotime is only called if it is truly a builtin function and not a 10259243Sobrien * prefix to another command 10359243Sobrien */ 10459243Sobrien/*ARGSUSED*/ 10559243Sobrienvoid 10659243Sobriendotime(v, c) 10759243Sobrien Char **v; 10859243Sobrien struct command *c; 10959243Sobrien{ 11059243Sobrien#ifdef BSDTIMES 11159243Sobrien timeval_t timedol; 11259243Sobrien struct sysrusage ru1, ruch; 11359243Sobrien#ifdef convex 11459243Sobrien memset(&ru1, 0, sizeof(ru1)); 11559243Sobrien memset(&ruch, 0, sizeof(ruch)); 11659243Sobrien#endif /* convex */ 11759243Sobrien 11859243Sobrien (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1); 11959243Sobrien (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch); 12059243Sobrien ruadd(&ru1, &ruch); 12159243Sobrien (void) gettimeofday(&timedol, NULL); 12259243Sobrien prusage(&ru0, &ru1, &timedol, &time0); 12359243Sobrien#else 12459243Sobrien# ifdef _SEQUENT_ 12559243Sobrien timeval_t timedol; 12659243Sobrien struct process_stats ru1, ruch; 12759243Sobrien 12859243Sobrien (void) get_process_stats(&timedol, PS_SELF, &ru1, &ruch); 12959243Sobrien ruadd(&ru1, &ruch); 13059243Sobrien prusage(&ru0, &ru1, &timedol, &time0); 13159243Sobrien# else /* _SEQUENT_ */ 13259243Sobrien# ifndef POSIX 13359243Sobrien time_t timedol; 13459243Sobrien# else /* POSIX */ 13559243Sobrien clock_t timedol; 13659243Sobrien# endif /* POSIX */ 13759243Sobrien 13859243Sobrien struct tms times_dol; 13959243Sobrien 14059243Sobrien#ifndef COHERENT 14159243Sobrien timedol = times(×_dol); 14259243Sobrien#else 14359243Sobrien timedol = HZ * time(NULL); 14459243Sobrien times(×_dol); 14559243Sobrien#endif 14659243Sobrien times_dol.tms_stime += times_dol.tms_cstime; 14759243Sobrien times_dol.tms_utime += times_dol.tms_cutime; 14859243Sobrien times_dol.tms_cstime = 0; 14959243Sobrien times_dol.tms_cutime = 0; 15059243Sobrien prusage(×0, ×_dol, timedol, time0); 15159243Sobrien# endif /* _SEQUENT_ */ 15259243Sobrien#endif /* BSDTIMES */ 15359243Sobrien USE(c); 15459243Sobrien USE(v); 15559243Sobrien} 15659243Sobrien 15759243Sobrien/* 15859243Sobrien * donice is only called when it on the line by itself or with a +- value 15959243Sobrien */ 16059243Sobrien/*ARGSUSED*/ 16159243Sobrienvoid 16259243Sobriendonice(v, c) 16359243Sobrien register Char **v; 16459243Sobrien struct command *c; 16559243Sobrien{ 16659243Sobrien register Char *cp; 16759243Sobrien int nval = 0; 16859243Sobrien 16959243Sobrien USE(c); 17059243Sobrien v++, cp = *v++; 17159243Sobrien if (cp == 0) 17259243Sobrien nval = 4; 17359243Sobrien else if (*v == 0 && any("+-", cp[0])) 17459243Sobrien nval = getn(cp); 17559243Sobrien#ifdef BSDNICE 17683098Smp if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno) 17783098Smp stderror(ERR_SYSTEM, "setpriority", strerror(errno)); 17859243Sobrien#else /* BSDNICE */ 17959243Sobrien (void) nice(nval); 18059243Sobrien#endif /* BSDNICE */ 18159243Sobrien} 18259243Sobrien 18359243Sobrien#ifdef BSDTIMES 18459243Sobrienvoid 18559243Sobrienruadd(ru, ru2) 18659243Sobrien register struct sysrusage *ru, *ru2; 18759243Sobrien{ 18859243Sobrien tvadd(&ru->ru_utime, &ru2->ru_utime); 18959243Sobrien tvadd(&ru->ru_stime, &ru2->ru_stime); 19059243Sobrien if (ru2->ru_maxrss > ru->ru_maxrss) 19159243Sobrien ru->ru_maxrss = ru2->ru_maxrss; 19259243Sobrien 19359243Sobrien ru->ru_ixrss += ru2->ru_ixrss; 19459243Sobrien ru->ru_idrss += ru2->ru_idrss; 19559243Sobrien ru->ru_isrss += ru2->ru_isrss; 19659243Sobrien ru->ru_minflt += ru2->ru_minflt; 19759243Sobrien ru->ru_majflt += ru2->ru_majflt; 19859243Sobrien ru->ru_nswap += ru2->ru_nswap; 19959243Sobrien ru->ru_inblock += ru2->ru_inblock; 20059243Sobrien ru->ru_oublock += ru2->ru_oublock; 20159243Sobrien ru->ru_msgsnd += ru2->ru_msgsnd; 20259243Sobrien ru->ru_msgrcv += ru2->ru_msgrcv; 20359243Sobrien ru->ru_nsignals += ru2->ru_nsignals; 20459243Sobrien ru->ru_nvcsw += ru2->ru_nvcsw; 20559243Sobrien ru->ru_nivcsw += ru2->ru_nivcsw; 20659243Sobrien 20759243Sobrien# ifdef convex 20859243Sobrien tvadd(&ru->ru_exutime, &ru2->ru_exutime); 20959243Sobrien ru->ru_utotal += ru2->ru_utotal; 21059243Sobrien ru->ru_usamples += ru2->ru_usamples; 21159243Sobrien ru->ru_stotal += ru2->ru_stotal; 21259243Sobrien ru->ru_ssamples += ru2->ru_ssamples; 21359243Sobrien# endif /* convex */ 21459243Sobrien} 21559243Sobrien 21659243Sobrien#else /* BSDTIMES */ 21759243Sobrien# ifdef _SEQUENT_ 21859243Sobrienvoid 21959243Sobrienruadd(ru, ru2) 22059243Sobrien register struct process_stats *ru, *ru2; 22159243Sobrien{ 22259243Sobrien tvadd(&ru->ps_utime, &ru2->ps_utime); 22359243Sobrien tvadd(&ru->ps_stime, &ru2->ps_stime); 22459243Sobrien if (ru2->ps_maxrss > ru->ps_maxrss) 22559243Sobrien ru->ps_maxrss = ru2->ps_maxrss; 22659243Sobrien 22759243Sobrien ru->ps_pagein += ru2->ps_pagein; 22859243Sobrien ru->ps_reclaim += ru2->ps_reclaim; 22959243Sobrien ru->ps_zerofill += ru2->ps_zerofill; 23059243Sobrien ru->ps_pffincr += ru2->ps_pffincr; 23159243Sobrien ru->ps_pffdecr += ru2->ps_pffdecr; 23259243Sobrien ru->ps_swap += ru2->ps_swap; 23359243Sobrien ru->ps_syscall += ru2->ps_syscall; 23459243Sobrien ru->ps_volcsw += ru2->ps_volcsw; 23559243Sobrien ru->ps_involcsw += ru2->ps_involcsw; 23659243Sobrien ru->ps_signal += ru2->ps_signal; 23759243Sobrien ru->ps_lread += ru2->ps_lread; 23859243Sobrien ru->ps_lwrite += ru2->ps_lwrite; 23959243Sobrien ru->ps_bread += ru2->ps_bread; 24059243Sobrien ru->ps_bwrite += ru2->ps_bwrite; 24159243Sobrien ru->ps_phread += ru2->ps_phread; 24259243Sobrien ru->ps_phwrite += ru2->ps_phwrite; 24359243Sobrien} 24459243Sobrien 24559243Sobrien# endif /* _SEQUENT_ */ 24659243Sobrien#endif /* BSDTIMES */ 24759243Sobrien 24859243Sobrien#ifdef BSDTIMES 24959243Sobrien 25059243Sobrien/* 25159243Sobrien * PWP: the LOG1024 and pagetok stuff taken from the top command, 25259243Sobrien * written by William LeFebvre 25359243Sobrien */ 25459243Sobrien/* Log base 2 of 1024 is 10 (2^10 == 1024) */ 25559243Sobrien#define LOG1024 10 25659243Sobrien 25759243Sobrien/* Convert clicks (kernel pages) to kbytes ... */ 25859243Sobrien/* If there is no PGSHIFT defined, assume it is 11 */ 25959243Sobrien/* Is this needed for compatability with some old flavor of 4.2 or 4.1? */ 26059243Sobrien#ifdef SUNOS4 26159243Sobrien# ifndef PGSHIFT 26259243Sobrien# define pagetok(size) ((size) << 1) 26359243Sobrien# else 26459243Sobrien# if PGSHIFT>10 26559243Sobrien# define pagetok(size) ((size) << (PGSHIFT - LOG1024)) 26659243Sobrien# else 26759243Sobrien# define pagetok(size) ((size) >> (LOG1024 - PGSHIFT)) 26859243Sobrien# endif 26959243Sobrien# endif 27059243Sobrien#endif 27159243Sobrien 27259243Sobrien/* 27359243Sobrien * if any other machines return wierd values in the ru_i* stuff, put 27459243Sobrien * the adjusting macro here: 27559243Sobrien */ 27659243Sobrien#ifdef SUNOS4 27759243Sobrien# define IADJUST(i) (pagetok(i)/2) 27859243Sobrien#else /* SUNOS4 */ 27959243Sobrien# ifdef convex 28059243Sobrien /* 28159243Sobrien * convex has megabytes * CLK_TCK 28259243Sobrien * multiply by 100 since we use time in 100ths of a second in prusage 28359243Sobrien */ 28459243Sobrien# define IADJUST(i) (((i) << 10) / CLK_TCK * 100) 28559243Sobrien# else /* convex */ 28659243Sobrien# define IADJUST(i) (i) 28759243Sobrien# endif /* convex */ 28859243Sobrien#endif /* SUNOS4 */ 28959243Sobrien 29059243Sobrienvoid 29159243Sobrienprusage(r0, r1, e, b) 29259243Sobrien register struct sysrusage *r0, *r1; 29359243Sobrien timeval_t *e, *b; 29459243Sobrien 29559243Sobrien#else /* BSDTIMES */ 29659243Sobrien# ifdef _SEQUENT_ 29759243Sobrienvoid 29859243Sobrienprusage(r0, r1, e, b) 29959243Sobrien register struct process_stats *r0, *r1; 30059243Sobrien timeval_t *e, *b; 30159243Sobrien 30259243Sobrien# else /* _SEQUENT_ */ 30359243Sobrienvoid 30459243Sobrienprusage(bs, es, e, b) 30559243Sobrien struct tms *bs, *es; 30659243Sobrien 30759243Sobrien# ifndef POSIX 30859243Sobrien time_t e, b; 30959243Sobrien 31059243Sobrien# else /* POSIX */ 31159243Sobrien clock_t e, b; 31259243Sobrien 31359243Sobrien# endif /* POSIX */ 31459243Sobrien# endif /* _SEQUENT_ */ 31559243Sobrien#endif /* BSDTIMES */ 31659243Sobrien{ 31759243Sobrien#ifdef BSDTIMES 31859243Sobrien register time_t t = 31959243Sobrien (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + 32059243Sobrien (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + 32159243Sobrien (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + 32259243Sobrien (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; 32359243Sobrien 32459243Sobrien#else 32559243Sobrien# ifdef _SEQUENT_ 32659243Sobrien register time_t t = 32759243Sobrien (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec) * 100 + 32859243Sobrien (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 + 32959243Sobrien (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec) * 100 + 33059243Sobrien (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000; 33159243Sobrien 33259243Sobrien# else /* _SEQUENT_ */ 33359243Sobrien# ifndef POSIX 33459243Sobrien register time_t t = (es->tms_utime - bs->tms_utime + 33559243Sobrien es->tms_stime - bs->tms_stime) * 100 / HZ; 33659243Sobrien 33759243Sobrien# else /* POSIX */ 33859243Sobrien register clock_t t = (es->tms_utime - bs->tms_utime + 33959243Sobrien es->tms_stime - bs->tms_stime) * 100 / clk_tck; 34059243Sobrien 34159243Sobrien# endif /* POSIX */ 34259243Sobrien# endif /* _SEQUENT_ */ 34359243Sobrien#endif /* BSDTIMES */ 34459243Sobrien 34559243Sobrien register char *cp; 34659243Sobrien register long i; 34759243Sobrien register struct varent *vp = adrof(STRtime); 34859243Sobrien 34959243Sobrien#ifdef BSDTIMES 35059243Sobrien# ifdef convex 35159243Sobrien static struct system_information sysinfo; 35259243Sobrien long long memtmp; /* let memory calculations exceede 2Gb */ 35359243Sobrien# endif /* convex */ 35459243Sobrien int ms = (int) 35559243Sobrien ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 35659243Sobrien 35759243Sobrien cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 35859243Sobrien#else /* !BSDTIMES */ 35959243Sobrien# ifdef _SEQUENT_ 36059243Sobrien int ms = (int) 36159243Sobrien ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000); 36259243Sobrien 36359243Sobrien cp = "%Uu %Ss %E %P %I+%Oio %Fpf+%Ww"; 36459243Sobrien# else /* !_SEQUENT_ */ 36559243Sobrien# ifndef POSIX 36659243Sobrien time_t ms = ((time_t)((e - b) / HZ) * 100) + 36759243Sobrien (time_t)(((e - b) % HZ) * 100) / HZ; 36859243Sobrien# else /* POSIX */ 36959243Sobrien clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) + 37059243Sobrien (clock_t)(((e - b) % clk_tck) * 100) / clk_tck; 37159243Sobrien# endif /* POSIX */ 37259243Sobrien 37359243Sobrien cp = "%Uu %Ss %E %P"; 37459243Sobrien 37559243Sobrien /* 37659243Sobrien * the tms stuff is not very precise, so we fudge it. 37759243Sobrien * granularity fix: can't be more than 100% 37859243Sobrien * this breaks in multi-processor systems... 37959243Sobrien * maybe I should take it out and let people see more then 100% 38059243Sobrien * utilizations. 38159243Sobrien */ 38259243Sobrien# if 0 38359243Sobrien if (ms < t && ms != 0) 38459243Sobrien ms = t; 38559243Sobrien# endif 38659243Sobrien# endif /*! _SEQUENT_ */ 38759243Sobrien#endif /* !BSDTIMES */ 38859243Sobrien#ifdef TDEBUG 38959243Sobrien xprintf("es->tms_utime %lu bs->tms_utime %lu\n", 39059243Sobrien es->tms_utime, bs->tms_utime); 39159243Sobrien xprintf("es->tms_stime %lu bs->tms_stime %lu\n", 39259243Sobrien es->tms_stime, bs->tms_stime); 39359243Sobrien xprintf("ms %lu e %lu b %lu\n", ms, e, b); 39459243Sobrien xprintf("t %lu\n", t); 39559243Sobrien#endif /* TDEBUG */ 39659243Sobrien 397100616Smp if (vp && vp->vec && vp->vec[0] && vp->vec[1]) 39859243Sobrien cp = short2str(vp->vec[1]); 39959243Sobrien for (; *cp; cp++) 40059243Sobrien if (*cp != '%') 40159243Sobrien xputchar(*cp); 40259243Sobrien else if (cp[1]) 40359243Sobrien switch (*++cp) { 40459243Sobrien 40559243Sobrien case 'U': /* user CPU time used */ 40659243Sobrien#ifdef BSDTIMES 40759243Sobrien pdeltat(&r1->ru_utime, &r0->ru_utime); 40859243Sobrien#else 40959243Sobrien# ifdef _SEQUENT_ 41059243Sobrien pdeltat(&r1->ps_utime, &r0->ps_utime); 41159243Sobrien# else /* _SEQUENT_ */ 41259243Sobrien# ifndef POSIX 41359243Sobrien pdtimet(es->tms_utime, bs->tms_utime); 41459243Sobrien# else /* POSIX */ 41559243Sobrien pdtimet(es->tms_utime, bs->tms_utime); 41659243Sobrien# endif /* POSIX */ 41759243Sobrien# endif /* _SEQUENT_ */ 41859243Sobrien#endif /* BSDTIMES */ 41959243Sobrien break; 42059243Sobrien 42159243Sobrien case 'S': /* system CPU time used */ 42259243Sobrien#ifdef BSDTIMES 42359243Sobrien pdeltat(&r1->ru_stime, &r0->ru_stime); 42459243Sobrien#else 42559243Sobrien# ifdef _SEQUENT_ 42659243Sobrien pdeltat(&r1->ps_stime, &r0->ps_stime); 42759243Sobrien# else /* _SEQUENT_ */ 42859243Sobrien# ifndef POSIX 42959243Sobrien pdtimet(es->tms_stime, bs->tms_stime); 43059243Sobrien# else /* POSIX */ 43159243Sobrien pdtimet(es->tms_stime, bs->tms_stime); 43259243Sobrien# endif /* POSIX */ 43359243Sobrien# endif /* _SEQUENT_ */ 43459243Sobrien#endif /* BSDTIMES */ 43559243Sobrien break; 43659243Sobrien 43759243Sobrien case 'E': /* elapsed (wall-clock) time */ 43859243Sobrien#ifdef BSDTIMES 43959243Sobrien pcsecs((long) ms); 44059243Sobrien#else /* BSDTIMES */ 44159243Sobrien pcsecs(ms); 44259243Sobrien#endif /* BSDTIMES */ 44359243Sobrien break; 44459243Sobrien 44559243Sobrien case 'P': /* percent time spent running */ 44659243Sobrien /* check if the process did not run */ 44759243Sobrien#ifdef convex 44859243Sobrien /* 44959243Sobrien * scale the cpu %- ages by the number of processors 45059243Sobrien * available on this machine 45159243Sobrien */ 45259243Sobrien if ((sysinfo.cpu_count == 0) && 45359243Sobrien (getsysinfo(SYSINFO_SIZE, &sysinfo) < 0)) 45459243Sobrien sysinfo.cpu_count = 1; 45559415Sobrien i = (ms == 0) ? 0 : (t * 1000.0 / (ms * sysinfo.cpu_count)); 45659243Sobrien#else /* convex */ 45761521Sobrien i = (ms == 0) ? 0 : (long)(t * 1000.0 / ms); 45859243Sobrien#endif /* convex */ 45959243Sobrien xprintf("%ld.%01ld%%", i / 10, i % 10); /* nn.n% */ 46059243Sobrien break; 46159243Sobrien 46259243Sobrien#ifdef BSDTIMES 46359243Sobrien case 'W': /* number of swaps */ 46459243Sobrien i = r1->ru_nswap - r0->ru_nswap; 46559243Sobrien xprintf("%ld", i); 46659243Sobrien break; 46759243Sobrien 46859243Sobrien#ifdef convex 46959243Sobrien case 'X': /* (average) shared text size */ 47059243Sobrien memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss - 47159243Sobrien (long long)r0->ru_ixrss) / 47259243Sobrien (long long)t); 47359243Sobrien xprintf("%lu", (unsigned long)memtmp); 47459243Sobrien 47559243Sobrien break; 47659243Sobrien 47759243Sobrien case 'D': /* (average) unshared data size */ 47859243Sobrien memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss + 47959243Sobrien (long long)r1->ru_isrss - 48059243Sobrien ((long long)r0->ru_idrss + 48159243Sobrien (long long)r0->ru_isrss)) / 48259243Sobrien (long long)t); 48359243Sobrien xprintf("%lu", (unsigned long)memtmp); 48459243Sobrien break; 48559243Sobrien 48659243Sobrien case 'K': /* (average) total data memory used */ 48759243Sobrien memtmp = (t == 0 ? 0LL : IADJUST(((long long)r1->ru_ixrss + 48859243Sobrien (long long)r1->ru_isrss + 48959243Sobrien (long long)r1->ru_idrss) - 49059243Sobrien ((long long)r0->ru_ixrss + 49159243Sobrien (long long)r0->ru_idrss + 49259243Sobrien (long long)r0->ru_isrss)) / 49359243Sobrien (long long)t); 49459243Sobrien xprintf("%lu", (unsigned long)memtmp); 49559243Sobrien break; 49659243Sobrien#else /* !convex */ 49759243Sobrien case 'X': /* (average) shared text size */ 49859243Sobrien xprintf("%ld", t == 0 ? 0L : 49959243Sobrien IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t); 50059243Sobrien break; 50159243Sobrien 50259243Sobrien case 'D': /* (average) unshared data size */ 50359243Sobrien xprintf("%ld", t == 0 ? 0L : 50459243Sobrien IADJUST(r1->ru_idrss + r1->ru_isrss - 50559243Sobrien (r0->ru_idrss + r0->ru_isrss)) / t); 50659243Sobrien break; 50759243Sobrien 50859243Sobrien case 'K': /* (average) total data memory used */ 50959243Sobrien xprintf("%ld", t == 0 ? 0L : 51059243Sobrien IADJUST((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - 51159243Sobrien (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); 51259243Sobrien break; 51359243Sobrien#endif /* convex */ 51459243Sobrien case 'M': /* max. Resident Set Size */ 51559243Sobrien#ifdef SUNOS4 51659243Sobrien xprintf("%ld", pagetok(r1->ru_maxrss)); 51759243Sobrien#else 51859243Sobrien# ifdef convex 51959243Sobrien xprintf("%ld", r1->ru_maxrss * 4L); 52059243Sobrien# else /* !convex */ 52159243Sobrien xprintf("%ld", r1->ru_maxrss / 2L); 52259243Sobrien# endif /* convex */ 52359243Sobrien#endif /* SUNOS4 */ 52459243Sobrien break; 52559243Sobrien 52659243Sobrien case 'F': /* page faults */ 52759243Sobrien xprintf("%ld", r1->ru_majflt - r0->ru_majflt); 52859243Sobrien break; 52959243Sobrien 53059243Sobrien case 'R': /* page reclaims */ 53159243Sobrien xprintf("%ld", r1->ru_minflt - r0->ru_minflt); 53259243Sobrien break; 53359243Sobrien 53459243Sobrien case 'I': /* FS blocks in */ 53559243Sobrien xprintf("%ld", r1->ru_inblock - r0->ru_inblock); 53659243Sobrien break; 53759243Sobrien 53859243Sobrien case 'O': /* FS blocks out */ 53959243Sobrien xprintf("%ld", r1->ru_oublock - r0->ru_oublock); 54059243Sobrien break; 54159243Sobrien 54259243Sobrien# ifdef convex 54359243Sobrien case 'C': /* CPU parallelization factor */ 54459243Sobrien if (r1->ru_usamples != 0LL) { 54559243Sobrien long long parr = ((r1->ru_utotal * 100LL) / 54659243Sobrien r1->ru_usamples); 54759243Sobrien xprintf("%d.%02d", (int)(parr/100), (int)(parr%100)); 54859243Sobrien } else 54959243Sobrien xprintf("?"); 55059243Sobrien break; 55159243Sobrien# endif /* convex */ 55259243Sobrien case 'r': /* PWP: socket messages recieved */ 55359243Sobrien xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv); 55459243Sobrien break; 55559243Sobrien 55659243Sobrien case 's': /* PWP: socket messages sent */ 55759243Sobrien xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd); 55859243Sobrien break; 55959243Sobrien 56059243Sobrien case 'k': /* PWP: signals received */ 56159243Sobrien xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals); 56259243Sobrien break; 56359243Sobrien 56459243Sobrien case 'w': /* PWP: voluntary context switches (waits) */ 56559243Sobrien xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw); 56659243Sobrien break; 56759243Sobrien 56859243Sobrien case 'c': /* PWP: involuntary context switches */ 56959243Sobrien xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw); 57059243Sobrien break; 57159243Sobrien#else /* BSDTIMES */ 57259243Sobrien# ifdef _SEQUENT_ 57359243Sobrien case 'W': /* number of swaps */ 57459243Sobrien i = r1->ps_swap - r0->ps_swap; 57559243Sobrien xprintf("%ld", i); 57659243Sobrien break; 57759243Sobrien 57859243Sobrien case 'M': 57959243Sobrien xprintf("%ld", r1->ps_maxrss / 2); 58059243Sobrien break; 58159243Sobrien 58259243Sobrien case 'F': 58359243Sobrien xprintf("%ld", r1->ps_pagein - r0->ps_pagein); 58459243Sobrien break; 58559243Sobrien 58659243Sobrien case 'R': 58759243Sobrien xprintf("%ld", r1->ps_reclaim - r0->ps_reclaim); 58859243Sobrien break; 58959243Sobrien 59059243Sobrien case 'I': 59159243Sobrien xprintf("%ld", r1->ps_bread - r0->ps_bread); 59259243Sobrien break; 59359243Sobrien 59459243Sobrien case 'O': 59559243Sobrien xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite); 59659243Sobrien break; 59759243Sobrien 59859243Sobrien case 'k': 59959243Sobrien xprintf("%ld", r1->ps_signal - r0->ps_signal); 60059243Sobrien break; 60159243Sobrien 60259243Sobrien case 'w': 60359243Sobrien xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw); 60459243Sobrien break; 60559243Sobrien 60659243Sobrien case 'c': 60759243Sobrien xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw); 60859243Sobrien break; 60959243Sobrien 61059243Sobrien case 'Z': 61159243Sobrien xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill); 61259243Sobrien break; 61359243Sobrien 61459243Sobrien case 'i': 61559243Sobrien xprintf("%ld", r1->ps_pffincr - r0->ps_pffincr); 61659243Sobrien break; 61759243Sobrien 61859243Sobrien case 'd': 61959243Sobrien xprintf("%ld", r1->ps_pffdecr - r0->ps_pffdecr); 62059243Sobrien break; 62159243Sobrien 62259243Sobrien case 'Y': 62359243Sobrien xprintf("%ld", r1->ps_syscall - r0->ps_syscall); 62459243Sobrien break; 62559243Sobrien 62659243Sobrien case 'l': 62759243Sobrien xprintf("%ld", r1->ps_lread - r0->ps_lread); 62859243Sobrien break; 62959243Sobrien 63059243Sobrien case 'm': 63159243Sobrien xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite); 63259243Sobrien break; 63359243Sobrien 63459243Sobrien case 'p': 63559243Sobrien xprintf("%ld", r1->ps_phread - r0->ps_phread); 63659243Sobrien break; 63759243Sobrien 63859243Sobrien case 'q': 63959243Sobrien xprintf("%ld", r1->ps_phwrite - r0->ps_phwrite); 64059243Sobrien break; 64159243Sobrien# endif /* _SEQUENT_ */ 64259243Sobrien#endif /* BSDTIMES */ 64359243Sobrien default: 64459243Sobrien break; 64559243Sobrien } 64659243Sobrien xputchar('\n'); 64759243Sobrien} 64859243Sobrien 64959243Sobrien#if defined(BSDTIMES) || defined(_SEQUENT_) 65059243Sobrienstatic void 65159243Sobrienpdeltat(t1, t0) 65259243Sobrien timeval_t *t1, *t0; 65359243Sobrien{ 65459243Sobrien timeval_t td; 65559243Sobrien 65659243Sobrien tvsub(&td, t1, t0); 65759243Sobrien xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L); 65859243Sobrien} 65959243Sobrien 66059243Sobrienstatic void 66159243Sobrientvadd(tsum, t0) 66259243Sobrien timeval_t *tsum, *t0; 66359243Sobrien{ 66459243Sobrien 66559243Sobrien tsum->tv_sec += t0->tv_sec; 66659243Sobrien tsum->tv_usec += t0->tv_usec; 66759243Sobrien if (tsum->tv_usec >= 1000000) 66859243Sobrien tsum->tv_sec++, tsum->tv_usec -= 1000000; 66959243Sobrien} 67059243Sobrien 67159243Sobrienvoid 67259243Sobrientvsub(tdiff, t1, t0) 67359243Sobrien timeval_t *tdiff, *t1, *t0; 67459243Sobrien{ 67559243Sobrien 67659243Sobrien tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 67759243Sobrien tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 67859243Sobrien if (tdiff->tv_usec < 0) 67959243Sobrien tdiff->tv_sec--, tdiff->tv_usec += 1000000; 68059243Sobrien} 68159243Sobrien 68259243Sobrien#else /* !BSDTIMES && !_SEQUENT_ */ 68359243Sobrienstatic void 68459243Sobrienpdtimet(eval, bval) 68559243Sobrien#ifndef POSIX 68659243Sobrien time_t eval, bval; 68759243Sobrien 68859243Sobrien#else /* POSIX */ 68959243Sobrien clock_t eval, bval; 69059243Sobrien 69159243Sobrien#endif /* POSIX */ 69259243Sobrien{ 69359243Sobrien#ifndef POSIX 69459243Sobrien time_t val; 69559243Sobrien 69659243Sobrien#else /* POSIX */ 69759243Sobrien clock_t val; 69859243Sobrien 69959243Sobrien#endif /* POSIX */ 70059243Sobrien 70159243Sobrien#ifndef POSIX 70259243Sobrien val = (eval - bval) * 100 / HZ; 70359243Sobrien#else /* POSIX */ 70459243Sobrien val = (eval - bval) * 100 / clk_tck; 70559243Sobrien#endif /* POSIX */ 70659243Sobrien 70759243Sobrien xprintf("%ld.%02ld", val / 100, val - (val / 100 * 100)); 70859243Sobrien} 70959243Sobrien#endif /* BSDTIMES || _SEQUENT_ */ 710