sh.time.c revision 100616
152419Sjulian/* $Header: /src/pub/tcsh/sh.time.c,v 3.25 2002/06/25 19:02:11 christos Exp $ */
252419Sjulian/*
352419Sjulian * sh.time.c: Shell time keeping and printing.
452419Sjulian */
552419Sjulian/*-
670700Sjulian * Copyright (c) 1980, 1991 The	Regents	of the University of California.
752419Sjulian * All rights reserved.
852419Sjulian *
952419Sjulian * Redistribution and use in source and	binary forms, with or without
1052419Sjulian * modification, are permitted provided	that the following conditions
1152419Sjulian * are met:
1252419Sjulian * 1. Redistributions of source	code must retain the above copyright
1352419Sjulian *    notice, this list	of conditions and the following	disclaimer.
1452419Sjulian * 2. Redistributions in binary	form must reproduce the	above copyright
1552419Sjulian *    notice, this list	of conditions and the following	disclaimer in the
1652419Sjulian *    documentation and/or other materials provided with the distribution.
1770700Sjulian * 3. Neither the name of the University nor the names of its contributors
1852419Sjulian *    may be used to endorse or	promote	products derived from this software
1952419Sjulian *    without specific prior written permission.
2052419Sjulian *
2152419Sjulian * THIS	SOFTWARE IS PROVIDED BY	THE REGENTS AND	CONTRIBUTORS ``AS IS'' AND
2252419Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2352419Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2452419Sjulian * ARE DISCLAIMED.  IN NO EVENT	SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2552419Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR	CONSEQUENTIAL
2652419Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2752419Sjulian * OR SERVICES;	LOSS OF	USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2852419Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2952419Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3052419Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3152419Sjulian * SUCH	DAMAGE.
3252419Sjulian */
3352419Sjulian#include "sh.h"
3452419Sjulian
3552419SjulianRCSID("$Id: sh.time.c,v 3.25 2002/06/25 19:02:11 christos Exp $")
3667506Sjulian
3767506Sjulian#ifdef SUNOS4
3852419Sjulian# include <machine/param.h>
3952419Sjulian#endif /* SUNOS4 */
4052419Sjulian
4152419Sjulian/*
4252419Sjulian * C Shell - routines handling process timing and niceing
4352419Sjulian */
4452419Sjulian#ifdef BSDTIMES
4552419Sjulian# ifndef RUSAGE_SELF
4652419Sjulian#  define	RUSAGE_SELF	0
4752419Sjulian#  define	RUSAGE_CHILDREN	-1
4852419Sjulian# endif	/* RUSAGE_SELF */
4952419Sjulian#else /* BSDTIMES */
5052419Sjulianstruct tms times0;
5152419Sjulian#endif /* BSDTIMES */
5252419Sjulian
5370700Sjulian#if !defined(BSDTIMES) && !defined(_SEQUENT_)
5452419Sjulian# ifdef	POSIX
5552419Sjulianstatic	void	pdtimet	__P((clock_t, clock_t));
5652419Sjulian# else /* ! POSIX */
5752843Sphkstatic	void	pdtimet	__P((time_t, time_t));
5852816Sarchie# endif	/* ! POSIX */
5952419Sjulian#else /* BSDTIMES || _SEQUENT_ */
6052419Sjulianstatic	void	tvadd	__P((timeval_t *, timeval_t *));
6152419Sjulianstatic	void	pdeltat	__P((timeval_t *, timeval_t *));
6252419Sjulian#endif /* BSDTIMES || _SEQUENT_	*/
6352419Sjulian
6453913Sarchievoid
6552419Sjuliansettimes()
6659756Speter{
6759756Speter#ifdef BSDTIMES
6870784Sjulian    struct sysrusage ruch;
6970700Sjulian#ifdef convex
7070700Sjulian    memset(&ru0, 0, sizeof(ru0));
7152419Sjulian    memset(&ruch, 0, sizeof(ruch));
7270784Sjulian#endif /* convex */
7370784Sjulian
7470784Sjulian    (void) gettimeofday(&time0,	NULL);
7570784Sjulian    (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0);
7670784Sjulian    (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
7770784Sjulian    ruadd(&ru0,	&ruch);
7870784Sjulian#else
7970784Sjulian# ifdef	_SEQUENT_
8070784Sjulian    struct process_stats ruch;
8170784Sjulian
8270784Sjulian    (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch);
8370784Sjulian    ruadd(&ru0,	&ruch);
8470935Sjulian# else	/* _SEQUENT_ */
8570935Sjulian    seconds0 = time(NULL);
8670935Sjulian#  ifndef COHERENT
8770935Sjulian    time0 = times(&times0);
8870935Sjulian#  else	/* !COHERENT */
8970935Sjulian    time0 = HZ * seconds0;
9070935Sjulian    times(&times0);
9170935Sjulian#  endif /* !COHERENT */
9270935Sjulian    times0.tms_stime +=	times0.tms_cstime;
9370935Sjulian    times0.tms_utime +=	times0.tms_cutime;
9470935Sjulian    times0.tms_cstime =	0;
9570935Sjulian    times0.tms_cutime =	0;
9670935Sjulian# endif	/* _SEQUENT_ */
9770935Sjulian#endif /* BSDTIMES */
9870935Sjulian}
9970935Sjulian
10070935Sjulian/*
10170935Sjulian * dotime is only called if it is truly	a builtin function and not a
10270935Sjulian * prefix to another command
10370935Sjulian */
10470784Sjulian/*ARGSUSED*/
10570935Sjulianvoid
10670935Sjuliandotime(v, c)
10770935Sjulian    Char **v;
10870935Sjulian    struct command *c;
10970935Sjulian{
11070935Sjulian#ifdef BSDTIMES
11170935Sjulian    timeval_t timedol;
11270935Sjulian    struct sysrusage ru1, ruch;
11370935Sjulian#ifdef convex
11470935Sjulian    memset(&ru1, 0, sizeof(ru1));
11570935Sjulian    memset(&ruch, 0, sizeof(ruch));
11670935Sjulian#endif /* convex */
11770935Sjulian
11870935Sjulian    (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1);
11970935Sjulian    (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
12070935Sjulian    ruadd(&ru1,	&ruch);
12170935Sjulian    (void) gettimeofday(&timedol, NULL);
12270935Sjulian    prusage(&ru0, &ru1,	&timedol, &time0);
12370935Sjulian#else
12470935Sjulian# ifdef	_SEQUENT_
12570935Sjulian    timeval_t timedol;
12670935Sjulian    struct process_stats ru1, ruch;
12770935Sjulian
12870935Sjulian    (void) get_process_stats(&timedol, PS_SELF,	&ru1, &ruch);
12970935Sjulian    ruadd(&ru1,	&ruch);
13070935Sjulian    prusage(&ru0, &ru1,	&timedol, &time0);
13170935Sjulian# else /* _SEQUENT_ */
13270935Sjulian#  ifndef POSIX
13370935Sjulian    time_t  timedol;
13470935Sjulian#  else	/* POSIX */
13570935Sjulian    clock_t timedol;
13670935Sjulian#  endif /* POSIX */
13770935Sjulian
13870935Sjulian    struct tms times_dol;
13970935Sjulian
14070935Sjulian#ifndef	COHERENT
14170935Sjulian    timedol = times(&times_dol);
14270935Sjulian#else
14370935Sjulian    timedol = HZ * time(NULL);
14470935Sjulian    times(&times_dol);
14570935Sjulian#endif
14670935Sjulian    times_dol.tms_stime	+= times_dol.tms_cstime;
14770935Sjulian    times_dol.tms_utime	+= times_dol.tms_cutime;
14870935Sjulian    times_dol.tms_cstime = 0;
14970935Sjulian    times_dol.tms_cutime = 0;
15070700Sjulian    prusage(&times0, &times_dol, timedol, time0);
15170700Sjulian# endif	/* _SEQUENT_ */
15270700Sjulian#endif /* BSDTIMES */
15370700Sjulian    USE(c);
15452419Sjulian    USE(v);
15570700Sjulian}
15670700Sjulian
15752419Sjulian/*
15870700Sjulian * donice is only called when it on the	line by	itself or with a +- value
15971354Sjulian */
16071354Sjulian/*ARGSUSED*/
16171354Sjulianvoid
16270700Sjuliandonice(v, c)
16371354Sjulian    register Char **v;
16471354Sjulian    struct command *c;
16571354Sjulian{
16671354Sjulian    register Char *cp;
16771354Sjulian    int	    nval = 0;
16871354Sjulian
16971354Sjulian    USE(c);
17071354Sjulian    v++, cp = *v++;
17171354Sjulian    if (cp == 0)
17271354Sjulian	nval = 4;
17371354Sjulian    else if (*v	== 0 &&	any("+-", cp[0]))
17471354Sjulian	nval = getn(cp);
17552722Sjulian#ifdef BSDNICE
17670700Sjulian    if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno)
17770700Sjulian	stderror(ERR_SYSTEM, "setpriority", strerror(errno));
17870700Sjulian#else /* BSDNICE */
17970700Sjulian    (void) nice(nval);
18052419Sjulian#endif /* BSDNICE */
18152419Sjulian}
18270700Sjulian
18352722Sjulian#ifdef BSDTIMES
18452419Sjulianvoid
18570700Sjulianruadd(ru, ru2)
18652419Sjulian    register struct sysrusage *ru,	*ru2;
18770700Sjulian{
18870700Sjulian    tvadd(&ru->ru_utime, &ru2->ru_utime);
18970700Sjulian    tvadd(&ru->ru_stime, &ru2->ru_stime);
19070700Sjulian    if (ru2->ru_maxrss > ru->ru_maxrss)
19171047Sjulian	ru->ru_maxrss =	ru2->ru_maxrss;
19271047Sjulian
19371047Sjulian    ru->ru_ixrss += ru2->ru_ixrss;
19471047Sjulian    ru->ru_idrss += ru2->ru_idrss;
19571047Sjulian    ru->ru_isrss += ru2->ru_isrss;
19671047Sjulian    ru->ru_minflt += ru2->ru_minflt;
19752419Sjulian    ru->ru_majflt += ru2->ru_majflt;
19870784Sjulian    ru->ru_nswap += ru2->ru_nswap;
19970700Sjulian    ru->ru_inblock += ru2->ru_inblock;
20070700Sjulian    ru->ru_oublock += ru2->ru_oublock;
20170700Sjulian    ru->ru_msgsnd += ru2->ru_msgsnd;
20270700Sjulian    ru->ru_msgrcv += ru2->ru_msgrcv;
20370700Sjulian    ru->ru_nsignals += ru2->ru_nsignals;
20470700Sjulian    ru->ru_nvcsw += ru2->ru_nvcsw;
20570700Sjulian    ru->ru_nivcsw += ru2->ru_nivcsw;
20670700Sjulian
20770700Sjulian# ifdef	convex
20870784Sjulian    tvadd(&ru->ru_exutime, &ru2->ru_exutime);
20970700Sjulian    ru->ru_utotal += ru2->ru_utotal;
21070700Sjulian    ru->ru_usamples += ru2->ru_usamples;
21152419Sjulian    ru->ru_stotal += ru2->ru_stotal;
21252419Sjulian    ru->ru_ssamples += ru2->ru_ssamples;
21370700Sjulian# endif	/* convex */
21470700Sjulian}
21570700Sjulian
21670700Sjulian#else /* BSDTIMES */
21770700Sjulian# ifdef	_SEQUENT_
21852419Sjulianvoid
21970700Sjulianruadd(ru, ru2)
22070784Sjulian    register struct process_stats *ru, *ru2;
22170784Sjulian{
22270784Sjulian    tvadd(&ru->ps_utime, &ru2->ps_utime);
22370784Sjulian    tvadd(&ru->ps_stime, &ru2->ps_stime);
22470784Sjulian    if (ru2->ps_maxrss > ru->ps_maxrss)
22570784Sjulian	ru->ps_maxrss =	ru2->ps_maxrss;
22670784Sjulian
22770784Sjulian    ru->ps_pagein += ru2->ps_pagein;
22870784Sjulian    ru->ps_reclaim += ru2->ps_reclaim;
22970784Sjulian    ru->ps_zerofill += ru2->ps_zerofill;
23070784Sjulian    ru->ps_pffincr += ru2->ps_pffincr;
23170784Sjulian    ru->ps_pffdecr += ru2->ps_pffdecr;
23270784Sjulian    ru->ps_swap	+= ru2->ps_swap;
23370784Sjulian    ru->ps_syscall += ru2->ps_syscall;
23470784Sjulian    ru->ps_volcsw += ru2->ps_volcsw;
23570784Sjulian    ru->ps_involcsw += ru2->ps_involcsw;
23670784Sjulian    ru->ps_signal += ru2->ps_signal;
23770784Sjulian    ru->ps_lread += ru2->ps_lread;
23870784Sjulian    ru->ps_lwrite += ru2->ps_lwrite;
23970784Sjulian    ru->ps_bread += ru2->ps_bread;
24070784Sjulian    ru->ps_bwrite += ru2->ps_bwrite;
24170784Sjulian    ru->ps_phread += ru2->ps_phread;
24270784Sjulian    ru->ps_phwrite += ru2->ps_phwrite;
24370784Sjulian}
24470784Sjulian
24570784Sjulian# endif	/* _SEQUENT_ */
24670784Sjulian#endif /* BSDTIMES */
24770784Sjulian
24870784Sjulian#ifdef BSDTIMES
24970784Sjulian
25070784Sjulian/*
25170784Sjulian * PWP:	the LOG1024 and	pagetok	stuff taken from the top command,
25270784Sjulian * written by William LeFebvre
25370784Sjulian */
25470784Sjulian/* Log base 2 of 1024 is 10 (2^10 == 1024) */
25570784Sjulian#define	LOG1024		10
25670784Sjulian
25770784Sjulian/* Convert clicks (kernel pages) to kbytes ... */
25870784Sjulian/* If there is no PGSHIFT defined, assume it is	11 */
25970784Sjulian/* Is this needed for compatability with some old flavor of 4.2	or 4.1?	*/
26070784Sjulian#ifdef SUNOS4
26170784Sjulian# ifndef PGSHIFT
26270784Sjulian#  define pagetok(size)	  ((size) << 1)
26370784Sjulian# else
26470784Sjulian#  if PGSHIFT>10
26570784Sjulian#   define pagetok(size)   ((size) << (PGSHIFT - LOG1024))
26670784Sjulian#  else
26770784Sjulian#   define pagetok(size)   ((size) >> (LOG1024 - PGSHIFT))
26870784Sjulian#  endif
26970784Sjulian# endif
27070784Sjulian#endif
27170784Sjulian
27270784Sjulian/*
27370784Sjulian * if any other	machines return	wierd values in	the ru_i* stuff, put
27470784Sjulian * the adjusting macro here:
27570784Sjulian */
27670784Sjulian#ifdef SUNOS4
27770784Sjulian# define IADJUST(i)	(pagetok(i)/2)
27870784Sjulian#else /* SUNOS4	*/
27970784Sjulian# ifdef	convex
28070784Sjulian   /*
28170784Sjulian    * convex has megabytes * CLK_TCK
28270784Sjulian    * multiply by 100 since we use time	in 100ths of a second in prusage
28370784Sjulian    */
28470784Sjulian#  define IADJUST(i) (((i) << 10) / CLK_TCK * 100)
28570784Sjulian# else /* convex */
28670784Sjulian#  define IADJUST(i)	(i)
28770784Sjulian# endif	/* convex */
28870784Sjulian#endif /* SUNOS4 */
28970784Sjulian
29070784Sjulianvoid
29170784Sjulianprusage(r0, r1,	e, b)
29270784Sjulian    register struct sysrusage *r0,	*r1;
29370784Sjulian    timeval_t *e, *b;
29470784Sjulian
29570784Sjulian#else /* BSDTIMES */
29670784Sjulian# ifdef	_SEQUENT_
29770784Sjulianvoid
29870784Sjulianprusage(r0, r1,	e, b)
29970784Sjulian    register struct process_stats *r0, *r1;
30070784Sjulian    timeval_t *e, *b;
30170784Sjulian
30270784Sjulian# else /* _SEQUENT_ */
30370784Sjulianvoid
30470784Sjulianprusage(bs, es,	e, b)
30570784Sjulian    struct tms *bs, *es;
30670784Sjulian
30770784Sjulian#  ifndef POSIX
30870784Sjulian    time_t  e, b;
30970784Sjulian
31070784Sjulian#  else	/* POSIX */
31170784Sjulian    clock_t e, b;
31270784Sjulian
31370784Sjulian#  endif /* POSIX */
31470700Sjulian# endif	/* _SEQUENT_ */
31570700Sjulian#endif /* BSDTIMES */
31670784Sjulian{
31770784Sjulian#ifdef BSDTIMES
31870784Sjulian    register time_t t =
31970700Sjulian    (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec)	* 100 +
32070700Sjulian    (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
32170700Sjulian    (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec)	* 100 +
32270700Sjulian    (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
32352419Sjulian
32452419Sjulian#else
32571047Sjulian# ifdef	_SEQUENT_
32652419Sjulian    register time_t t =
32752419Sjulian    (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec)	* 100 +
32852722Sjulian    (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 +
32952722Sjulian    (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec)	* 100 +
33053403Sarchie    (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000;
33153403Sarchie
33253403Sarchie# else /* _SEQUENT_ */
33353403Sarchie#  ifndef POSIX
33453403Sarchie    register time_t t =	(es->tms_utime - bs->tms_utime +
33553403Sarchie			 es->tms_stime - bs->tms_stime)	* 100 /	HZ;
33653403Sarchie
33753403Sarchie#  else	/* POSIX */
33853403Sarchie    register clock_t t = (es->tms_utime	- bs->tms_utime	+
33953403Sarchie			  es->tms_stime	- bs->tms_stime) * 100 / clk_tck;
34053403Sarchie
34153403Sarchie#  endif /* POSIX */
34253403Sarchie# endif	/* _SEQUENT_ */
34353403Sarchie#endif /* BSDTIMES */
34453403Sarchie
34553403Sarchie    register char *cp;
34653403Sarchie    register long i;
34752722Sjulian    register struct varent *vp = adrof(STRtime);
34853403Sarchie
34952419Sjulian#ifdef BSDTIMES
35053913Sarchie# ifdef	convex
35153913Sarchie    static struct system_information sysinfo;
35253913Sarchie    long long memtmp;	/* let memory calculations exceede 2Gb */
35353913Sarchie# endif	/* convex */
35453913Sarchie    int	    ms = (int)
35553913Sarchie    ((e->tv_sec	- b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
35653913Sarchie
35753913Sarchie    cp = "%Uu %Ss %E %P	%X+%Dk %I+%Oio %Fpf+%Ww";
35853913Sarchie#else /* !BSDTIMES */
35953913Sarchie# ifdef	_SEQUENT_
36053913Sarchie    int	    ms = (int)
36153913Sarchie    ((e->tv_sec	- b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
36253913Sarchie
36353913Sarchie    cp = "%Uu %Ss %E %P	%I+%Oio	%Fpf+%Ww";
36453913Sarchie# else /* !_SEQUENT_ */
36553913Sarchie#  ifndef POSIX
36653913Sarchie    time_t ms = ((time_t)((e - b) / HZ) * 100) +
36753913Sarchie		 (time_t)(((e - b) % HZ) * 100) / HZ;
36853913Sarchie#  else	/* POSIX */
36953913Sarchie    clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) +
37053913Sarchie		  (clock_t)(((e - b) % clk_tck) * 100) / clk_tck;
37153913Sarchie#  endif /* POSIX */
37253913Sarchie
37353913Sarchie    cp = "%Uu %Ss %E %P";
37453913Sarchie
37553913Sarchie    /*
37653913Sarchie     * the tms stuff is	not very precise, so we	fudge it.
37753913Sarchie     * granularity fix:	can't be more than 100%
37853913Sarchie     * this breaks in multi-processor systems...
37953913Sarchie     * maybe I should take it out and let people see more then 100%
38053913Sarchie     * utilizations.
38153913Sarchie     */
38253913Sarchie#  if 0
38353913Sarchie    if (ms < t && ms !=	0)
38453913Sarchie	ms = t;
38553913Sarchie#  endif
38653913Sarchie# endif	/*! _SEQUENT_ */
38753913Sarchie#endif /* !BSDTIMES */
38853913Sarchie#ifdef TDEBUG
38953913Sarchie    xprintf("es->tms_utime %lu bs->tms_utime %lu\n",
39053913Sarchie	    es->tms_utime, bs->tms_utime);
39153913Sarchie    xprintf("es->tms_stime %lu bs->tms_stime %lu\n",
39253913Sarchie	    es->tms_stime, bs->tms_stime);
39353913Sarchie    xprintf("ms	%lu e %lu b %lu\n", ms,	e, b);
39453913Sarchie    xprintf("t %lu\n", t);
39553913Sarchie#endif /* TDEBUG */
39653913Sarchie
39753913Sarchie    if (vp && vp->vec && vp->vec[0] && vp->vec[1])
39853913Sarchie	cp = short2str(vp->vec[1]);
39953913Sarchie    for	(; *cp;	cp++)
40053913Sarchie	if (*cp	!= '%')
40153913Sarchie	    xputchar(*cp);
40253913Sarchie	else if	(cp[1])
40353913Sarchie	    switch (*++cp) {
40453913Sarchie
40553913Sarchie	    case 'U':		/* user	CPU time used */
40653913Sarchie#ifdef BSDTIMES
40753913Sarchie		pdeltat(&r1->ru_utime, &r0->ru_utime);
40853913Sarchie#else
40953913Sarchie# ifdef	_SEQUENT_
41053913Sarchie		pdeltat(&r1->ps_utime, &r0->ps_utime);
41153913Sarchie# else /* _SEQUENT_ */
41253913Sarchie#  ifndef POSIX
41353913Sarchie		pdtimet(es->tms_utime, bs->tms_utime);
41453913Sarchie#  else	/* POSIX */
41553913Sarchie		pdtimet(es->tms_utime, bs->tms_utime);
41653913Sarchie#  endif /* POSIX */
41753913Sarchie# endif	/* _SEQUENT_ */
41853913Sarchie#endif /* BSDTIMES */
41953913Sarchie		break;
42053913Sarchie
42153913Sarchie	    case 'S':		/* system CPU time used	*/
42253913Sarchie#ifdef BSDTIMES
42353913Sarchie		pdeltat(&r1->ru_stime, &r0->ru_stime);
42453913Sarchie#else
42553913Sarchie# ifdef	_SEQUENT_
42653913Sarchie		pdeltat(&r1->ps_stime, &r0->ps_stime);
42753913Sarchie# else /* _SEQUENT_ */
42853913Sarchie#  ifndef POSIX
42953913Sarchie		pdtimet(es->tms_stime, bs->tms_stime);
43053913Sarchie#  else	/* POSIX */
43153913Sarchie		pdtimet(es->tms_stime, bs->tms_stime);
43253913Sarchie#  endif /* POSIX */
43353913Sarchie# endif	/* _SEQUENT_ */
43453913Sarchie#endif /* BSDTIMES */
43553913Sarchie		break;
43653913Sarchie
43753913Sarchie	    case 'E':		/* elapsed (wall-clock)	time */
43853913Sarchie#ifdef BSDTIMES
43953913Sarchie		pcsecs((long) ms);
44053913Sarchie#else /* BSDTIMES */
44153913Sarchie		pcsecs(ms);
44253913Sarchie#endif /* BSDTIMES */
44353913Sarchie		break;
44453913Sarchie
44553913Sarchie	    case 'P':		/* percent time	spent running */
44653913Sarchie		/* check if the	process	did not	run */
44753913Sarchie#ifdef convex
44853913Sarchie		/*
44953913Sarchie		 * scale the cpu %- ages by the	number of processors
45053913Sarchie		 * available on	this machine
45153913Sarchie		 */
45253913Sarchie		if ((sysinfo.cpu_count == 0) &&
45353913Sarchie		    (getsysinfo(SYSINFO_SIZE, &sysinfo)	< 0))
45453913Sarchie		    sysinfo.cpu_count =	1;
45553913Sarchie		    i =	(ms == 0) ? 0 :	(t * 1000.0 / (ms * sysinfo.cpu_count));
45653913Sarchie#else /* convex	*/
45753913Sarchie		i = (ms	== 0) ?	0 : (long)(t * 1000.0 / ms);
45853913Sarchie#endif /* convex */
45953913Sarchie		xprintf("%ld.%01ld%%", i / 10, i % 10);	/* nn.n% */
46053913Sarchie		break;
46153913Sarchie
46253913Sarchie#ifdef BSDTIMES
46353913Sarchie	    case 'W':		/* number of swaps */
46453913Sarchie		i = r1->ru_nswap - r0->ru_nswap;
46553913Sarchie		xprintf("%ld", i);
46653913Sarchie		break;
46753913Sarchie
46853913Sarchie#ifdef convex
46953913Sarchie	    case 'X':		/* (average) shared text size */
47053913Sarchie		memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss -
47153913Sarchie				 (long long)r0->ru_ixrss) /
47253913Sarchie			 (long long)t);
47353913Sarchie		xprintf("%lu", (unsigned long)memtmp);
47453913Sarchie
47553913Sarchie		break;
47653913Sarchie
47753913Sarchie	    case 'D':		/* (average) unshared data size	*/
47853913Sarchie		memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss +
47953913Sarchie				 (long long)r1->ru_isrss -
48053913Sarchie				 ((long	long)r0->ru_idrss +
48153913Sarchie				  (long	long)r0->ru_isrss)) /
48253913Sarchie			 (long long)t);
48353913Sarchie		xprintf("%lu", (unsigned long)memtmp);
48453913Sarchie		break;
48553913Sarchie
48653913Sarchie	    case 'K':		/* (average) total data	memory used  */
48753913Sarchie		memtmp = (t == 0 ? 0LL : IADJUST(((long	long)r1->ru_ixrss +
48853913Sarchie				  (long	long)r1->ru_isrss +
48953913Sarchie				  (long	long)r1->ru_idrss) -
49053913Sarchie				  ((long long)r0->ru_ixrss +
49153913Sarchie				   (long long)r0->ru_idrss +
49253913Sarchie				   (long long)r0->ru_isrss)) /
49353913Sarchie			 (long long)t);
49453913Sarchie		xprintf("%lu", (unsigned long)memtmp);
49553913Sarchie		break;
49653913Sarchie#else /* !convex */
49753913Sarchie	    case 'X':		/* (average) shared text size */
49853913Sarchie		xprintf("%ld", t == 0 ?	0L :
49953913Sarchie			IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t);
50062471Sphk		break;
50162471Sphk
50262471Sphk	    case 'D':		/* (average) unshared data size	*/
50362471Sphk		xprintf("%ld", t == 0 ?	0L :
50462471Sphk			IADJUST(r1->ru_idrss + r1->ru_isrss -
50562471Sphk				(r0->ru_idrss +	r0->ru_isrss)) / t);
50662471Sphk		break;
50753913Sarchie
50853913Sarchie	    case 'K':		/* (average) total data	memory used  */
50953913Sarchie		xprintf("%ld", t == 0 ?	0L :
51053913Sarchie			IADJUST((r1->ru_ixrss +	r1->ru_isrss + r1->ru_idrss) -
51153913Sarchie			   (r0->ru_ixrss + r0->ru_idrss	+ r0->ru_isrss)) / t);
51253913Sarchie		break;
51353913Sarchie#endif /* convex */
51453913Sarchie	    case 'M':		/* max.	Resident Set Size */
51553913Sarchie#ifdef SUNOS4
51653913Sarchie		xprintf("%ld", pagetok(r1->ru_maxrss));
51753913Sarchie#else
51853913Sarchie# ifdef	convex
51953913Sarchie		xprintf("%ld", r1->ru_maxrss * 4L);
52053913Sarchie# else /* !convex */
52153913Sarchie		xprintf("%ld", r1->ru_maxrss / 2L);
52253913Sarchie# endif	/* convex */
52353913Sarchie#endif /* SUNOS4 */
52453913Sarchie		break;
52553913Sarchie
52653913Sarchie	    case 'F':		/* page	faults */
52753913Sarchie		xprintf("%ld", r1->ru_majflt - r0->ru_majflt);
52853913Sarchie		break;
52953913Sarchie
53052419Sjulian	    case 'R':		/* page	reclaims */
53152419Sjulian		xprintf("%ld", r1->ru_minflt - r0->ru_minflt);
53252419Sjulian		break;
53352419Sjulian
53452419Sjulian	    case 'I':		/* FS blocks in	*/
53552419Sjulian		xprintf("%ld", r1->ru_inblock -	r0->ru_inblock);
53652419Sjulian		break;
53752419Sjulian
53852419Sjulian	    case 'O':		/* FS blocks out */
53952419Sjulian		xprintf("%ld", r1->ru_oublock -	r0->ru_oublock);
54070700Sjulian		break;
54152419Sjulian
54252419Sjulian# ifdef	convex
54352419Sjulian	    case 'C':			/*  CPU	parallelization	factor */
54471047Sjulian		if (r1->ru_usamples	!= 0LL)	{
54552419Sjulian		    long long parr = ((r1->ru_utotal * 100LL) /
54652419Sjulian				      r1->ru_usamples);
54752419Sjulian		    xprintf("%d.%02d", (int)(parr/100), (int)(parr%100));
54852419Sjulian		} else
54952419Sjulian		    xprintf("?");
55059875Speter		break;
55152419Sjulian# endif	/* convex */
55252419Sjulian	    case 'r':		/* PWP:	socket messages	recieved */
55352419Sjulian		xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv);
55452419Sjulian		break;
55569923Sjulian
55659875Speter	    case 's':		/* PWP:	socket messages	sent */
55752419Sjulian		xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd);
55852419Sjulian		break;
55952419Sjulian
56052419Sjulian	    case 'k':		/* PWP:	signals	received */
56152419Sjulian		xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals);
56252419Sjulian		break;
56352419Sjulian
56452419Sjulian	    case 'w':		/* PWP:	voluntary context switches (waits) */
56552419Sjulian		xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw);
56670700Sjulian		break;
56770700Sjulian
56870700Sjulian	    case 'c':		/* PWP:	involuntary context switches */
56970700Sjulian		xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw);
57070700Sjulian		break;
57170700Sjulian#else /* BSDTIMES */
57270700Sjulian# ifdef	_SEQUENT_
57370784Sjulian	    case 'W':		/* number of swaps */
57470700Sjulian		i = r1->ps_swap	- r0->ps_swap;
57570700Sjulian		xprintf("%ld", i);
57670700Sjulian		break;
57770700Sjulian
57870700Sjulian	    case 'M':
57970700Sjulian		xprintf("%ld", r1->ps_maxrss / 2);
58070935Sjulian		break;
58170700Sjulian
58270700Sjulian	    case 'F':
58370700Sjulian		xprintf("%ld", r1->ps_pagein - r0->ps_pagein);
58471047Sjulian		break;
58570700Sjulian
58670700Sjulian	    case 'R':
58770700Sjulian		xprintf("%ld", r1->ps_reclaim -	r0->ps_reclaim);
58852419Sjulian		break;
58952419Sjulian
59052419Sjulian	    case 'I':
59170700Sjulian		xprintf("%ld", r1->ps_bread - r0->ps_bread);
59270700Sjulian		break;
59352419Sjulian
59452419Sjulian	    case 'O':
59552419Sjulian		xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite);
59652419Sjulian		break;
59752419Sjulian
59852419Sjulian	    case 'k':
59952419Sjulian		xprintf("%ld", r1->ps_signal - r0->ps_signal);
60052419Sjulian		break;
60152419Sjulian
60271047Sjulian	    case 'w':
60352419Sjulian		xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw);
60452419Sjulian		break;
60552419Sjulian
60652419Sjulian	    case 'c':
60770784Sjulian		xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw);
60852419Sjulian		break;
60971047Sjulian
61052419Sjulian	    case 'Z':
61152419Sjulian		xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill);
61270784Sjulian		break;
61370784Sjulian
61452419Sjulian	    case 'i':
61552419Sjulian		xprintf("%ld", r1->ps_pffincr -	r0->ps_pffincr);
61671380Sjulian		break;
61770784Sjulian
61870784Sjulian	    case 'd':
61970784Sjulian		xprintf("%ld", r1->ps_pffdecr -	r0->ps_pffdecr);
62070784Sjulian		break;
62152419Sjulian
62252419Sjulian	    case 'Y':
62370784Sjulian		xprintf("%ld", r1->ps_syscall -	r0->ps_syscall);
62452419Sjulian		break;
62570700Sjulian
62670700Sjulian	    case 'l':
62770784Sjulian		xprintf("%ld", r1->ps_lread - r0->ps_lread);
62870700Sjulian		break;
62970700Sjulian
63070700Sjulian	    case 'm':
63152722Sjulian		xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite);
63270700Sjulian		break;
63370784Sjulian
63470700Sjulian	    case 'p':
63570784Sjulian		xprintf("%ld", r1->ps_phread - r0->ps_phread);
63671354Sjulian		break;
63770784Sjulian
63871354Sjulian	    case 'q':
63971354Sjulian		xprintf("%ld", r1->ps_phwrite -	r0->ps_phwrite);
64070784Sjulian		break;
64170700Sjulian# endif	/* _SEQUENT_ */
64270784Sjulian#endif /* BSDTIMES */
64371354Sjulian	    default:
64470784Sjulian		break;
64570700Sjulian	    }
64652722Sjulian    xputchar('\n');
64752419Sjulian}
64852419Sjulian
64952419Sjulian#if defined(BSDTIMES) || defined(_SEQUENT_)
65052419Sjulianstatic void
65152419Sjulianpdeltat(t1, t0)
65252419Sjulian    timeval_t *t1, *t0;
65352419Sjulian{
65452419Sjulian    timeval_t td;
65552419Sjulian
65652419Sjulian    tvsub(&td, t1, t0);
65770700Sjulian    xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L);
65870939Sjulian}
65970939Sjulian
66070700Sjulianstatic void
66170700Sjuliantvadd(tsum, t0)
66270939Sjulian    timeval_t *tsum, *t0;
66370939Sjulian{
66470939Sjulian
66570939Sjulian    tsum->tv_sec += t0->tv_sec;
66670939Sjulian    tsum->tv_usec += t0->tv_usec;
66770939Sjulian    if (tsum->tv_usec >= 1000000)
66870939Sjulian	tsum->tv_sec++,	tsum->tv_usec -= 1000000;
66952419Sjulian}
67052419Sjulian
67152419Sjulianvoid
67252419Sjuliantvsub(tdiff, t1, t0)
67370939Sjulian    timeval_t *tdiff, *t1, *t0;
67470939Sjulian{
67552419Sjulian
67670784Sjulian    tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
67752419Sjulian    tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
67852419Sjulian    if (tdiff->tv_usec < 0)
67952419Sjulian	tdiff->tv_sec--, tdiff->tv_usec	+= 1000000;
68070784Sjulian}
68152419Sjulian
68270784Sjulian#else /* !BSDTIMES && !_SEQUENT_ */
68370784Sjulianstatic void
68470784Sjulianpdtimet(eval, bval)
68570784Sjulian#ifndef	POSIX
68670784Sjulian    time_t  eval, bval;
68770784Sjulian
68870784Sjulian#else /* POSIX */
68952419Sjulian    clock_t eval, bval;
69070939Sjulian
69170939Sjulian#endif /* POSIX	*/
69270939Sjulian{
69370784Sjulian#ifndef	POSIX
69470700Sjulian    time_t  val;
69570700Sjulian
69670784Sjulian#else /* POSIX */
69770784Sjulian    clock_t val;
69870784Sjulian
69970700Sjulian#endif /* POSIX	*/
70070784Sjulian
70170700Sjulian#ifndef	POSIX
70270700Sjulian    val	= (eval	- bval)	* 100 /	HZ;
70370700Sjulian#else /* POSIX */
70470784Sjulian    val	= (eval	- bval)	* 100 /	clk_tck;
70570700Sjulian#endif /* POSIX	*/
70670700Sjulian
70770700Sjulian    xprintf("%ld.%02ld", val / 100, val	- (val / 100 * 100));
70852419Sjulian}
70970784Sjulian#endif /* BSDTIMES || _SEQUENT_	*/
71070784Sjulian