]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcsh/sh.time.c
6.09.01 vendor update.
[FreeBSD/FreeBSD.git] / contrib / tcsh / sh.time.c
1 /* $Header: /src/pub/tcsh/sh.time.c,v 3.21 2000/01/14 22:57:29 christos Exp $ */
2 /*
3  * sh.time.c: Shell time keeping and printing.
4  */
5 /*-
6  * Copyright (c) 1980, 1991 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the University of
20  *      California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 #include "sh.h"
38
39 RCSID("$Id: sh.time.c,v 3.21 2000/01/14 22:57:29 christos Exp $")
40
41 #ifdef SUNOS4
42 # include <machine/param.h>
43 #endif /* SUNOS4 */
44
45 /*
46  * C Shell - routines handling process timing and niceing
47  */
48 #ifdef BSDTIMES
49 # ifndef RUSAGE_SELF
50 #  define       RUSAGE_SELF     0
51 #  define       RUSAGE_CHILDREN -1
52 # endif /* RUSAGE_SELF */
53 #else /* BSDTIMES */
54 struct tms times0;
55 #endif /* BSDTIMES */
56
57 #if !defined(BSDTIMES) && !defined(_SEQUENT_)
58 # ifdef POSIX
59 static  void    pdtimet __P((clock_t, clock_t));
60 # else /* ! POSIX */
61 static  void    pdtimet __P((time_t, time_t));
62 # endif /* ! POSIX */
63 #else /* BSDTIMES || _SEQUENT_ */
64 static  void    tvadd   __P((timeval_t *, timeval_t *));
65 static  void    pdeltat __P((timeval_t *, timeval_t *));
66 #endif /* BSDTIMES || _SEQUENT_ */
67
68 void
69 settimes()
70 {
71 #ifdef BSDTIMES
72     struct sysrusage ruch;
73 #ifdef convex
74     memset(&ru0, 0, sizeof(ru0));
75     memset(&ruch, 0, sizeof(ruch));
76 #endif /* convex */
77
78     (void) gettimeofday(&time0, NULL);
79     (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru0);
80     (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
81     ruadd(&ru0, &ruch);
82 #else
83 # ifdef _SEQUENT_
84     struct process_stats ruch;
85
86     (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch);
87     ruadd(&ru0, &ruch);
88 # else  /* _SEQUENT_ */
89     seconds0 = time(NULL);
90 #  ifndef COHERENT
91     time0 = times(&times0);
92 #  else /* !COHERENT */
93     time0 = HZ * seconds0;
94     times(&times0);
95 #  endif /* !COHERENT */
96     times0.tms_stime += times0.tms_cstime;
97     times0.tms_utime += times0.tms_cutime;
98     times0.tms_cstime = 0;
99     times0.tms_cutime = 0;
100 # endif /* _SEQUENT_ */
101 #endif /* BSDTIMES */
102 }
103
104 /*
105  * dotime is only called if it is truly a builtin function and not a
106  * prefix to another command
107  */
108 /*ARGSUSED*/
109 void
110 dotime(v, c)
111     Char **v;
112     struct command *c;
113 {
114 #ifdef BSDTIMES
115     timeval_t timedol;
116     struct sysrusage ru1, ruch;
117 #ifdef convex
118     memset(&ru1, 0, sizeof(ru1));
119     memset(&ruch, 0, sizeof(ruch));
120 #endif /* convex */
121
122     (void) getrusage(RUSAGE_SELF, (struct rusage *) &ru1);
123     (void) getrusage(RUSAGE_CHILDREN, (struct rusage *) &ruch);
124     ruadd(&ru1, &ruch);
125     (void) gettimeofday(&timedol, NULL);
126     prusage(&ru0, &ru1, &timedol, &time0);
127 #else
128 # ifdef _SEQUENT_
129     timeval_t timedol;
130     struct process_stats ru1, ruch;
131
132     (void) get_process_stats(&timedol, PS_SELF, &ru1, &ruch);
133     ruadd(&ru1, &ruch);
134     prusage(&ru0, &ru1, &timedol, &time0);
135 # else /* _SEQUENT_ */
136 #  ifndef POSIX
137     time_t  timedol;
138 #  else /* POSIX */
139     clock_t timedol;
140 #  endif /* POSIX */
141
142     struct tms times_dol;
143
144 #ifndef COHERENT
145     timedol = times(&times_dol);
146 #else
147     timedol = HZ * time(NULL);
148     times(&times_dol);
149 #endif
150     times_dol.tms_stime += times_dol.tms_cstime;
151     times_dol.tms_utime += times_dol.tms_cutime;
152     times_dol.tms_cstime = 0;
153     times_dol.tms_cutime = 0;
154     prusage(&times0, &times_dol, timedol, time0);
155 # endif /* _SEQUENT_ */
156 #endif /* BSDTIMES */
157     USE(c);
158     USE(v);
159 }
160
161 /*
162  * donice is only called when it on the line by itself or with a +- value
163  */
164 /*ARGSUSED*/
165 void
166 donice(v, c)
167     register Char **v;
168     struct command *c;
169 {
170     register Char *cp;
171     int     nval = 0;
172
173     USE(c);
174     v++, cp = *v++;
175     if (cp == 0)
176         nval = 4;
177     else if (*v == 0 && any("+-", cp[0]))
178         nval = getn(cp);
179 #ifdef BSDNICE
180     (void) setpriority(PRIO_PROCESS, 0, nval);
181 #else /* BSDNICE */
182     (void) nice(nval);
183 #endif /* BSDNICE */
184 }
185
186 #ifdef BSDTIMES
187 void
188 ruadd(ru, ru2)
189     register struct sysrusage *ru,      *ru2;
190 {
191     tvadd(&ru->ru_utime, &ru2->ru_utime);
192     tvadd(&ru->ru_stime, &ru2->ru_stime);
193     if (ru2->ru_maxrss > ru->ru_maxrss)
194         ru->ru_maxrss = ru2->ru_maxrss;
195
196     ru->ru_ixrss += ru2->ru_ixrss;
197     ru->ru_idrss += ru2->ru_idrss;
198     ru->ru_isrss += ru2->ru_isrss;
199     ru->ru_minflt += ru2->ru_minflt;
200     ru->ru_majflt += ru2->ru_majflt;
201     ru->ru_nswap += ru2->ru_nswap;
202     ru->ru_inblock += ru2->ru_inblock;
203     ru->ru_oublock += ru2->ru_oublock;
204     ru->ru_msgsnd += ru2->ru_msgsnd;
205     ru->ru_msgrcv += ru2->ru_msgrcv;
206     ru->ru_nsignals += ru2->ru_nsignals;
207     ru->ru_nvcsw += ru2->ru_nvcsw;
208     ru->ru_nivcsw += ru2->ru_nivcsw;
209
210 # ifdef convex
211     tvadd(&ru->ru_exutime, &ru2->ru_exutime);
212     ru->ru_utotal += ru2->ru_utotal;
213     ru->ru_usamples += ru2->ru_usamples;
214     ru->ru_stotal += ru2->ru_stotal;
215     ru->ru_ssamples += ru2->ru_ssamples;
216 # endif /* convex */
217 }
218
219 #else /* BSDTIMES */
220 # ifdef _SEQUENT_
221 void
222 ruadd(ru, ru2)
223     register struct process_stats *ru, *ru2;
224 {
225     tvadd(&ru->ps_utime, &ru2->ps_utime);
226     tvadd(&ru->ps_stime, &ru2->ps_stime);
227     if (ru2->ps_maxrss > ru->ps_maxrss)
228         ru->ps_maxrss = ru2->ps_maxrss;
229
230     ru->ps_pagein += ru2->ps_pagein;
231     ru->ps_reclaim += ru2->ps_reclaim;
232     ru->ps_zerofill += ru2->ps_zerofill;
233     ru->ps_pffincr += ru2->ps_pffincr;
234     ru->ps_pffdecr += ru2->ps_pffdecr;
235     ru->ps_swap += ru2->ps_swap;
236     ru->ps_syscall += ru2->ps_syscall;
237     ru->ps_volcsw += ru2->ps_volcsw;
238     ru->ps_involcsw += ru2->ps_involcsw;
239     ru->ps_signal += ru2->ps_signal;
240     ru->ps_lread += ru2->ps_lread;
241     ru->ps_lwrite += ru2->ps_lwrite;
242     ru->ps_bread += ru2->ps_bread;
243     ru->ps_bwrite += ru2->ps_bwrite;
244     ru->ps_phread += ru2->ps_phread;
245     ru->ps_phwrite += ru2->ps_phwrite;
246 }
247
248 # endif /* _SEQUENT_ */
249 #endif /* BSDTIMES */
250
251 #ifdef BSDTIMES
252
253 /*
254  * PWP: the LOG1024 and pagetok stuff taken from the top command,
255  * written by William LeFebvre
256  */
257 /* Log base 2 of 1024 is 10 (2^10 == 1024) */
258 #define LOG1024         10
259
260 /* Convert clicks (kernel pages) to kbytes ... */
261 /* If there is no PGSHIFT defined, assume it is 11 */
262 /* Is this needed for compatability with some old flavor of 4.2 or 4.1? */
263 #ifdef SUNOS4
264 # ifndef PGSHIFT
265 #  define pagetok(size)   ((size) << 1)
266 # else
267 #  if PGSHIFT>10
268 #   define pagetok(size)   ((size) << (PGSHIFT - LOG1024))
269 #  else
270 #   define pagetok(size)   ((size) >> (LOG1024 - PGSHIFT))
271 #  endif
272 # endif
273 #endif
274
275 /*
276  * if any other machines return wierd values in the ru_i* stuff, put
277  * the adjusting macro here:
278  */
279 #ifdef SUNOS4
280 # define IADJUST(i)     (pagetok(i)/2)
281 #else /* SUNOS4 */
282 # ifdef convex
283    /*
284     * convex has megabytes * CLK_TCK
285     * multiply by 100 since we use time in 100ths of a second in prusage
286     */
287 #  define IADJUST(i) (((i) << 10) / CLK_TCK * 100)
288 # else /* convex */
289 #  define IADJUST(i)    (i)
290 # endif /* convex */
291 #endif /* SUNOS4 */
292
293 void
294 prusage(r0, r1, e, b)
295     register struct sysrusage *r0,      *r1;
296     timeval_t *e, *b;
297
298 #else /* BSDTIMES */
299 # ifdef _SEQUENT_
300 void
301 prusage(r0, r1, e, b)
302     register struct process_stats *r0, *r1;
303     timeval_t *e, *b;
304
305 # else /* _SEQUENT_ */
306 void
307 prusage(bs, es, e, b)
308     struct tms *bs, *es;
309
310 #  ifndef POSIX
311     time_t  e, b;
312
313 #  else /* POSIX */
314     clock_t e, b;
315
316 #  endif /* POSIX */
317 # endif /* _SEQUENT_ */
318 #endif /* BSDTIMES */
319 {
320 #ifdef BSDTIMES
321     register time_t t =
322     (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
323     (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
324     (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
325     (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
326
327 #else
328 # ifdef _SEQUENT_
329     register time_t t =
330     (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec) * 100 +
331     (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 +
332     (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec) * 100 +
333     (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000;
334
335 # else /* _SEQUENT_ */
336 #  ifndef POSIX
337     register time_t t = (es->tms_utime - bs->tms_utime +
338                          es->tms_stime - bs->tms_stime) * 100 / HZ;
339
340 #  else /* POSIX */
341     register clock_t t = (es->tms_utime - bs->tms_utime +
342                           es->tms_stime - bs->tms_stime) * 100 / clk_tck;
343
344 #  endif /* POSIX */
345 # endif /* _SEQUENT_ */
346 #endif /* BSDTIMES */
347
348     register char *cp;
349     register long i;
350     register struct varent *vp = adrof(STRtime);
351
352 #ifdef BSDTIMES
353 # ifdef convex
354     static struct system_information sysinfo;
355     long long memtmp;   /* let memory calculations exceede 2Gb */
356 # endif /* convex */
357     int     ms = (int)
358     ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
359
360     cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
361 #else /* !BSDTIMES */
362 # ifdef _SEQUENT_
363     int     ms = (int)
364     ((e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000);
365
366     cp = "%Uu %Ss %E %P %I+%Oio %Fpf+%Ww";
367 # else /* !_SEQUENT_ */
368 #  ifndef POSIX
369     time_t ms = ((time_t)((e - b) / HZ) * 100) +
370                  (time_t)(((e - b) % HZ) * 100) / HZ;
371 #  else /* POSIX */
372     clock_t ms = ((clock_t)((e - b) / clk_tck) * 100) +
373                   (clock_t)(((e - b) % clk_tck) * 100) / clk_tck;
374 #  endif /* POSIX */
375
376     cp = "%Uu %Ss %E %P";
377
378     /*
379      * the tms stuff is not very precise, so we fudge it.
380      * granularity fix: can't be more than 100% 
381      * this breaks in multi-processor systems...
382      * maybe I should take it out and let people see more then 100% 
383      * utilizations.
384      */
385 #  if 0
386     if (ms < t && ms != 0)
387         ms = t;
388 #  endif
389 # endif /*! _SEQUENT_ */
390 #endif /* !BSDTIMES */
391 #ifdef TDEBUG
392     xprintf("es->tms_utime %lu bs->tms_utime %lu\n",
393             es->tms_utime, bs->tms_utime);
394     xprintf("es->tms_stime %lu bs->tms_stime %lu\n",
395             es->tms_stime, bs->tms_stime);
396     xprintf("ms %lu e %lu b %lu\n", ms, e, b);
397     xprintf("t %lu\n", t);
398 #endif /* TDEBUG */
399
400     if (vp && vp->vec[0] && vp->vec[1])
401         cp = short2str(vp->vec[1]);
402     for (; *cp; cp++)
403         if (*cp != '%')
404             xputchar(*cp);
405         else if (cp[1])
406             switch (*++cp) {
407
408             case 'U':           /* user CPU time used */
409 #ifdef BSDTIMES
410                 pdeltat(&r1->ru_utime, &r0->ru_utime);
411 #else
412 # ifdef _SEQUENT_
413                 pdeltat(&r1->ps_utime, &r0->ps_utime);
414 # else /* _SEQUENT_ */
415 #  ifndef POSIX
416                 pdtimet(es->tms_utime, bs->tms_utime);
417 #  else /* POSIX */
418                 pdtimet(es->tms_utime, bs->tms_utime);
419 #  endif /* POSIX */
420 # endif /* _SEQUENT_ */
421 #endif /* BSDTIMES */
422                 break;
423
424             case 'S':           /* system CPU time used */
425 #ifdef BSDTIMES
426                 pdeltat(&r1->ru_stime, &r0->ru_stime);
427 #else
428 # ifdef _SEQUENT_
429                 pdeltat(&r1->ps_stime, &r0->ps_stime);
430 # else /* _SEQUENT_ */
431 #  ifndef POSIX
432                 pdtimet(es->tms_stime, bs->tms_stime);
433 #  else /* POSIX */
434                 pdtimet(es->tms_stime, bs->tms_stime);
435 #  endif /* POSIX */
436 # endif /* _SEQUENT_ */
437 #endif /* BSDTIMES */
438                 break;
439
440             case 'E':           /* elapsed (wall-clock) time */
441 #ifdef BSDTIMES
442                 pcsecs((long) ms);
443 #else /* BSDTIMES */
444                 pcsecs(ms);
445 #endif /* BSDTIMES */
446                 break;
447
448             case 'P':           /* percent time spent running */
449                 /* check if the process did not run */
450 #ifdef convex
451                 /*
452                  * scale the cpu %- ages by the number of processors
453                  * available on this machine
454                  */
455                 if ((sysinfo.cpu_count == 0) &&
456                     (getsysinfo(SYSINFO_SIZE, &sysinfo) < 0))
457                     sysinfo.cpu_count = 1;
458                     i = (ms == 0) ? 0 : (t * 1000.0 / (ms * sysinfo.cpu_count));
459 #else /* convex */
460                 i = (ms == 0) ? 0 : (t * 1000.0 / ms);
461 #endif /* convex */
462                 xprintf("%ld.%01ld%%", i / 10, i % 10); /* nn.n% */
463                 break;
464
465 #ifdef BSDTIMES
466             case 'W':           /* number of swaps */
467                 i = r1->ru_nswap - r0->ru_nswap;
468                 xprintf("%ld", i);
469                 break;
470  
471 #ifdef convex
472             case 'X':           /* (average) shared text size */
473                 memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_ixrss -
474                                  (long long)r0->ru_ixrss) /
475                          (long long)t);
476                 xprintf("%lu", (unsigned long)memtmp);
477                         
478                 break;
479
480             case 'D':           /* (average) unshared data size */
481                 memtmp = (t == 0 ? 0LL : IADJUST((long long)r1->ru_idrss +
482                                  (long long)r1->ru_isrss -
483                                  ((long long)r0->ru_idrss +
484                                   (long long)r0->ru_isrss)) /
485                          (long long)t);
486                 xprintf("%lu", (unsigned long)memtmp);
487                 break;
488
489             case 'K':           /* (average) total data memory used  */
490                 memtmp = (t == 0 ? 0LL : IADJUST(((long long)r1->ru_ixrss +
491                                   (long long)r1->ru_isrss +
492                                   (long long)r1->ru_idrss) -
493                                   ((long long)r0->ru_ixrss +
494                                    (long long)r0->ru_idrss +
495                                    (long long)r0->ru_isrss)) /
496                          (long long)t);
497                 xprintf("%lu", (unsigned long)memtmp);
498                 break;
499 #else /* !convex */
500             case 'X':           /* (average) shared text size */
501                 xprintf("%ld", t == 0 ? 0L :
502                         IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t);
503                 break;
504
505             case 'D':           /* (average) unshared data size */
506                 xprintf("%ld", t == 0 ? 0L :
507                         IADJUST(r1->ru_idrss + r1->ru_isrss -
508                                 (r0->ru_idrss + r0->ru_isrss)) / t);
509                 break;
510
511             case 'K':           /* (average) total data memory used  */
512                 xprintf("%ld", t == 0 ? 0L :
513                         IADJUST((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) -
514                            (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t);
515                 break;
516 #endif /* convex */
517             case 'M':           /* max. Resident Set Size */
518 #ifdef SUNOS4
519                 xprintf("%ld", pagetok(r1->ru_maxrss));
520 #else
521 # ifdef convex
522                 xprintf("%ld", r1->ru_maxrss * 4L);
523 # else /* !convex */
524                 xprintf("%ld", r1->ru_maxrss / 2L);
525 # endif /* convex */
526 #endif /* SUNOS4 */
527                 break;
528
529             case 'F':           /* page faults */
530                 xprintf("%ld", r1->ru_majflt - r0->ru_majflt);
531                 break;
532
533             case 'R':           /* page reclaims */
534                 xprintf("%ld", r1->ru_minflt - r0->ru_minflt);
535                 break;
536
537             case 'I':           /* FS blocks in */
538                 xprintf("%ld", r1->ru_inblock - r0->ru_inblock);
539                 break;
540
541             case 'O':           /* FS blocks out */
542                 xprintf("%ld", r1->ru_oublock - r0->ru_oublock);
543                 break;
544
545 # ifdef convex
546             case 'C':                   /*  CPU parallelization factor */
547                 if (r1->ru_usamples     != 0LL) {
548                     long long parr = ((r1->ru_utotal * 100LL) /
549                                       r1->ru_usamples);
550                     xprintf("%d.%02d", (int)(parr/100), (int)(parr%100));
551                 } else
552                     xprintf("?");
553                 break;
554 # endif /* convex */
555             case 'r':           /* PWP: socket messages recieved */
556                 xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv);
557                 break;
558
559             case 's':           /* PWP: socket messages sent */
560                 xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd);
561                 break;
562
563             case 'k':           /* PWP: signals received */
564                 xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals);
565                 break;
566
567             case 'w':           /* PWP: voluntary context switches (waits) */
568                 xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw);
569                 break;
570
571             case 'c':           /* PWP: involuntary context switches */
572                 xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw);
573                 break;
574 #else /* BSDTIMES */
575 # ifdef _SEQUENT_
576             case 'W':           /* number of swaps */
577                 i = r1->ps_swap - r0->ps_swap;
578                 xprintf("%ld", i);
579                 break;
580
581             case 'M':
582                 xprintf("%ld", r1->ps_maxrss / 2);
583                 break;
584
585             case 'F':
586                 xprintf("%ld", r1->ps_pagein - r0->ps_pagein);
587                 break;
588
589             case 'R':
590                 xprintf("%ld", r1->ps_reclaim - r0->ps_reclaim);
591                 break;
592
593             case 'I':
594                 xprintf("%ld", r1->ps_bread - r0->ps_bread);
595                 break;
596
597             case 'O':
598                 xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite);
599                 break;
600
601             case 'k':
602                 xprintf("%ld", r1->ps_signal - r0->ps_signal);
603                 break;
604
605             case 'w':
606                 xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw);
607                 break;
608
609             case 'c':
610                 xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw);
611                 break;
612
613             case 'Z':
614                 xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill);
615                 break;
616
617             case 'i':
618                 xprintf("%ld", r1->ps_pffincr - r0->ps_pffincr);
619                 break;
620
621             case 'd':
622                 xprintf("%ld", r1->ps_pffdecr - r0->ps_pffdecr);
623                 break;
624
625             case 'Y':
626                 xprintf("%ld", r1->ps_syscall - r0->ps_syscall);
627                 break;
628
629             case 'l':
630                 xprintf("%ld", r1->ps_lread - r0->ps_lread);
631                 break;
632
633             case 'm':
634                 xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite);
635                 break;
636
637             case 'p':
638                 xprintf("%ld", r1->ps_phread - r0->ps_phread);
639                 break;
640
641             case 'q':
642                 xprintf("%ld", r1->ps_phwrite - r0->ps_phwrite);
643                 break;
644 # endif /* _SEQUENT_ */
645 #endif /* BSDTIMES */
646             default:
647                 break;
648             }
649     xputchar('\n');
650 }
651
652 #if defined(BSDTIMES) || defined(_SEQUENT_)
653 static void
654 pdeltat(t1, t0)
655     timeval_t *t1, *t0;
656 {
657     timeval_t td;
658
659     tvsub(&td, t1, t0);
660     xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L);
661 }
662
663 static void
664 tvadd(tsum, t0)
665     timeval_t *tsum, *t0;
666 {
667
668     tsum->tv_sec += t0->tv_sec;
669     tsum->tv_usec += t0->tv_usec;
670     if (tsum->tv_usec >= 1000000)
671         tsum->tv_sec++, tsum->tv_usec -= 1000000;
672 }
673
674 void
675 tvsub(tdiff, t1, t0)
676     timeval_t *tdiff, *t1, *t0;
677 {
678
679     tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
680     tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
681     if (tdiff->tv_usec < 0)
682         tdiff->tv_sec--, tdiff->tv_usec += 1000000;
683 }
684
685 #else /* !BSDTIMES && !_SEQUENT_ */
686 static void
687 pdtimet(eval, bval)
688 #ifndef POSIX
689     time_t  eval, bval;
690
691 #else /* POSIX */
692     clock_t eval, bval;
693
694 #endif /* POSIX */
695 {
696 #ifndef POSIX
697     time_t  val;
698
699 #else /* POSIX */
700     clock_t val;
701
702 #endif /* POSIX */
703
704 #ifndef POSIX
705     val = (eval - bval) * 100 / HZ;
706 #else /* POSIX */
707     val = (eval - bval) * 100 / clk_tck;
708 #endif /* POSIX */
709
710     xprintf("%ld.%02ld", val / 100, val - (val / 100 * 100));
711 }
712 #endif /* BSDTIMES || _SEQUENT_ */