sh.time.c revision 167465
1124524Sume/* $Header: /p/tcsh/cvsroot/tcsh/sh.time.c,v 3.33 2006/03/02 18:46:44 christos Exp $ */
266776Skris/*
355163Sshin * sh.time.c: Shell time keeping and printing.
455163Sshin */
5222732Shrs/*-
655163Sshin * Copyright (c) 1980, 1991 The	Regents	of the University of California.
762632Skris * All rights reserved.
855163Sshin *
955163Sshin * Redistribution and use in source and	binary forms, with or without
1055163Sshin * modification, are permitted provided	that the following conditions
1155163Sshin * are met:
1255163Sshin * 1. Redistributions of source	code must retain the above copyright
1355163Sshin *    notice, this list	of conditions and the following	disclaimer.
1455163Sshin * 2. Redistributions in binary	form must reproduce the	above copyright
1555163Sshin *    notice, this list	of conditions and the following	disclaimer in the
1655163Sshin *    documentation and/or other materials provided with the distribution.
1755163Sshin * 3. Neither the name of the University nor the names of its contributors
1855163Sshin *    may be used to endorse or	promote	products derived from this software
1962632Skris *    without specific prior written permission.
2055163Sshin *
2155163Sshin * THIS	SOFTWARE IS PROVIDED BY	THE REGENTS AND	CONTRIBUTORS ``AS IS'' AND
2255163Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355163Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455163Sshin * ARE DISCLAIMED.  IN NO EVENT	SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2555163Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR	CONSEQUENTIAL
2655163Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755163Sshin * OR SERVICES;	LOSS OF	USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855163Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955163Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055163Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155163Sshin * SUCH	DAMAGE.
3255163Sshin */
3355163Sshin#include "sh.h"
3455163Sshin
3555163SshinRCSID("$tcsh: sh.time.c,v 3.33 2006/03/02 18:46:44 christos Exp $")
3655163Sshin
3755163Sshin#ifdef SUNOS4
3866776Skris# include <machine/param.h>
39118661Sume#endif /* SUNOS4 */
40118661Sume
4155163Sshin/*
4255163Sshin * C Shell - routines handling process timing and niceing
4355163Sshin */
4455163Sshin#ifdef BSDTIMES
4555163Sshin# ifndef RUSAGE_SELF
46222732Shrs#  define	RUSAGE_SELF	0
4755163Sshin#  define	RUSAGE_CHILDREN	-1
48222732Shrs# endif	/* RUSAGE_SELF */
4955163Sshin#else /* BSDTIMES */
5055163Sshinstruct tms times0;
5155163Sshin#endif /* BSDTIMES */
5255163Sshin
5355163Sshin#if !defined(BSDTIMES) && !defined(_SEQUENT_)
5455163Sshin# ifdef	POSIX
55222732Shrsstatic	void	pdtimet	(clock_t, clock_t);
5655163Sshin# else /* ! POSIX */
57119026Sumestatic	void	pdtimet	(time_t, time_t);
5855163Sshin# endif	/* ! POSIX */
5955163Sshin#else /* BSDTIMES || _SEQUENT_ */
60253970Shrsstatic	void	tvadd	(timeval_t *, timeval_t *);
6155163Sshinstatic	void	pdeltat	(timeval_t *, timeval_t *);
6255163Sshin#endif /* BSDTIMES || _SEQUENT_	*/
6355163Sshin
6455163Sshinvoid
6555163Sshinsettimes(void)
6655163Sshin{
6755163Sshin#ifdef BSDTIMES
6855163Sshin    struct sysrusage ruch;
6955163Sshin#ifdef convex
7055163Sshin    memset(&ru0, 0, sizeof(ru0));
7155163Sshin    memset(&ruch, 0, sizeof(ruch));
7255163Sshin#endif /* convex */
73119026Sume
7455163Sshin    (void) gettimeofday(&time0,	NULL);
7562632Skris    (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0);
76225520Shrs    (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
77222732Shrs    ruadd(&ru0,	&ruch);
78222732Shrs#else
7955163Sshin# ifdef	_SEQUENT_
80222732Shrs    struct process_stats ruch;
81204407Suqs
82204407Suqs    (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch);
83222732Shrs    ruadd(&ru0,	&ruch);
84204407Suqs# else	/* _SEQUENT_ */
8555163Sshin    seconds0 = time(NULL);
86225520Shrs    time0 = times(&times0);
87225520Shrs    times0.tms_stime +=	times0.tms_cstime;
88222732Shrs    times0.tms_utime +=	times0.tms_cutime;
89173412Skevlo    times0.tms_cstime =	0;
90222861Shrs    times0.tms_cutime =	0;
91225520Shrs# endif	/* _SEQUENT_ */
92225520Shrs#endif /* BSDTIMES */
93225520Shrs}
94118661Sume
95222732Shrs/*
96225520Shrs * dotime is only called if it is truly	a builtin function and not a
97225520Shrs * prefix to another command
98222732Shrs */
99222732Shrs/*ARGSUSED*/
100222732Shrsvoid
101222732Shrsdotime(Char **v, struct command *c)
102222732Shrs{
103222732Shrs#ifdef BSDTIMES
104222732Shrs    timeval_t timedol;
105222732Shrs    struct sysrusage ru1, ruch;
106222732Shrs#ifdef convex
107222732Shrs    memset(&ru1, 0, sizeof(ru1));
108222732Shrs    memset(&ruch, 0, sizeof(ruch));
109222732Shrs#endif /* convex */
110222732Shrs
111222732Shrs    (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1);
112222732Shrs    (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
113222732Shrs    ruadd(&ru1,	&ruch);
114222732Shrs    (void) gettimeofday(&timedol, NULL);
115222732Shrs    prusage(&ru0, &ru1,	&timedol, &time0);
11655163Sshin#else
117124524Sume# ifdef	_SEQUENT_
11855163Sshin    timeval_t timedol;
119119026Sume    struct process_stats ru1, ruch;
120119026Sume
121119026Sume    (void) get_process_stats(&timedol, PS_SELF,	&ru1, &ruch);
12255163Sshin    ruadd(&ru1,	&ruch);
12355163Sshin    prusage(&ru0, &ru1,	&timedol, &time0);
12462632Skris# else /* _SEQUENT_ */
125118664Sume#  ifndef POSIX
12662632Skris    time_t  timedol;
127118660Sume#  else	/* POSIX */
128118664Sume    clock_t timedol;
129222732Shrs#  endif /* POSIX */
13062632Skris
131118664Sume    struct tms times_dol;
132118660Sume
133118664Sume    timedol = times(&times_dol);
134222732Shrs    times_dol.tms_stime	+= times_dol.tms_cstime;
13562632Skris    times_dol.tms_utime	+= times_dol.tms_cutime;
13655163Sshin    times_dol.tms_cstime = 0;
137118660Sume    times_dol.tms_cutime = 0;
138222732Shrs    prusage(&times0, &times_dol, timedol, time0);
13955163Sshin# endif	/* _SEQUENT_ */
14055163Sshin#endif /* BSDTIMES */
14155163Sshin    USE(c);
14255163Sshin    USE(v);
14362632Skris}
144118664Sume
145118660Sume/*
146118664Sume * donice is only called when it on the	line by	itself or with a +- value
14762632Skris */
14862632Skris/*ARGSUSED*/
14955163Sshinvoid
150222732Shrsdonice(Char **v, struct command *c)
15155163Sshin{
15262632Skris    Char *cp;
153118664Sume    int	    nval = 0;
154118660Sume
155118664Sume    USE(c);
15662632Skris    v++, cp = *v++;
15762632Skris    if (cp == 0)
15855163Sshin	nval = 4;
15955163Sshin    else if (*v	== 0 &&	any("+-", cp[0]))
16055163Sshin	nval = getn(cp);
16155163Sshin#ifdef HAVE_SETPRIORITY
16255163Sshin    if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno)
163118664Sume	stderror(ERR_SYSTEM, "setpriority", strerror(errno));
164118660Sume#else /* !HAVE_SETPRIORITY */
165118664Sume    (void) nice(nval);
16655163Sshin#endif /* HAVE_SETPRIORITY */
16755163Sshin}
16855163Sshin
16955163Sshin#ifdef BSDTIMES
17055163Sshinvoid
17155163Sshinruadd(struct sysrusage *ru, struct sysrusage *ru2)
17255163Sshin{
17355163Sshin    tvadd(&ru->ru_utime, &ru2->ru_utime);
17455163Sshin    tvadd(&ru->ru_stime, &ru2->ru_stime);
17555163Sshin#ifndef _OSD_POSIX
17655163Sshin    if (ru2->ru_maxrss > ru->ru_maxrss)
17755163Sshin	ru->ru_maxrss =	ru2->ru_maxrss;
17855163Sshin
17955163Sshin    ru->ru_ixrss += ru2->ru_ixrss;
18055163Sshin    ru->ru_idrss += ru2->ru_idrss;
18155163Sshin    ru->ru_isrss += ru2->ru_isrss;
18262632Skris    ru->ru_minflt += ru2->ru_minflt;
18355163Sshin    ru->ru_majflt += ru2->ru_majflt;
184222732Shrs    ru->ru_nswap += ru2->ru_nswap;
18555163Sshin    ru->ru_inblock += ru2->ru_inblock;
18655163Sshin    ru->ru_oublock += ru2->ru_oublock;
18755163Sshin    ru->ru_msgsnd += ru2->ru_msgsnd;
188222732Shrs    ru->ru_msgrcv += ru2->ru_msgrcv;
18955163Sshin    ru->ru_nsignals += ru2->ru_nsignals;
190118664Sume    ru->ru_nvcsw += ru2->ru_nvcsw;
191118664Sume    ru->ru_nivcsw += ru2->ru_nivcsw;
192118664Sume#endif /*bs2000*/
193204407Suqs
194119026Sume# ifdef	convex
19555163Sshin    tvadd(&ru->ru_exutime, &ru2->ru_exutime);
196119026Sume    ru->ru_utotal += ru2->ru_utotal;
197222732Shrs    ru->ru_usamples += ru2->ru_usamples;
198119026Sume    ru->ru_stotal += ru2->ru_stotal;
199119026Sume    ru->ru_ssamples += ru2->ru_ssamples;
200222732Shrs# endif	/* convex */
201222732Shrs}
20255163Sshin
20355163Sshin#else /* BSDTIMES */
20455163Sshin# ifdef	_SEQUENT_
20555163Sshinvoid
20655163Sshinruadd(struct process_stats *ru, struct process_stats *ru2)
20755163Sshin{
208254462Shrs    tvadd(&ru->ps_utime, &ru2->ps_utime);
20955163Sshin    tvadd(&ru->ps_stime, &ru2->ps_stime);
210222732Shrs    if (ru2->ps_maxrss > ru->ps_maxrss)
21155163Sshin	ru->ps_maxrss =	ru2->ps_maxrss;
21255163Sshin
213118664Sume    ru->ps_pagein += ru2->ps_pagein;
214118664Sume    ru->ps_reclaim += ru2->ps_reclaim;
215118664Sume    ru->ps_zerofill += ru2->ps_zerofill;
216118664Sume    ru->ps_pffincr += ru2->ps_pffincr;
217118664Sume    ru->ps_pffdecr += ru2->ps_pffdecr;
21855163Sshin    ru->ps_swap	+= ru2->ps_swap;
219118664Sume    ru->ps_syscall += ru2->ps_syscall;
220118664Sume    ru->ps_volcsw += ru2->ps_volcsw;
221222732Shrs    ru->ps_involcsw += ru2->ps_involcsw;
22255163Sshin    ru->ps_signal += ru2->ps_signal;
223222732Shrs    ru->ps_lread += ru2->ps_lread;
22455163Sshin    ru->ps_lwrite += ru2->ps_lwrite;
22555163Sshin    ru->ps_bread += ru2->ps_bread;
22655163Sshin    ru->ps_bwrite += ru2->ps_bwrite;
22755163Sshin    ru->ps_phread += ru2->ps_phread;
22855163Sshin    ru->ps_phwrite += ru2->ps_phwrite;
229118660Sume}
230222732Shrs
23155163Sshin# endif	/* _SEQUENT_ */
23255163Sshin#endif /* BSDTIMES */
23355163Sshin
234222732Shrs#ifdef BSDTIMES
23555163Sshin
23655163Sshin/*
23755163Sshin * PWP:	the LOG1024 and	pagetok	stuff taken from the top command,
23855163Sshin * written by William LeFebvre
23955163Sshin */
240253376Skevlo/* Log base 2 of 1024 is 10 (2^10 == 1024) */
241222732Shrs#define	LOG1024		10
242222732Shrs
24355163Sshin/* Convert clicks (kernel pages) to kbytes ... */
24455163Sshin/* If there is no PGSHIFT defined, assume it is	11 */
245222732Shrs/* Is this needed for compatability with some old flavor of 4.2	or 4.1?	*/
246119026Sume#ifdef SUNOS4
247118661Sume# ifndef PGSHIFT
248119026Sume#  define pagetok(size)	  ((size) << 1)
249222861Shrs# else
250222732Shrs#  if PGSHIFT>10
251222732Shrs#   define pagetok(size)   ((size) << (PGSHIFT - LOG1024))
252222732Shrs#  else
253222732Shrs#   define pagetok(size)   ((size) >> (LOG1024 - PGSHIFT))
254222732Shrs#  endif
255222732Shrs# endif
256222732Shrs#endif
257222732Shrs
258222732Shrs/*
259253970Shrs * if any other	machines return	wierd values in	the ru_i* stuff, put
260253970Shrs * the adjusting macro here:
261222861Shrs */
262222861Shrs#ifdef SUNOS4
26355163Sshin# define IADJUST(i)	(pagetok(i)/2)
264119026Sume#else /* SUNOS4	*/
265119026Sume# ifdef	convex
266119026Sume   /*
267222732Shrs    * convex has megabytes * CLK_TCK
268118660Sume    * multiply by 100 since we use time	in 100ths of a second in prusage
26955163Sshin    */
27055163Sshin#  define IADJUST(i) (((i) << 10) / CLK_TCK * 100)
27155163Sshin# else /* convex */
27255163Sshin#  define IADJUST(i)	(i)
273118664Sume# endif	/* convex */
274118664Sume#endif /* SUNOS4 */
27555163Sshin
27655163Sshinvoid
27755163Sshinprusage(struct sysrusage *r0, struct sysrusage *r1, timeval_t *e, timeval_t *b)
278254462Shrs
27955163Sshin#else /* BSDTIMES */
28055163Sshin# ifdef	_SEQUENT_
28155163Sshinvoid
28255163Sshinprusage(struct process_stats *r0, struct process_stats *r1, timeval_t e,
28355163Sshin	timeval_t b)
284254462Shrs
28555163Sshin# else /* _SEQUENT_ */
28655163Sshin#  ifndef POSIX
28755163Sshinvoid
288118664Sumeprusage(struct tms *bs, struct tms *es, time_t e, time_t b)
289118664Sume#  else	/* POSIX */
29055163Sshinvoid
29155163Sshinprusage(struct tms *bs, struct tms *es, clock_t e, clock_t b)
29255163Sshin#  endif /* POSIX */
293118664Sume# endif	/* _SEQUENT_ */
294118664Sume#endif /* BSDTIMES */
29555163Sshin{
29655163Sshin#ifdef BSDTIMES
29755163Sshin    time_t t =
298222732Shrs    (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec)	* 100 +
299118906Sume    (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
300222732Shrs    (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec)	* 100 +
30155163Sshin    (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
30255163Sshin
30355163Sshin#else
30455163Sshin# ifdef	_SEQUENT_
30555163Sshin    time_t t =
30655163Sshin    (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec)	* 100 +
307118906Sume    (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 +
308118906Sume    (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec)	* 100 +
309118906Sume    (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000;
310118906Sume
311118660Sume# else /* _SEQUENT_ */
312118664Sume#  ifndef POSIX
313118664Sume    time_t t =	(es->tms_utime - bs->tms_utime +
314225520Shrs			 es->tms_stime - bs->tms_stime)	* 100 /	HZ;
315118664Sume
31655163Sshin#  else	/* POSIX */
31755163Sshin    clock_t t = (es->tms_utime	- bs->tms_utime	+
31855163Sshin			  es->tms_stime	- bs->tms_stime) * 100 / clk_tck;
31955163Sshin
320118906Sume#  endif /* POSIX */
321118664Sume# endif	/* _SEQUENT_ */
322118664Sume#endif /* BSDTIMES */
323225520Shrs
324118664Sume    const char *cp;
32555163Sshin    long i;
32655163Sshin    struct varent *vp = adrof(STRtime);
32755163Sshin
32855163Sshin#ifdef BSDTIMES
329118906Sume# ifdef	convex
330118664Sume    static struct system_information sysinfo;
331118664Sume    long long memtmp;	/* let memory calculations exceede 2Gb */
332118664Sume# endif	/* convex */
333225520Shrs    int	    ms = (int)
334118664Sume    ((e->tv_sec	- b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
33555163Sshin
33655163Sshin    cp = "%Uu %Ss %E %P	%X+%Dk %I+%Oio %Fpf+%Ww";
33755163Sshin#else /* !BSDTIMES */
33855163Sshin# ifdef	_SEQUENT_
339118906Sume    int	    ms = (int)
340118664Sume    ((e->tv_sec	- b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
341118664Sume
342225520Shrs    cp = "%Uu %Ss %E %P	%I+%Oio	%Fpf+%Ww";
343118664Sume# else /* !_SEQUENT_ */
34455163Sshin#  ifndef POSIX
34555163Sshin    time_t ms = ((time_t)((e - b) / HZ) * 100) +
34655163Sshin		 (time_t)(((e - b) % HZ) * 100) / HZ;
34755163Sshin#  else	/* POSIX */
34855163Sshin    clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) +
34955163Sshin		  (clock_t)(((e - b) % clk_tck) * 100) / clk_tck;
350118906Sume#  endif /* POSIX */
351118664Sume
352118664Sume    cp = "%Uu %Ss %E %P";
353225520Shrs
354118664Sume    /*
35555163Sshin     * the tms stuff is	not very precise, so we	fudge it.
35655163Sshin     * granularity fix:	can't be more than 100%
35755163Sshin     * this breaks in multi-processor systems...
358118660Sume     * maybe I should take it out and let people see more then 100%
359118664Sume     * utilizations.
360225520Shrs     */
361118664Sume#  if 0
36255163Sshin    if (ms < t && ms !=	0)
363118661Sume	ms = t;
364118661Sume#  endif
365118661Sume# endif	/*! _SEQUENT_ */
366118661Sume#endif /* !BSDTIMES */
367118661Sume#ifdef TDEBUG
368118661Sume    xprintf("es->tms_utime %lu bs->tms_utime %lu\n",
369118661Sume	    es->tms_utime, bs->tms_utime);
370118661Sume    xprintf("es->tms_stime %lu bs->tms_stime %lu\n",
371118661Sume	    es->tms_stime, bs->tms_stime);
372118661Sume    xprintf("ms	%lu e %lu b %lu\n", ms,	e, b);
373118661Sume    xprintf("t %lu\n", t);
374118661Sume#endif /* TDEBUG */
375118661Sume
376118661Sume    if (vp && vp->vec && vp->vec[0] && vp->vec[1])
377222732Shrs	cp = short2str(vp->vec[1]);
378118661Sume    for	(; *cp;	cp++)
379253970Shrs	if (*cp	!= '%')
380222861Shrs	    xputchar(*cp);
381222861Shrs	else if	(cp[1])
382222861Shrs	    switch (*++cp) {
383222861Shrs
384222861Shrs	    case 'U':		/* user	CPU time used */
385222861Shrs#ifdef BSDTIMES
386225520Shrs		pdeltat(&r1->ru_utime, &r0->ru_utime);
387225520Shrs#else
388222861Shrs# ifdef	_SEQUENT_
389222861Shrs		pdeltat(&r1->ps_utime, &r0->ps_utime);
390222861Shrs# else /* _SEQUENT_ */
391222861Shrs#  ifndef POSIX
392222732Shrs		pdtimet(es->tms_utime, bs->tms_utime);
393222732Shrs#  else	/* POSIX */
394222732Shrs		pdtimet(es->tms_utime, bs->tms_utime);
395222732Shrs#  endif /* POSIX */
396222732Shrs# endif	/* _SEQUENT_ */
397222732Shrs#endif /* BSDTIMES */
398222732Shrs		break;
399222732Shrs
400222732Shrs	    case 'S':		/* system CPU time used	*/
401222732Shrs#ifdef BSDTIMES
402222732Shrs		pdeltat(&r1->ru_stime, &r0->ru_stime);
403222732Shrs#else
404222732Shrs# ifdef	_SEQUENT_
405222732Shrs		pdeltat(&r1->ps_stime, &r0->ps_stime);
406222732Shrs# else /* _SEQUENT_ */
407222732Shrs#  ifndef POSIX
408222732Shrs		pdtimet(es->tms_stime, bs->tms_stime);
409222732Shrs#  else	/* POSIX */
410222732Shrs		pdtimet(es->tms_stime, bs->tms_stime);
411222732Shrs#  endif /* POSIX */
412222732Shrs# endif	/* _SEQUENT_ */
413222732Shrs#endif /* BSDTIMES */
414222732Shrs		break;
415222732Shrs
416225520Shrs	    case 'E':		/* elapsed (wall-clock)	time */
417222732Shrs#ifdef BSDTIMES
418222732Shrs		pcsecs((long) ms);
419222732Shrs#else /* BSDTIMES */
420254462Shrs		pcsecs(ms);
421222732Shrs#endif /* BSDTIMES */
422222732Shrs		break;
423225520Shrs
424222732Shrs	    case 'P':		/* percent time	spent running */
425222732Shrs		/* check if the	process	did not	run */
426222732Shrs#ifdef convex
427222732Shrs		/*
428225520Shrs		 * scale the cpu %- ages by the	number of processors
429222732Shrs		 * available on	this machine
430222732Shrs		 */
431222732Shrs		if ((sysinfo.cpu_count == 0) &&
432222732Shrs		    (getsysinfo(SYSINFO_SIZE, &sysinfo)	< 0))
433222732Shrs		    sysinfo.cpu_count =	1;
434222732Shrs		    i =	(ms == 0) ? 0 :	(t * 1000.0 / (ms * sysinfo.cpu_count));
435222732Shrs#else /* convex	*/
436222732Shrs		i = (ms	== 0) ?	0 : (long)(t * 1000.0 / ms);
437222732Shrs#endif /* convex */
438222732Shrs		xprintf("%ld.%01ld%%", i / 10, i % 10);	/* nn.n% */
439222732Shrs		break;
440222732Shrs
441222732Shrs#ifdef BSDTIMES
442222732Shrs	    case 'W':		/* number of swaps */
443222732Shrs#ifdef _OSD_POSIX
444222732Shrs		i = 0;
445222732Shrs#else
446222732Shrs		i = r1->ru_nswap - r0->ru_nswap;
447222732Shrs#endif
448222732Shrs		xprintf("%ld", i);
449222732Shrs		break;
450222732Shrs
451222861Shrs#ifdef convex
452222861Shrs	    case 'X':		/* (average) shared text size */
453222861Shrs		memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss -
454222861Shrs				 (long long)r0->ru_ixrss) /
455222861Shrs			 (long long)t);
456222861Shrs		xprintf("%lu", (unsigned long)memtmp);
457222861Shrs		break;
458222861Shrs
459222861Shrs	    case 'D':		/* (average) unshared data size	*/
460222861Shrs		memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss +
461222861Shrs				 (long long)r1->ru_isrss -
462222861Shrs				 ((long	long)r0->ru_idrss +
463222861Shrs				  (long	long)r0->ru_isrss)) /
464222861Shrs			 (long long)t);
465222861Shrs		xprintf("%lu", (unsigned long)memtmp);
466222861Shrs		break;
467222861Shrs
468222732Shrs	    case 'K':		/* (average) total data	memory used  */
469222732Shrs		memtmp = (t == 0 ? 0LL : IADJUST(((long	long)r1->ru_ixrss +
470222861Shrs				  (long	long)r1->ru_isrss +
471222861Shrs				  (long	long)r1->ru_idrss) -
472222732Shrs				  ((long long)r0->ru_ixrss +
473222861Shrs				   (long long)r0->ru_idrss +
474222861Shrs				   (long long)r0->ru_isrss)) /
475253970Shrs			 (long long)t);
476222732Shrs		xprintf("%lu", (unsigned long)memtmp);
477222861Shrs		break;
478222861Shrs#else /* !convex */
479222861Shrs	    case 'X':		/* (average) shared text size */
480222732Shrs#ifdef _OSD_POSIX
481222732Shrs		xprintf("0",0);
482222732Shrs#else
483222732Shrs		xprintf("%ld", t == 0 ?	0L :
484222732Shrs			IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t);
485222732Shrs#endif
486222732Shrs		break;
487222732Shrs
488222732Shrs	    case 'D':		/* (average) unshared data size	*/
489222732Shrs#ifdef _OSD_POSIX
490222732Shrs		xprintf("0",0);
491222732Shrs#else
492225520Shrs		xprintf("%ld", t == 0 ?	0L :
493222732Shrs			IADJUST(r1->ru_idrss + r1->ru_isrss -
494222732Shrs				(r0->ru_idrss +	r0->ru_isrss)) / t);
495222732Shrs#endif
496222732Shrs		break;
497222732Shrs
498222732Shrs	    case 'K':		/* (average) total data	memory used  */
499222732Shrs#ifdef _OSD_POSIX
500222732Shrs		xprintf("0",0);
501222732Shrs#else
502222732Shrs		xprintf("%ld", t == 0 ?	0L :
503222732Shrs			IADJUST((r1->ru_ixrss +	r1->ru_isrss + r1->ru_idrss) -
504222732Shrs			   (r0->ru_ixrss + r0->ru_idrss	+ r0->ru_isrss)) / t);
505222732Shrs#endif
506222732Shrs		break;
507222732Shrs#endif /* convex */
508222732Shrs	    case 'M':		/* max.	Resident Set Size */
509222732Shrs#ifdef SUNOS4
510222861Shrs		xprintf("%ld", pagetok(r1->ru_maxrss));
511222861Shrs#else
512222861Shrs# ifdef	convex
513222861Shrs		xprintf("%ld", r1->ru_maxrss * 4L);
514222861Shrs# else /* !convex */
515222861Shrs#  ifdef _OSD_POSIX
516222861Shrs		xprintf("0",0);
517222861Shrs#  else
518222861Shrs		xprintf("%ld", r1->ru_maxrss / 2L);
519222861Shrs#  endif
520222861Shrs# endif	/* convex */
521222861Shrs#endif /* SUNOS4 */
522222861Shrs		break;
523222861Shrs
524222861Shrs	    case 'F':		/* page	faults */
525222861Shrs#ifdef _OSD_POSIX
526222861Shrs		xprintf("0",0);
527222732Shrs#else
528222732Shrs		xprintf("%ld", r1->ru_majflt - r0->ru_majflt);
529222861Shrs#endif
530222861Shrs		break;
531222732Shrs
532222861Shrs	    case 'R':		/* page	reclaims */
533222861Shrs#ifdef _OSD_POSIX
534253970Shrs		xprintf("0",0);
535222732Shrs#else
536222861Shrs		xprintf("%ld", r1->ru_minflt - r0->ru_minflt);
537222861Shrs#endif
538222861Shrs		break;
539222732Shrs
540222732Shrs	    case 'I':		/* FS blocks in	*/
541222732Shrs#ifdef _OSD_POSIX
542222732Shrs		xprintf("0",0);
543222732Shrs#else
544222732Shrs		xprintf("%ld", r1->ru_inblock -	r0->ru_inblock);
545222732Shrs#endif
546222732Shrs		break;
547222732Shrs
548222861Shrs	    case 'O':		/* FS blocks out */
549222861Shrs#ifdef _OSD_POSIX
550222861Shrs		xprintf("0",0);
551222732Shrs#else
55255163Sshin		xprintf("%ld", r1->ru_oublock -	r0->ru_oublock);
55355163Sshin#endif
554118664Sume		break;
555118664Sume
556118664Sume# ifdef	convex
557118664Sume	    case 'C':			/*  CPU	parallelization	factor */
558118664Sume		if (r1->ru_usamples	!= 0LL)	{
559118664Sume		    long long parr = ((r1->ru_utotal * 100LL) /
560118664Sume				      r1->ru_usamples);
561118664Sume		    xprintf("%d.%02d", (int)(parr/100), (int)(parr%100));
562118664Sume		} else
56355163Sshin		    xprintf("?");
56455163Sshin		break;
565118661Sume# endif	/* convex */
566222732Shrs	    case 'r':		/* PWP:	socket messages	recieved */
567222732Shrs#ifdef _OSD_POSIX
568222732Shrs		xprintf("0",0);
569222732Shrs#else
570222732Shrs		xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv);
571222732Shrs#endif
572222732Shrs		break;
573222732Shrs
574222732Shrs	    case 's':		/* PWP:	socket messages	sent */
575222861Shrs#ifdef _OSD_POSIX
576222732Shrs		xprintf("0",0);
577253970Shrs#else
578225520Shrs		xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd);
579225520Shrs#endif
580225520Shrs		break;
581225520Shrs
582225520Shrs	    case 'k':		/* PWP:	signals	received */
583222732Shrs#ifdef _OSD_POSIX
584222732Shrs		xprintf("0",0);
585222732Shrs#else
586222732Shrs		xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals);
587253970Shrs#endif
588222732Shrs		break;
589222861Shrs
590222861Shrs	    case 'w':		/* PWP:	voluntary context switches (waits) */
591222861Shrs#ifdef _OSD_POSIX
592222861Shrs		xprintf("0",0);
593222861Shrs#else
594222861Shrs		xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw);
595222861Shrs#endif
596222861Shrs		break;
597222861Shrs
598253970Shrs	    case 'c':		/* PWP:	involuntary context switches */
599222861Shrs#ifdef _OSD_POSIX
600222861Shrs		xprintf("0",0);
601222861Shrs#else
602222861Shrs		xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw);
603222861Shrs#endif
604222861Shrs		break;
605222861Shrs#else /* BSDTIMES */
606222861Shrs# ifdef	_SEQUENT_
607222861Shrs	    case 'W':		/* number of swaps */
608222861Shrs		i = r1->ps_swap	- r0->ps_swap;
609222861Shrs		xprintf("%ld", i);
610222861Shrs		break;
611222861Shrs
612222861Shrs	    case 'M':
613222861Shrs		xprintf("%ld", r1->ps_maxrss / 2);
614222861Shrs		break;
615222861Shrs
616222861Shrs	    case 'F':
617222861Shrs		xprintf("%ld", r1->ps_pagein - r0->ps_pagein);
618222732Shrs		break;
619222861Shrs
620253970Shrs	    case 'R':
621222861Shrs		xprintf("%ld", r1->ps_reclaim -	r0->ps_reclaim);
622222861Shrs		break;
623222861Shrs
624222861Shrs	    case 'I':
625222861Shrs		xprintf("%ld", r1->ps_bread - r0->ps_bread);
626222861Shrs		break;
627222861Shrs
628222861Shrs	    case 'O':
629222861Shrs		xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite);
630222861Shrs		break;
631222861Shrs
632222861Shrs	    case 'k':
633222861Shrs		xprintf("%ld", r1->ps_signal - r0->ps_signal);
634222861Shrs		break;
635222861Shrs
636222861Shrs	    case 'w':
637222861Shrs		xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw);
638222861Shrs		break;
639222861Shrs
640222861Shrs	    case 'c':
641222861Shrs		xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw);
642222861Shrs		break;
643222861Shrs
644222861Shrs	    case 'Z':
645222861Shrs		xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill);
646222861Shrs		break;
647222861Shrs
648222861Shrs	    case 'i':
649222861Shrs		xprintf("%ld", r1->ps_pffincr -	r0->ps_pffincr);
650222861Shrs		break;
651222861Shrs
652222861Shrs	    case 'd':
653222861Shrs		xprintf("%ld", r1->ps_pffdecr -	r0->ps_pffdecr);
654222861Shrs		break;
655222861Shrs
656222861Shrs	    case 'Y':
657222732Shrs		xprintf("%ld", r1->ps_syscall -	r0->ps_syscall);
658222861Shrs		break;
659222861Shrs
660222861Shrs	    case 'l':
661222732Shrs		xprintf("%ld", r1->ps_lread - r0->ps_lread);
662222732Shrs		break;
663222861Shrs
664222732Shrs	    case 'm':
665222861Shrs		xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite);
666222732Shrs		break;
667222861Shrs
668222861Shrs	    case 'p':
669225520Shrs		xprintf("%ld", r1->ps_phread - r0->ps_phread);
670225520Shrs		break;
671225520Shrs
672225520Shrs	    case 'q':
673222732Shrs		xprintf("%ld", r1->ps_phwrite -	r0->ps_phwrite);
674225520Shrs		break;
675225520Shrs# endif	/* _SEQUENT_ */
676225520Shrs#endif /* BSDTIMES */
677225520Shrs	    default:
678225520Shrs		break;
679225520Shrs	    }
680225520Shrs    xputchar('\n');
681225520Shrs}
682225520Shrs
683225520Shrs#if defined(BSDTIMES) || defined(_SEQUENT_)
684225520Shrsstatic void
685225520Shrspdeltat(timeval_t *t1, timeval_t *t0)
686225520Shrs{
687225520Shrs    timeval_t td;
688225520Shrs
689225520Shrs    tvsub(&td, t1, t0);
690225520Shrs    xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L);
691225520Shrs}
692225520Shrs
693225520Shrsstatic void
694225520Shrstvadd(timeval_t *tsum, timeval_t *t0)
695225520Shrs{
696225520Shrs
697225520Shrs    tsum->tv_sec += t0->tv_sec;
698225520Shrs    tsum->tv_usec += t0->tv_usec;
699225520Shrs    if (tsum->tv_usec >= 1000000)
700225520Shrs	tsum->tv_sec++,	tsum->tv_usec -= 1000000;
701225520Shrs}
702225520Shrs
703225520Shrsvoid
704225520Shrstvsub(timeval_t *tdiff, timeval_t *t1, timeval_t *t0)
705225520Shrs{
706225520Shrs
707225520Shrs    tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
708225520Shrs    tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
709225520Shrs    if (tdiff->tv_usec < 0)
710225520Shrs	tdiff->tv_sec--, tdiff->tv_usec	+= 1000000;
711225520Shrs}
712222732Shrs
713225520Shrs#else /* !BSDTIMES && !_SEQUENT_ */
714225520Shrsstatic void
715222732Shrs#ifndef	POSIX
716225520Shrspdtimet(time_t eval, time_t bval)
717222732Shrs
718225520Shrs#else /* POSIX */
719222732Shrspdtimet(clock_t eval, clock_t bval)
720225520Shrs
721225520Shrs#endif /* POSIX	*/
722225520Shrs{
723225520Shrs#ifndef	POSIX
724225520Shrs    time_t  val;
725225520Shrs
726225520Shrs#else /* POSIX */
727225520Shrs    clock_t val;
728225520Shrs
729225520Shrs#endif /* POSIX	*/
730225520Shrs
731225520Shrs#ifndef	POSIX
732222861Shrs    val	= (eval	- bval)	* 100 /	HZ;
733222861Shrs#else /* POSIX */
734222732Shrs    val	= (eval	- bval)	* 100 /	clk_tck;
735222861Shrs#endif /* POSIX	*/
736222861Shrs
737222861Shrs    xprintf("%ld.%02ld", val / 100, val	- (val / 100 * 100));
738222732Shrs}
739225520Shrs#endif /* BSDTIMES || _SEQUENT_	*/
740222732Shrs