home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Shells / tcsh / Source / sh.time.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  15.3 KB  |  624 lines

  1. /* $Header: /u/christos/src/tcsh-6.03/RCS/sh.time.c,v 3.13 1992/11/13 04:19:10 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.13 1992/11/13 04:19:10 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 rusage ruch;
  73.  
  74.     (void) gettimeofday(&time0, NULL);
  75.     (void) getrusage(RUSAGE_SELF, &ru0);
  76.     (void) getrusage(RUSAGE_CHILDREN, &ruch);
  77.     ruadd(&ru0, &ruch);
  78. #else
  79. # ifdef _SEQUENT_
  80.     struct process_stats ruch;
  81.  
  82.     (void) get_process_stats(&time0, PS_SELF, &ru0, &ruch);
  83.     ruadd(&ru0, &ruch);
  84. # else    /* _SEQUENT_ */
  85. #  ifndef COHERENT
  86.     time0 = times(×0);
  87. #  else /* !COHERENT */
  88.     time0 = HZ * time(NULL);
  89.     times(×0);
  90. #  endif /* !COHERENT */
  91.     times0.tms_stime += times0.tms_cstime;
  92.     times0.tms_utime += times0.tms_cutime;
  93.     times0.tms_cstime = 0;
  94.     times0.tms_cutime = 0;
  95. # endif    /* _SEQUENT_ */
  96. #endif /* BSDTIMES */
  97. }
  98.  
  99. /*
  100.  * dotime is only called if it is truly a builtin function and not a
  101.  * prefix to another command
  102.  */
  103. /*ARGSUSED*/
  104. void
  105. dotime(v, c)
  106.     Char **v;
  107.     struct command *c;
  108. {
  109. #ifdef BSDTIMES
  110.     timeval_t timedol;
  111.     struct rusage ru1, ruch;
  112.  
  113.     (void) getrusage(RUSAGE_SELF, &ru1);
  114.     (void) getrusage(RUSAGE_CHILDREN, &ruch);
  115.     ruadd(&ru1, &ruch);
  116.     (void) gettimeofday(&timedol, NULL);
  117.     prusage(&ru0, &ru1, &timedol, &time0);
  118. #else
  119. # ifdef _SEQUENT_
  120.     timeval_t timedol;
  121.     struct process_stats ru1, ruch;
  122.  
  123.     (void) get_process_stats(&timedol, PS_SELF, &ru1, &ruch);
  124.     ruadd(&ru1, &ruch);
  125.     prusage(&ru0, &ru1, &timedol, &time0);
  126. # else /* _SEQUENT_ */
  127. #  ifndef POSIX
  128.     time_t  timedol;
  129. #  else /* POSIX */
  130.     clock_t timedol;
  131. #  endif /* POSIX */
  132.  
  133.     struct tms times_dol;
  134.  
  135. #ifndef COHERENT
  136.     timedol = times(×_dol);
  137. #else
  138.     timedol = HZ * time(NULL);
  139.     times(×_dol);
  140. #endif
  141.     times_dol.tms_stime += times_dol.tms_cstime;
  142.     times_dol.tms_utime += times_dol.tms_cutime;
  143.     times_dol.tms_cstime = 0;
  144.     times_dol.tms_cutime = 0;
  145.     prusage(×0, ×_dol, timedol, time0);
  146. # endif    /* _SEQUENT_ */
  147. #endif /* BSDTIMES */
  148. }
  149.  
  150. /*
  151.  * donice is only called when it on the line by itself or with a +- value
  152.  */
  153. /*ARGSUSED*/
  154. void
  155. donice(v, c)
  156.     register Char **v;
  157.     struct command *c;
  158. {
  159.     register Char *cp;
  160.     int     nval = 0;
  161.  
  162.     v++, cp = *v++;
  163.     if (cp == 0)
  164.     nval = 4;
  165.     else if (*v == 0 && any("+-", cp[0]))
  166.     nval = getn(cp);
  167. #ifdef BSDNICE
  168.     (void) setpriority(PRIO_PROCESS, 0, nval);
  169. #else /* BSDNICE */
  170.     (void) nice(nval);
  171. #endif /* BSDNICE */
  172. }
  173.  
  174. #ifdef BSDTIMES
  175. void
  176. ruadd(ru, ru2)
  177.     register struct rusage *ru, *ru2;
  178. {
  179.     tvadd(&ru->ru_utime, &ru2->ru_utime);
  180.     tvadd(&ru->ru_stime, &ru2->ru_stime);
  181.     if (ru2->ru_maxrss > ru->ru_maxrss)
  182.     ru->ru_maxrss = ru2->ru_maxrss;
  183.  
  184.     ru->ru_ixrss += ru2->ru_ixrss;
  185.     ru->ru_idrss += ru2->ru_idrss;
  186.     ru->ru_isrss += ru2->ru_isrss;
  187.     ru->ru_minflt += ru2->ru_minflt;
  188.     ru->ru_majflt += ru2->ru_majflt;
  189.     ru->ru_nswap += ru2->ru_nswap;
  190.     ru->ru_inblock += ru2->ru_inblock;
  191.     ru->ru_oublock += ru2->ru_oublock;
  192.     ru->ru_msgsnd += ru2->ru_msgsnd;
  193.     ru->ru_msgrcv += ru2->ru_msgrcv;
  194.     ru->ru_nsignals += ru2->ru_nsignals;
  195.     ru->ru_nvcsw += ru2->ru_nvcsw;
  196.     ru->ru_nivcsw += ru2->ru_nivcsw;
  197. }
  198.  
  199. #else /* BSDTIMES */
  200. # ifdef _SEQUENT_
  201. void
  202. ruadd(ru, ru2)
  203.     register struct process_stats *ru, *ru2;
  204. {
  205.     tvadd(&ru->ps_utime, &ru2->ps_utime);
  206.     tvadd(&ru->ps_stime, &ru2->ps_stime);
  207.     if (ru2->ps_maxrss > ru->ps_maxrss)
  208.     ru->ps_maxrss = ru2->ps_maxrss;
  209.  
  210.     ru->ps_pagein += ru2->ps_pagein;
  211.     ru->ps_reclaim += ru2->ps_reclaim;
  212.     ru->ps_zerofill += ru2->ps_zerofill;
  213.     ru->ps_pffincr += ru2->ps_pffincr;
  214.     ru->ps_pffdecr += ru2->ps_pffdecr;
  215.     ru->ps_swap += ru2->ps_swap;
  216.     ru->ps_syscall += ru2->ps_syscall;
  217.     ru->ps_volcsw += ru2->ps_volcsw;
  218.     ru->ps_involcsw += ru2->ps_involcsw;
  219.     ru->ps_signal += ru2->ps_signal;
  220.     ru->ps_lread += ru2->ps_lread;
  221.     ru->ps_lwrite += ru2->ps_lwrite;
  222.     ru->ps_bread += ru2->ps_bread;
  223.     ru->ps_bwrite += ru2->ps_bwrite;
  224.     ru->ps_phread += ru2->ps_phread;
  225.     ru->ps_phwrite += ru2->ps_phwrite;
  226. }
  227.  
  228. # endif    /* _SEQUENT_ */
  229. #endif /* BSDTIMES */
  230.  
  231. #ifdef BSDTIMES
  232.  
  233. /*
  234.  * PWP: the LOG1024 and pagetok stuff taken from the top command,
  235.  * written by William LeFebvre
  236.  */
  237. /* Log base 2 of 1024 is 10 (2^10 == 1024) */
  238. #define LOG1024         10
  239.  
  240. /* Convert clicks (kernel pages) to kbytes ... */
  241. /* If there is no PGSHIFT defined, assume it is 11 */
  242. /* Is this needed for compatability with some old flavor of 4.2 or 4.1? */
  243. #ifdef SUNOS4
  244. # ifndef PGSHIFT
  245. #  define pagetok(size)   ((size) << 1)
  246. # else
  247. #  if PGSHIFT>10
  248. #   define pagetok(size)   ((size) << (PGSHIFT - LOG1024))
  249. #  else
  250. #   define pagetok(size)   ((size) >> (LOG1024 - PGSHIFT))
  251. #  endif
  252. # endif
  253. #endif
  254.  
  255. /*
  256.  * if any other machines return wierd values in the ru_i* stuff, put
  257.  * the adjusting macro here:
  258.  */
  259. #ifdef SUNOS4
  260. # define IADJUST(i)    (pagetok(i)/2)
  261. #else /* SUNOS4 */
  262. # define IADJUST(i)    (i)
  263. #endif /* SUNOS4 */
  264.  
  265. void
  266. prusage(r0, r1, e, b)
  267.     register struct rusage *r0, *r1;
  268.     timeval_t *e, *b;
  269.  
  270. #else /* BSDTIMES */
  271. # ifdef _SEQUENT_
  272. void
  273. prusage(r0, r1, e, b)
  274.     register struct process_stats *r0, *r1;
  275.     timeval_t *e, *b;
  276.  
  277. # else /* _SEQUENT_ */
  278. void
  279. prusage(bs, es, e, b)
  280.     struct tms *bs, *es;
  281.  
  282. #  ifndef POSIX
  283.     time_t  e, b;
  284.  
  285. #  else    /* POSIX */
  286.     clock_t e, b;
  287.  
  288. #  endif /* POSIX */
  289. # endif    /* _SEQUENT_ */
  290. #endif /* BSDTIMES */
  291. {
  292. #ifdef BSDTIMES
  293.     register time_t t =
  294.     (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
  295.     (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
  296.     (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
  297.     (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
  298.  
  299. #else
  300. # ifdef _SEQUENT_
  301.     register time_t t =
  302.     (r1->ps_utime.tv_sec - r0->ps_utime.tv_sec) * 100 +
  303.     (r1->ps_utime.tv_usec - r0->ps_utime.tv_usec) / 10000 +
  304.     (r1->ps_stime.tv_sec - r0->ps_stime.tv_sec) * 100 +
  305.     (r1->ps_stime.tv_usec - r0->ps_stime.tv_usec) / 10000;
  306.  
  307. # else /* _SEQUENT_ */
  308. #  ifndef POSIX
  309.     register time_t t = (es->tms_utime - bs->tms_utime +
  310.              es->tms_stime - bs->tms_stime) * 100 / HZ;
  311.  
  312. #  else /* POSIX */
  313.     register clock_t t = (es->tms_utime - bs->tms_utime +
  314.               es->tms_stime - bs->tms_stime) * 100 / clk_tck;
  315.  
  316. #  endif /* POSIX */
  317. # endif /* _SEQUENT_ */
  318. #endif /* BSDTIMES */
  319.  
  320.     register char *cp;
  321.     register long i;
  322.     register struct varent *vp = adrof(STRtime);
  323.  
  324. #ifdef BSDTIMES
  325.     int     ms =
  326.     (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000;
  327.  
  328.     cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
  329. #else
  330. # ifdef _SEQUENT_
  331.     int     ms =
  332.     (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000;
  333.  
  334.     cp = "%Uu %Ss %E %P %I+%Oio %Fpf+%Ww";
  335. # else /* _SEQUENT_ */
  336. #  ifndef POSIX
  337.     time_t  ms = (e - b) * 100 / HZ;
  338.  
  339. #  else /* POSIX */
  340.     clock_t ms = (e - b) * 100 / clk_tck;
  341.  
  342. #  endif /* POSIX */
  343.     cp = "%Uu %Ss %E %P";
  344.  
  345.     /*
  346.      * the tms stuff is not very precise, so we fudge it.
  347.      * granularity fix: can't be more than 100% 
  348.      * this breaks in multi-processor systems...
  349.      * maybe I should take it out and let people see more then 100% 
  350.      * utilizations.
  351.      */
  352.     if (ms < t && ms != 0)
  353.     ms = t;
  354. # endif /* _SEQUENT_ */
  355. #endif /* BSDTIMES */
  356. #ifdef TDEBUG
  357.     xprintf("es->tms_utime %lu bs->tms_utime %lu\n",
  358.         es->tms_utime, bs->tms_utime);
  359.     xprintf("es->tms_stime %lu bs->tms_stime %lu\n",
  360.         es->tms_stime, bs->tms_stime);
  361.     xprintf("ms %lu e %lu b %lu\n", ms, e, b);
  362.     xprintf("t %lu\n", t);
  363. #endif /* TDEBUG */
  364.  
  365.     if (vp && vp->vec[0] && vp->vec[1])
  366.     cp = short2str(vp->vec[1]);
  367.     for (; *cp; cp++)
  368.     if (*cp != '%')
  369.         xputchar(*cp);
  370.     else if (cp[1])
  371.         switch (*++cp) {
  372.  
  373.         case 'U':        /* user CPU time used */
  374. #ifdef BSDTIMES
  375.         pdeltat(&r1->ru_utime, &r0->ru_utime);
  376. #else
  377. # ifdef _SEQUENT_
  378.         pdeltat(&r1->ps_utime, &r0->ps_utime);
  379. # else /* _SEQUENT_ */
  380. #  ifndef POSIX
  381.         pdtimet(es->tms_utime, bs->tms_utime);
  382. #  else /* POSIX */
  383.         pdtimet(es->tms_utime, bs->tms_utime);
  384. #  endif /* POSIX */
  385. # endif /* _SEQUENT_ */
  386. #endif /* BSDTIMES */
  387.         break;
  388.  
  389.         case 'S':        /* system CPU time used */
  390. #ifdef BSDTIMES
  391.         pdeltat(&r1->ru_stime, &r0->ru_stime);
  392. #else
  393. # ifdef _SEQUENT_
  394.         pdeltat(&r1->ps_stime, &r0->ps_stime);
  395. # else /* _SEQUENT_ */
  396. #  ifndef POSIX
  397.         pdtimet(es->tms_stime, bs->tms_stime);
  398. #  else /* POSIX */
  399.         pdtimet(es->tms_stime, bs->tms_stime);
  400. #  endif /* POSIX */
  401. # endif /* _SEQUENT_ */
  402. #endif /* BSDTIMES */
  403.         break;
  404.  
  405.         case 'E':        /* elapsed (wall-clock) time */
  406. #ifdef BSDTIMES
  407.         pcsecs((long) ms);
  408. #else /* BSDTIMES */
  409.         pcsecs(ms);
  410. #endif /* BSDTIMES */
  411.         break;
  412.  
  413.         case 'P':        /* percent time spent running */
  414.         /* check if the process did not run */
  415.         i = (ms == 0) ? 0 : (t * 1000 / ms);
  416.         xprintf("%ld.%01ld%%", i / 10, i % 10);    /* nn.n% */
  417.         break;
  418.  
  419. #ifdef BSDTIMES
  420.         case 'W':        /* number of swaps */
  421.         i = r1->ru_nswap - r0->ru_nswap;
  422.         xprintf("%ld", i);
  423.         break;
  424.  
  425.         case 'X':        /* (average) shared text size */
  426.         xprintf("%ld", t == 0 ? 0L :
  427.             IADJUST(r1->ru_ixrss - r0->ru_ixrss) / t);
  428.         break;
  429.  
  430.         case 'D':        /* (average) unshared data size */
  431.         xprintf("%ld", t == 0 ? 0L :
  432.             IADJUST(r1->ru_idrss + r1->ru_isrss -
  433.                 (r0->ru_idrss + r0->ru_isrss)) / t);
  434.         break;
  435.  
  436.         case 'K':        /* (average) total data memory used  */
  437.         xprintf("%ld", t == 0 ? 0L :
  438.             IADJUST((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) -
  439.                (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t);
  440.         break;
  441.  
  442.         case 'M':        /* max. Resident Set Size */
  443. #ifdef SUNOS4
  444.         xprintf("%ld", pagetok(r1->ru_maxrss));
  445. #else
  446.         xprintf("%ld", r1->ru_maxrss / 2L);
  447. #endif /* SUNOS4 */
  448.         break;
  449.  
  450.         case 'F':        /* page faults */
  451.         xprintf("%ld", r1->ru_majflt - r0->ru_majflt);
  452.         break;
  453.  
  454.         case 'R':        /* page reclaims */
  455.         xprintf("%ld", r1->ru_minflt - r0->ru_minflt);
  456.         break;
  457.  
  458.         case 'I':        /* FS blocks in */
  459.         xprintf("%ld", r1->ru_inblock - r0->ru_inblock);
  460.         break;
  461.  
  462.         case 'O':        /* FS blocks out */
  463.         xprintf("%ld", r1->ru_oublock - r0->ru_oublock);
  464.         break;
  465.  
  466.         case 'r':        /* PWP: socket messages recieved */
  467.         xprintf("%ld", r1->ru_msgrcv - r0->ru_msgrcv);
  468.         break;
  469.  
  470.         case 's':        /* PWP: socket messages sent */
  471.         xprintf("%ld", r1->ru_msgsnd - r0->ru_msgsnd);
  472.         break;
  473.  
  474.         case 'k':        /* PWP: signals received */
  475.         xprintf("%ld", r1->ru_nsignals - r0->ru_nsignals);
  476.         break;
  477.  
  478.         case 'w':        /* PWP: voluntary context switches (waits) */
  479.         xprintf("%ld", r1->ru_nvcsw - r0->ru_nvcsw);
  480.         break;
  481.  
  482.         case 'c':        /* PWP: involuntary context switches */
  483.         xprintf("%ld", r1->ru_nivcsw - r0->ru_nivcsw);
  484.         break;
  485. #else /* BSDTIMES */
  486. # ifdef _SEQUENT_
  487.         case 'W':        /* number of swaps */
  488.         i = r1->ps_swap - r0->ps_swap;
  489.         xprintf("%ld", i);
  490.         break;
  491.  
  492.         case 'M':
  493.         xprintf("%ld", r1->ps_maxrss / 2);
  494.         break;
  495.  
  496.         case 'F':
  497.         xprintf("%ld", r1->ps_pagein - r0->ps_pagein);
  498.         break;
  499.  
  500.         case 'R':
  501.         xprintf("%ld", r1->ps_reclaim - r0->ps_reclaim);
  502.         break;
  503.  
  504.         case 'I':
  505.         xprintf("%ld", r1->ps_bread - r0->ps_bread);
  506.         break;
  507.  
  508.         case 'O':
  509.         xprintf("%ld", r1->ps_bwrite - r0->ps_bwrite);
  510.         break;
  511.  
  512.         case 'k':
  513.         xprintf("%ld", r1->ps_signal - r0->ps_signal);
  514.         break;
  515.  
  516.         case 'w':
  517.         xprintf("%ld", r1->ps_volcsw - r0->ps_volcsw);
  518.         break;
  519.  
  520.         case 'c':
  521.         xprintf("%ld", r1->ps_involcsw - r0->ps_involcsw);
  522.         break;
  523.  
  524.         case 'Z':
  525.         xprintf("%ld", r1->ps_zerofill - r0->ps_zerofill);
  526.         break;
  527.  
  528.         case 'i':
  529.         xprintf("%ld", r1->ps_pffincr - r0->ps_pffincr);
  530.         break;
  531.  
  532.         case 'd':
  533.         xprintf("%ld", r1->ps_pffdecr - r0->ps_pffdecr);
  534.         break;
  535.  
  536.         case 'Y':
  537.         xprintf("%ld", r1->ps_syscall - r0->ps_syscall);
  538.         break;
  539.  
  540.         case 'l':
  541.         xprintf("%ld", r1->ps_lread - r0->ps_lread);
  542.         break;
  543.  
  544.         case 'm':
  545.         xprintf("%ld", r1->ps_lwrite - r0->ps_lwrite);
  546.         break;
  547.  
  548.         case 'p':
  549.         xprintf("%ld", r1->ps_phread - r0->ps_phread);
  550.         break;
  551.  
  552.         case 'q':
  553.         xprintf("%ld", r1->ps_phwrite - r0->ps_phwrite);
  554.         break;
  555. # endif    /* _SEQUENT_ */
  556. #endif /* BSDTIMES */
  557.         default:
  558.         break;
  559.         }
  560.     xputchar('\n');
  561. }
  562.  
  563. #if defined(BSDTIMES) || defined(_SEQUENT_)
  564. static void
  565. pdeltat(t1, t0)
  566.     timeval_t *t1, *t0;
  567. {
  568.     timeval_t td;
  569.  
  570.     tvsub(&td, t1, t0);
  571.     xprintf("%ld.%03ld", td.tv_sec, td.tv_usec / 1000L);
  572. }
  573.  
  574. static void
  575. tvadd(tsum, t0)
  576.     timeval_t *tsum, *t0;
  577. {
  578.  
  579.     tsum->tv_sec += t0->tv_sec;
  580.     tsum->tv_usec += t0->tv_usec;
  581.     if (tsum->tv_usec > 1000000)
  582.     tsum->tv_sec++, tsum->tv_usec -= 1000000;
  583. }
  584.  
  585. void
  586. tvsub(tdiff, t1, t0)
  587.     timeval_t *tdiff, *t1, *t0;
  588. {
  589.  
  590.     tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
  591.     tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
  592.     if (tdiff->tv_usec < 0)
  593.     tdiff->tv_sec--, tdiff->tv_usec += 1000000;
  594. }
  595.  
  596. #else /* !BSDTIMES && !_SEQUENT_ */
  597. static void
  598. pdtimet(eval, bval)
  599. #ifndef POSIX
  600.     time_t  eval, bval;
  601.  
  602. #else /* POSIX */
  603.     clock_t eval, bval;
  604.  
  605. #endif /* POSIX */
  606. {
  607. #ifndef POSIX
  608.     time_t  val;
  609.  
  610. #else /* POSIX */
  611.     clock_t val;
  612.  
  613. #endif /* POSIX */
  614.  
  615. #ifndef POSIX
  616.     val = (eval - bval) * 100 / HZ;
  617. #else /* POSIX */
  618.     val = (eval - bval) * 100 / clk_tck;
  619. #endif /* POSIX */
  620.  
  621.     xprintf("%ld.%02ld", val / 100, val - (val / 100 * 100));
  622. }
  623. #endif /* BSDTIMES || _SEQUENT_ */
  624.