sh.time.c revision 59415
1250963Sachim/* $Header: /src/pub/tcsh/sh.time.c,v 3.21 2000/01/14 22:57:29 christos Exp $ */
2250963Sachim/*
3250963Sachim * sh.time.c: Shell time keeping and printing.
4250963Sachim */
5250963Sachim/*-
6250963Sachim * Copyright (c) 1980, 1991 The	Regents	of the University of California.
7250963Sachim * All rights reserved.
8250963Sachim *
9250963Sachim * Redistribution and use in source and	binary forms, with or without
10250963Sachim * modification, are permitted provided	that the following conditions
11250963Sachim * are met:
12250963Sachim * 1. Redistributions of source	code must retain the above copyright
13250963Sachim *    notice, this list	of conditions and the following	disclaimer.
14250963Sachim * 2. Redistributions in binary	form must reproduce the	above copyright
15250963Sachim *    notice, this list	of conditions and the following	disclaimer in the
16250963Sachim *    documentation and/or other materials provided with the distribution.
17250963Sachim * 3. All advertising materials	mentioning features or use of this software
18250963Sachim *    must display the following acknowledgement:
19250963Sachim *	This product includes software developed by the	University of
20250963Sachim *	California, Berkeley and its contributors.
21250963Sachim * 4. Neither the name of the University nor the names of its contributors
22250963Sachim *    may be used to endorse or	promote	products derived from this software
23250963Sachim *    without specific prior written permission.
24250963Sachim *
25250963Sachim * THIS	SOFTWARE IS PROVIDED BY	THE REGENTS AND	CONTRIBUTORS ``AS IS'' AND
26250963Sachim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27250963Sachim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28250963Sachim * ARE DISCLAIMED.  IN NO EVENT	SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29250963Sachim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR	CONSEQUENTIAL
30250963Sachim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31250963Sachim * OR SERVICES;	LOSS OF	USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32250963Sachim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33250963Sachim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34250963Sachim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35250963Sachim * SUCH	DAMAGE.
36250963Sachim */
37250963Sachim#include "sh.h"
38250963Sachim
39250963SachimRCSID("$Id: sh.time.c,v 3.21 2000/01/14 22:57:29 christos Exp $")
40250963Sachim
41250963Sachim#ifdef SUNOS4
42250963Sachim# include <machine/param.h>
43250963Sachim#endif /* SUNOS4 */
44250963Sachim
45250963Sachim/*
46250963Sachim * C Shell - routines handling process timing and niceing
47250963Sachim */
48250963Sachim#ifdef BSDTIMES
49250963Sachim# ifndef RUSAGE_SELF
50250963Sachim#  define	RUSAGE_SELF	0
51250963Sachim#  define	RUSAGE_CHILDREN	-1
52250963Sachim# endif	/* RUSAGE_SELF */
53250963Sachim#else /* BSDTIMES */
54250963Sachimstruct tms times0;
55250963Sachim#endif /* BSDTIMES */
56250963Sachim
57250963Sachim#if !defined(BSDTIMES) && !defined(_SEQUENT_)
58250963Sachim# ifdef	POSIX
59250963Sachimstatic	void	pdtimet	__P((clock_t, clock_t));
60250963Sachim# else /* ! POSIX */
61250963Sachimstatic	void	pdtimet	__P((time_t, time_t));
62250963Sachim# endif	/* ! POSIX */
63250963Sachim#else /* BSDTIMES || _SEQUENT_ */
64250963Sachimstatic	void	tvadd	__P((timeval_t *, timeval_t *));
65250963Sachimstatic	void	pdeltat	__P((timeval_t *, timeval_t *));
66250963Sachim#endif /* BSDTIMES || _SEQUENT_	*/
67250963Sachim
68250963Sachimvoid
69250963Sachimsettimes()
70250963Sachim{
71250963Sachim#ifdef BSDTIMES
72250963Sachim    struct sysrusage ruch;
73250963Sachim#ifdef convex
74250963Sachim    memset(&ru0, 0, sizeof(ru0));
75250963Sachim    memset(&ruch, 0, sizeof(ruch));
76250963Sachim#endif /* convex */
77250963Sachim
78250963Sachim    (void) gettimeofday(&time0,	NULL);
79250963Sachim    (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0);
80250963Sachim    (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
81250963Sachim    ruadd(&ru0,	&ruch);
82250963Sachim#else
83250963Sachim# ifdef	_SEQUENT_
84250963Sachim    struct process_stats ruch;
85250963Sachim
86250963Sachim    (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch);
87250963Sachim    ruadd(&ru0,	&ruch);
88250963Sachim# else	/* _SEQUENT_ */
89250963Sachim    seconds0 = time(NULL);
90250963Sachim#  ifndef COHERENT
91250963Sachim    time0 = times(&times0);
92250963Sachim#  else	/* !COHERENT */
93250963Sachim    time0 = HZ * seconds0;
94250963Sachim    times(&times0);
95250963Sachim#  endif /* !COHERENT */
96250963Sachim    times0.tms_stime +=	times0.tms_cstime;
97250963Sachim    times0.tms_utime +=	times0.tms_cutime;
98250963Sachim    times0.tms_cstime =	0;
99250963Sachim    times0.tms_cutime =	0;
100250963Sachim# endif	/* _SEQUENT_ */
101263024Sachim#endif /* BSDTIMES */
102250963Sachim}
103263024Sachim
104250963Sachim/*
105263024Sachim * dotime is only called if it is truly	a builtin function and not a
106250963Sachim * prefix to another command
107250963Sachim */
108250963Sachim/*ARGSUSED*/
109250963Sachimvoid
110250963Sachimdotime(v, c)
111250963Sachim    Char **v;
112250963Sachim    struct command *c;
113250963Sachim{
114250963Sachim#ifdef BSDTIMES
115250963Sachim    timeval_t timedol;
116263024Sachim    struct sysrusage ru1, ruch;
117250963Sachim#ifdef convex
118250963Sachim    memset(&ru1, 0, sizeof(ru1));
119250963Sachim    memset(&ruch, 0, sizeof(ruch));
120250963Sachim#endif /* convex */
121250963Sachim
122250963Sachim    (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1);
123250963Sachim    (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
124250963Sachim    ruadd(&ru1,	&ruch);
125250963Sachim    (void) gettimeofday(&timedol, NULL);
126250963Sachim    prusage(&ru0, &ru1,	&timedol, &time0);
127250963Sachim#else
128263024Sachim# ifdef	_SEQUENT_
129250963Sachim    timeval_t timedol;
130250963Sachim    struct process_stats ru1, ruch;
131250963Sachim
132250963Sachim    (void) get_process_stats(&timedol, PS_SELF,	&ru1, &ruch);
133250963Sachim    ruadd(&ru1,	&ruch);
134250963Sachim    prusage(&ru0, &ru1,	&timedol, &time0);
135250963Sachim# else /* _SEQUENT_ */
136250963Sachim#  ifndef POSIX
137250963Sachim    time_t  timedol;
138250963Sachim#  else	/* POSIX */
139250963Sachim    clock_t timedol;
140250963Sachim#  endif /* POSIX */
141250963Sachim
142250963Sachim    struct tms times_dol;
143250963Sachim
144250963Sachim#ifndef	COHERENT
145250963Sachim    timedol = times(&times_dol);
146250963Sachim#else
147263024Sachim    timedol = HZ * time(NULL);
148250963Sachim    times(&times_dol);
149250963Sachim#endif
150250963Sachim    times_dol.tms_stime	+= times_dol.tms_cstime;
151250963Sachim    times_dol.tms_utime	+= times_dol.tms_cutime;
152250963Sachim    times_dol.tms_cstime = 0;
153250963Sachim    times_dol.tms_cutime = 0;
154250963Sachim    prusage(&times0, &times_dol, timedol, time0);
155250963Sachim# endif	/* _SEQUENT_ */
156250963Sachim#endif /* BSDTIMES */
157250963Sachim    USE(c);
158250963Sachim    USE(v);
159250963Sachim}
160250963Sachim
161250963Sachim/*
162250963Sachim * donice is only called when it on the	line by	itself or with a +- value
163250963Sachim */
164250963Sachim/*ARGSUSED*/
165250963Sachimvoid
166250963Sachimdonice(v, c)
167250963Sachim    register Char **v;
168250963Sachim    struct command *c;
169250963Sachim{
170250963Sachim    register Char *cp;
171250963Sachim    int	    nval = 0;
172250963Sachim
173250963Sachim    USE(c);
174250963Sachim    v++, cp = *v++;
175250963Sachim    if (cp == 0)
176250963Sachim	nval = 4;
177250963Sachim    else if (*v	== 0 &&	any("+-", cp[0]))
178250963Sachim	nval = getn(cp);
179250963Sachim#ifdef BSDNICE
180250963Sachim    (void) setpriority(PRIO_PROCESS, 0,	nval);
181250963Sachim#else /* BSDNICE */
182250963Sachim    (void) nice(nval);
183250963Sachim#endif /* BSDNICE */
184250963Sachim}
185250963Sachim
186250963Sachim#ifdef BSDTIMES
187250963Sachimvoid
188250963Sachimruadd(ru, ru2)
189250963Sachim    register struct sysrusage *ru,	*ru2;
190250963Sachim{
191250963Sachim    tvadd(&ru->ru_utime, &ru2->ru_utime);
192250963Sachim    tvadd(&ru->ru_stime, &ru2->ru_stime);
193250963Sachim    if (ru2->ru_maxrss > ru->ru_maxrss)
194250963Sachim	ru->ru_maxrss =	ru2->ru_maxrss;
195250963Sachim
196250963Sachim    ru->ru_ixrss += ru2->ru_ixrss;
197250963Sachim    ru->ru_idrss += ru2->ru_idrss;
198250963Sachim    ru->ru_isrss += ru2->ru_isrss;
199250963Sachim    ru->ru_minflt += ru2->ru_minflt;
200250963Sachim    ru->ru_majflt += ru2->ru_majflt;
201250963Sachim    ru->ru_nswap += ru2->ru_nswap;
202250963Sachim    ru->ru_inblock += ru2->ru_inblock;
203250963Sachim    ru->ru_oublock += ru2->ru_oublock;
204250963Sachim    ru->ru_msgsnd += ru2->ru_msgsnd;
205250963Sachim    ru->ru_msgrcv += ru2->ru_msgrcv;
206250963Sachim    ru->ru_nsignals += ru2->ru_nsignals;
207250963Sachim    ru->ru_nvcsw += ru2->ru_nvcsw;
208250963Sachim    ru->ru_nivcsw += ru2->ru_nivcsw;
209250963Sachim
210250963Sachim# ifdef	convex
211250963Sachim    tvadd(&ru->ru_exutime, &ru2->ru_exutime);
212250963Sachim    ru->ru_utotal += ru2->ru_utotal;
213250963Sachim    ru->ru_usamples += ru2->ru_usamples;
214250963Sachim    ru->ru_stotal += ru2->ru_stotal;
215250963Sachim    ru->ru_ssamples += ru2->ru_ssamples;
216250963Sachim# endif	/* convex */
217250963Sachim}
218250963Sachim
219250963Sachim#else /* BSDTIMES */
220250963Sachim# ifdef	_SEQUENT_
221250963Sachimvoid
222250963Sachimruadd(ru, ru2)
223250963Sachim    register struct process_stats *ru, *ru2;
224250963Sachim{
225250963Sachim    tvadd(&ru->ps_utime, &ru2->ps_utime);
226250963Sachim    tvadd(&ru->ps_stime, &ru2->ps_stime);
227250963Sachim    if (ru2->ps_maxrss > ru->ps_maxrss)
228250963Sachim	ru->ps_maxrss =	ru2->ps_maxrss;
229250963Sachim
230250963Sachim    ru->ps_pagein += ru2->ps_pagein;
231250963Sachim    ru->ps_reclaim += ru2->ps_reclaim;
232250963Sachim    ru->ps_zerofill += ru2->ps_zerofill;
233250963Sachim    ru->ps_pffincr += ru2->ps_pffincr;
234250963Sachim    ru->ps_pffdecr += ru2->ps_pffdecr;
235250963Sachim    ru->ps_swap	+= ru2->ps_swap;
236250963Sachim    ru->ps_syscall += ru2->ps_syscall;
237250963Sachim    ru->ps_volcsw += ru2->ps_volcsw;
238250963Sachim    ru->ps_involcsw += ru2->ps_involcsw;
239250963Sachim    ru->ps_signal += ru2->ps_signal;
240250963Sachim    ru->ps_lread += ru2->ps_lread;
241250963Sachim    ru->ps_lwrite += ru2->ps_lwrite;
242250963Sachim    ru->ps_bread += ru2->ps_bread;
243250963Sachim    ru->ps_bwrite += ru2->ps_bwrite;
244250963Sachim    ru->ps_phread += ru2->ps_phread;
245250963Sachim    ru->ps_phwrite += ru2->ps_phwrite;
246250963Sachim}
247250963Sachim
248250963Sachim# endif	/* _SEQUENT_ */
249250963Sachim#endif /* BSDTIMES */
250250963Sachim
251250963Sachim#ifdef BSDTIMES
252250963Sachim
253250963Sachim/*
254250963Sachim * PWP:	the LOG1024 and	pagetok	stuff taken from the top command,
255250963Sachim * written by William LeFebvre
256250963Sachim */
257250963Sachim/* Log base 2 of 1024 is 10 (2^10 == 1024) */
258250963Sachim#define	LOG1024		10
259250963Sachim
260250963Sachim/* Convert clicks (kernel pages) to kbytes ... */
261250963Sachim/* If there is no PGSHIFT defined, assume it is	11 */
262250963Sachim/* Is this needed for compatability with some old flavor of 4.2	or 4.1?	*/
263250963Sachim#ifdef SUNOS4
264263024Sachim# ifndef PGSHIFT
265250963Sachim#  define pagetok(size)	  ((size) << 1)
266250963Sachim# else
267250963Sachim#  if PGSHIFT>10
268250963Sachim#   define pagetok(size)   ((size) << (PGSHIFT - LOG1024))
269250963Sachim#  else
270250963Sachim#   define pagetok(size)   ((size) >> (LOG1024 - PGSHIFT))
271250963Sachim#  endif
272250963Sachim# endif
273250963Sachim#endif
274250963Sachim
275250963Sachim/*
276250963Sachim * if any other	machines return	wierd values in	the ru_i* stuff, put
277250963Sachim * the adjusting macro here:
278250963Sachim */
279250963Sachim#ifdef SUNOS4
280250963Sachim# define IADJUST(i)	(pagetok(i)/2)
281250963Sachim#else /* SUNOS4	*/
282250963Sachim# ifdef	convex
283250963Sachim   /*
284250963Sachim    * convex has megabytes * CLK_TCK
285263024Sachim    * multiply by 100 since we use time	in 100ths of a second in prusage
286250963Sachim    */
287250963Sachim#  define IADJUST(i) (((i) << 10) / CLK_TCK * 100)
288250963Sachim# else /* convex */
289250963Sachim#  define IADJUST(i)	(i)
290250963Sachim# endif	/* convex */
291250963Sachim#endif /* SUNOS4 */
292250963Sachim
293250963Sachimvoid
294250963Sachimprusage(r0, r1,	e, b)
295250963Sachim    register struct sysrusage *r0,	*r1;
296250963Sachim    timeval_t *e, *b;
297250963Sachim
298250963Sachim#else /* BSDTIMES */
299250963Sachim# ifdef	_SEQUENT_
300250963Sachimvoid
301250963Sachimprusage(r0, r1,	e, b)
302250963Sachim    register struct process_stats *r0, *r1;
303250963Sachim    timeval_t *e, *b;
304250963Sachim
305250963Sachim# else /* _SEQUENT_ */
306250963Sachimvoid
307250963Sachimprusage(bs, es,	e, b)
308250963Sachim    struct tms *bs, *es;
309250963Sachim
310250963Sachim#  ifndef POSIX
311250963Sachim    time_t  e, b;
312250963Sachim
313250963Sachim#  else	/* POSIX */
314250963Sachim    clock_t e, b;
315250963Sachim
316250963Sachim#  endif /* POSIX */
317250963Sachim# endif	/* _SEQUENT_ */
318250963Sachim#endif /* BSDTIMES */
319250963Sachim{
320250963Sachim#ifdef BSDTIMES
321250963Sachim    register time_t t =
322250963Sachim    (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec)	* 100 +
323250963Sachim    (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
324250963Sachim    (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec)	* 100 +
325250963Sachim    (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
326250963Sachim
327250963Sachim#else
328250963Sachim# ifdef	_SEQUENT_
329250963Sachim    register time_t t =
330250963Sachim    (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec)	* 100 +
331250963Sachim    (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 +
332250963Sachim    (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec)	* 100 +
333250963Sachim    (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000;
334250963Sachim
335250963Sachim# else /* _SEQUENT_ */
336250963Sachim#  ifndef POSIX
337250963Sachim    register time_t t =	(es->tms_utime - bs->tms_utime +
338250963Sachim			 es->tms_stime - bs->tms_stime)	* 100 /	HZ;
339250963Sachim
340250963Sachim#  else	/* POSIX */
341250963Sachim    register clock_t t = (es->tms_utime	- bs->tms_utime	+
342250963Sachim			  es->tms_stime	- bs->tms_stime) * 100 / clk_tck;
343250963Sachim
344250963Sachim#  endif /* POSIX */
345250963Sachim# endif	/* _SEQUENT_ */
346250963Sachim#endif /* BSDTIMES */
347250963Sachim
348250963Sachim    register char *cp;
349263024Sachim    register long i;
350250963Sachim    register struct varent *vp = adrof(STRtime);
351250963Sachim
352250963Sachim#ifdef BSDTIMES
353250963Sachim# ifdef	convex
354250963Sachim    static struct system_information sysinfo;
355250963Sachim    long long memtmp;	/* let memory calculations exceede 2Gb */
356250963Sachim# endif	/* convex */
357250963Sachim    int	    ms = (int)
358250963Sachim    ((e->tv_sec	- b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
359250963Sachim
360250963Sachim    cp = "%Uu %Ss %E %P	%X+%Dk %I+%Oio %Fpf+%Ww";
361250963Sachim#else /* !BSDTIMES */
362250963Sachim# ifdef	_SEQUENT_
363250963Sachim    int	    ms = (int)
364250963Sachim    ((e->tv_sec	- b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
365250963Sachim
366250963Sachim    cp = "%Uu %Ss %E %P	%I+%Oio	%Fpf+%Ww";
367250963Sachim# else /* !_SEQUENT_ */
368250963Sachim#  ifndef POSIX
369250963Sachim    time_t ms = ((time_t)((e - b) / HZ) * 100) +
370250963Sachim		 (time_t)(((e - b) % HZ) * 100) / HZ;
371250963Sachim#  else	/* POSIX */
372250963Sachim    clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) +
373250963Sachim		  (clock_t)(((e - b) % clk_tck) * 100) / clk_tck;
374250963Sachim#  endif /* POSIX */
375250963Sachim
376250963Sachim    cp = "%Uu %Ss %E %P";
377250963Sachim
378250963Sachim    /*
379250963Sachim     * the tms stuff is	not very precise, so we	fudge it.
380250963Sachim     * granularity fix:	can't be more than 100%
381250963Sachim     * this breaks in multi-processor systems...
382250963Sachim     * maybe I should take it out and let people see more then 100%
383250963Sachim     * utilizations.
384250963Sachim     */
385250963Sachim#  if 0
386250963Sachim    if (ms < t && ms !=	0)
387250963Sachim	ms = t;
388250963Sachim#  endif
389250963Sachim# endif	/*! _SEQUENT_ */
390250963Sachim#endif /* !BSDTIMES */
391250963Sachim#ifdef TDEBUG
392250963Sachim    xprintf("es->tms_utime %lu bs->tms_utime %lu\n",
393250963Sachim	    es->tms_utime, bs->tms_utime);
394250963Sachim    xprintf("es->tms_stime %lu bs->tms_stime %lu\n",
395250963Sachim	    es->tms_stime, bs->tms_stime);
396250963Sachim    xprintf("ms	%lu e %lu b %lu\n", ms,	e, b);
397250963Sachim    xprintf("t %lu\n", t);
398250963Sachim#endif /* TDEBUG */
399250963Sachim
400250963Sachim    if (vp && vp->vec[0] && vp->vec[1])
401250963Sachim	cp = short2str(vp->vec[1]);
402250963Sachim    for	(; *cp;	cp++)
403250963Sachim	if (*cp	!= '%')
404250963Sachim	    xputchar(*cp);
405250963Sachim	else if	(cp[1])
406250963Sachim	    switch (*++cp) {
407250963Sachim
408250963Sachim	    case 'U':		/* user	CPU time used */
409250963Sachim#ifdef BSDTIMES
410250963Sachim		pdeltat(&r1->ru_utime, &r0->ru_utime);
411250963Sachim#else
412250963Sachim# ifdef	_SEQUENT_
413250963Sachim		pdeltat(&r1->ps_utime, &r0->ps_utime);
414250963Sachim# else /* _SEQUENT_ */
415250963Sachim#  ifndef POSIX
416250963Sachim		pdtimet(es->tms_utime, bs->tms_utime);
417250963Sachim#  else	/* POSIX */
418250963Sachim		pdtimet(es->tms_utime, bs->tms_utime);
419250963Sachim#  endif /* POSIX */
420250963Sachim# endif	/* _SEQUENT_ */
421250963Sachim#endif /* BSDTIMES */
422250963Sachim		break;
423250963Sachim
424250963Sachim	    case 'S':		/* system CPU time used	*/
425250963Sachim#ifdef BSDTIMES
426250963Sachim		pdeltat(&r1->ru_stime, &r0->ru_stime);
427250963Sachim#else
428250963Sachim# ifdef	_SEQUENT_
429250963Sachim		pdeltat(&r1->ps_stime, &r0->ps_stime);
430250963Sachim# else /* _SEQUENT_ */
431250963Sachim#  ifndef POSIX
432250963Sachim		pdtimet(es->tms_stime, bs->tms_stime);
433250963Sachim#  else	/* POSIX */
434250963Sachim		pdtimet(es->tms_stime, bs->tms_stime);
435250963Sachim#  endif /* POSIX */
436250963Sachim# endif	/* _SEQUENT_ */
437250963Sachim#endif /* BSDTIMES */
438250963Sachim		break;
439250963Sachim
440250963Sachim	    case 'E':		/* elapsed (wall-clock)	time */
441250963Sachim#ifdef BSDTIMES
442250963Sachim		pcsecs((long) ms);
443250963Sachim#else /* BSDTIMES */
444250963Sachim		pcsecs(ms);
445250963Sachim#endif /* BSDTIMES */
446250963Sachim		break;
447250963Sachim
448250963Sachim	    case 'P':		/* percent time	spent running */
449250963Sachim		/* check if the	process	did not	run */
450263024Sachim#ifdef convex
451250963Sachim		/*
452250963Sachim		 * scale the cpu %- ages by the	number of processors
453250963Sachim		 * available on	this machine
454250963Sachim		 */
455250963Sachim		if ((sysinfo.cpu_count == 0) &&
456250963Sachim		    (getsysinfo(SYSINFO_SIZE, &sysinfo)	< 0))
457250963Sachim		    sysinfo.cpu_count =	1;
458250963Sachim		    i =	(ms == 0) ? 0 :	(t * 1000.0 / (ms * sysinfo.cpu_count));
459250963Sachim#else /* convex	*/
460250963Sachim		i = (ms	== 0) ?	0 : (t * 1000.0 / ms);
461250963Sachim#endif /* convex */
462250963Sachim		xprintf("%ld.%01ld%%", i / 10, i % 10);	/* nn.n% */
463250963Sachim		break;
464250963Sachim
465250963Sachim#ifdef BSDTIMES
466250963Sachim	    case 'W':		/* number of swaps */
467250963Sachim		i = r1->ru_nswap - r0->ru_nswap;
468250963Sachim		xprintf("%ld", i);
469250963Sachim		break;
470250963Sachim
471250963Sachim#ifdef convex
472250963Sachim	    case 'X':		/* (average) shared text size */
473250963Sachim		memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss -
474250963Sachim				 (long long)r0->ru_ixrss) /
475250963Sachim			 (long long)t);
476250963Sachim		xprintf("%lu", (unsigned long)memtmp);
477250963Sachim
478250963Sachim		break;
479250963Sachim
480250963Sachim	    case 'D':		/* (average) unshared data size	*/
481250963Sachim		memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss +
482250963Sachim				 (long long)r1->ru_isrss -
483250963Sachim				 ((long	long)r0->ru_idrss +
484250963Sachim				  (long	long)r0->ru_isrss)) /
485250963Sachim			 (long long)t);
486250963Sachim		xprintf("%lu", (unsigned long)memtmp);
487250963Sachim		break;
488250963Sachim
489250963Sachim	    case 'K':		/* (average) total data	memory used  */
490250963Sachim		memtmp = (t == 0 ? 0LL : IADJUST(((long	long)r1->ru_ixrss +
491250963Sachim				  (long	long)r1->ru_isrss +
492250963Sachim				  (long	long)r1->ru_idrss) -
493250963Sachim				  ((long long)r0->ru_ixrss +
494250963Sachim				   (long long)r0->ru_idrss +
495250963Sachim				   (long long)r0->ru_isrss)) /
496250963Sachim			 (long long)t);
497250963Sachim		xprintf("%lu", (unsigned long)memtmp);
498250963Sachim		break;
499250963Sachim#else /* !convex */
500250963Sachim	    case 'X':		/* (average) shared text size */
501250963Sachim		xprintf("%ld", t == 0 ?	0L :
502250963Sachim			IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t);
503250963Sachim		break;
504250963Sachim
505250963Sachim	    case 'D':		/* (average) unshared data size	*/
506250963Sachim		xprintf("%ld", t == 0 ?	0L :
507250963Sachim			IADJUST(r1->ru_idrss + r1->ru_isrss -
508263024Sachim				(r0->ru_idrss +	r0->ru_isrss)) / t);
509263024Sachim		break;
510263024Sachim
511263024Sachim	    case 'K':		/* (average) total data	memory used  */
512250963Sachim		xprintf("%ld", t == 0 ?	0L :
513250963Sachim			IADJUST((r1->ru_ixrss +	r1->ru_isrss + r1->ru_idrss) -
514250963Sachim			   (r0->ru_ixrss + r0->ru_idrss	+ r0->ru_isrss)) / t);
515250963Sachim		break;
516250963Sachim#endif /* convex */
517250963Sachim	    case 'M':		/* max.	Resident Set Size */
518250963Sachim#ifdef SUNOS4
519263024Sachim		xprintf("%ld", pagetok(r1->ru_maxrss));
520263024Sachim#else
521263024Sachim# ifdef	convex
522263024Sachim		xprintf("%ld", r1->ru_maxrss * 4L);
523250963Sachim# else /* !convex */
524250963Sachim		xprintf("%ld", r1->ru_maxrss / 2L);
525250963Sachim# endif	/* convex */
526250963Sachim#endif /* SUNOS4 */
527250963Sachim		break;
528250963Sachim
529250963Sachim	    case 'F':		/* page	faults */
530250963Sachim		xprintf("%ld", r1->ru_majflt - r0->ru_majflt);
531250963Sachim		break;
532250963Sachim
533250963Sachim	    case 'R':		/* page	reclaims */
534250963Sachim		xprintf("%ld", r1->ru_minflt - r0->ru_minflt);
535250963Sachim		break;
536250963Sachim
537250963Sachim	    case 'I':		/* FS blocks in	*/
538263024Sachim		xprintf("%ld", r1->ru_inblock -	r0->ru_inblock);
539263024Sachim		break;
540263024Sachim
541250963Sachim	    case 'O':		/* FS blocks out */
542250963Sachim		xprintf("%ld", r1->ru_oublock -	r0->ru_oublock);
543250963Sachim		break;
544250963Sachim
545250963Sachim# ifdef	convex
546250963Sachim	    case 'C':			/*  CPU	parallelization	factor */
547250963Sachim		if (r1->ru_usamples	!= 0LL)	{
548250963Sachim		    long long parr = ((r1->ru_utotal * 100LL) /
549250963Sachim				      r1->ru_usamples);
550250963Sachim		    xprintf("%d.%02d", (int)(parr/100), (int)(parr%100));
551250963Sachim		} else
552250963Sachim		    xprintf("?");
553250963Sachim		break;
554250963Sachim# endif	/* convex */
555250963Sachim	    case 'r':		/* PWP:	socket messages	recieved */
556250963Sachim		xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv);
557250963Sachim		break;
558250963Sachim
559250963Sachim	    case 's':		/* PWP:	socket messages	sent */
560250963Sachim		xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd);
561250963Sachim		break;
562250963Sachim
563250963Sachim	    case 'k':		/* PWP:	signals	received */
564250963Sachim		xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals);
565250963Sachim		break;
566250963Sachim
567250963Sachim	    case 'w':		/* PWP:	voluntary context switches (waits) */
568250963Sachim		xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw);
569250963Sachim		break;
570250963Sachim
571250963Sachim	    case 'c':		/* PWP:	involuntary context switches */
572250963Sachim		xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw);
573250963Sachim		break;
574250963Sachim#else /* BSDTIMES */
575250963Sachim# ifdef	_SEQUENT_
576250963Sachim	    case 'W':		/* number of swaps */
577250963Sachim		i = r1->ps_swap	- r0->ps_swap;
578250963Sachim		xprintf("%ld", i);
579250963Sachim		break;
580250963Sachim
581250963Sachim	    case 'M':
582250963Sachim		xprintf("%ld", r1->ps_maxrss / 2);
583250963Sachim		break;
584250963Sachim
585250963Sachim	    case 'F':
586250963Sachim		xprintf("%ld", r1->ps_pagein - r0->ps_pagein);
587250963Sachim		break;
588250963Sachim
589250963Sachim	    case 'R':
590250963Sachim		xprintf("%ld", r1->ps_reclaim -	r0->ps_reclaim);
591250963Sachim		break;
592250963Sachim
593250963Sachim	    case 'I':
594250963Sachim		xprintf("%ld", r1->ps_bread - r0->ps_bread);
595250963Sachim		break;
596250963Sachim
597250963Sachim	    case 'O':
598250963Sachim		xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite);
599250963Sachim		break;
600281826Smav
601250963Sachim	    case 'k':
602281826Smav		xprintf("%ld", r1->ps_signal - r0->ps_signal);
603250963Sachim		break;
604250963Sachim
605250963Sachim	    case 'w':
606250963Sachim		xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw);
607250963Sachim		break;
608250963Sachim
609250963Sachim	    case 'c':
610250963Sachim		xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw);
611250963Sachim		break;
612250963Sachim
613250963Sachim	    case 'Z':
614250963Sachim		xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill);
615250963Sachim		break;
616250963Sachim
617250963Sachim	    case 'i':
618250963Sachim		xprintf("%ld", r1->ps_pffincr -	r0->ps_pffincr);
619250963Sachim		break;
620250963Sachim
621250963Sachim	    case 'd':
622250963Sachim		xprintf("%ld", r1->ps_pffdecr -	r0->ps_pffdecr);
623250963Sachim		break;
624250963Sachim
625250963Sachim	    case 'Y':
626250963Sachim		xprintf("%ld", r1->ps_syscall -	r0->ps_syscall);
627250963Sachim		break;
628250963Sachim
629250963Sachim	    case 'l':
630250963Sachim		xprintf("%ld", r1->ps_lread - r0->ps_lread);
631250963Sachim		break;
632250963Sachim
633250963Sachim	    case 'm':
634250963Sachim		xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite);
635250963Sachim		break;
636250963Sachim
637250963Sachim	    case 'p':
638250963Sachim		xprintf("%ld", r1->ps_phread - r0->ps_phread);
639250963Sachim		break;
640250963Sachim
641250963Sachim	    case 'q':
642250963Sachim		xprintf("%ld", r1->ps_phwrite -	r0->ps_phwrite);
643250963Sachim		break;
644250963Sachim# endif	/* _SEQUENT_ */
645250963Sachim#endif /* BSDTIMES */
646250963Sachim	    default:
647250963Sachim		break;
648250963Sachim	    }
649250963Sachim    xputchar('\n');
650250963Sachim}
651250963Sachim
652250963Sachim#if defined(BSDTIMES) || defined(_SEQUENT_)
653250963Sachimstatic void
654250963Sachimpdeltat(t1, t0)
655250963Sachim    timeval_t *t1, *t0;
656250963Sachim{
657250963Sachim    timeval_t td;
658250963Sachim
659250963Sachim    tvsub(&td, t1, t0);
660250963Sachim    xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L);
661250963Sachim}
662250963Sachim
663250963Sachimstatic void
664250963Sachimtvadd(tsum, t0)
665250963Sachim    timeval_t *tsum, *t0;
666250963Sachim{
667250963Sachim
668250963Sachim    tsum->tv_sec += t0->tv_sec;
669250963Sachim    tsum->tv_usec += t0->tv_usec;
670250963Sachim    if (tsum->tv_usec >= 1000000)
671250963Sachim	tsum->tv_sec++,	tsum->tv_usec -= 1000000;
672250963Sachim}
673250963Sachim
674250963Sachimvoid
675250963Sachimtvsub(tdiff, t1, t0)
676250963Sachim    timeval_t *tdiff, *t1, *t0;
677250963Sachim{
678250963Sachim
679250963Sachim    tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
680250963Sachim    tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
681250963Sachim    if (tdiff->tv_usec < 0)
682250963Sachim	tdiff->tv_sec--, tdiff->tv_usec	+= 1000000;
683250963Sachim}
684250963Sachim
685250963Sachim#else /* !BSDTIMES && !_SEQUENT_ */
686250963Sachimstatic void
687250963Sachimpdtimet(eval, bval)
688250963Sachim#ifndef	POSIX
689250963Sachim    time_t  eval, bval;
690250963Sachim
691250963Sachim#else /* POSIX */
692250963Sachim    clock_t eval, bval;
693263024Sachim
694263024Sachim#endif /* POSIX	*/
695250963Sachim{
696250963Sachim#ifndef	POSIX
697250963Sachim    time_t  val;
698250963Sachim
699250963Sachim#else /* POSIX */
700250963Sachim    clock_t val;
701250963Sachim
702250963Sachim#endif /* POSIX	*/
703250963Sachim
704250963Sachim#ifndef	POSIX
705250963Sachim    val	= (eval	- bval)	* 100 /	HZ;
706250963Sachim#else /* POSIX */
707250963Sachim    val	= (eval	- bval)	* 100 /	clk_tck;
708250963Sachim#endif /* POSIX	*/
709250963Sachim
710250963Sachim    xprintf("%ld.%02ld", val / 100, val	- (val / 100 * 100));
711250963Sachim}
712250963Sachim#endif /* BSDTIMES || _SEQUENT_	*/
713250963Sachim