/contrib/tcsh/sh.time.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 740 lines · 582 code · 86 blank · 72 comment · 47 complexity · 9ac80ebafdc35b96544e325a3d16a03f MD5 · raw file

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