home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1486 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  26.9 KB

  1. From: wht@n4hgf.uucp (Warren Tucker)
  2. Newsgroups: alt.sources
  3. Subject: u386mon, UNIX/386 system monitor, part 02/02
  4. Message-ID: <104@n4hgf.uucp>
  5. Date: 20 Jun 90 01:57:06 GMT
  6.  
  7. Archive-name: u386mon008/part02
  8. Submitted-by: wht@n4hgf
  9.  
  10. #!/bin/sh
  11. # This is part 02 of u386mon.x0.08
  12. if touch 2>&1 | fgrep 'mmdd' > /dev/null
  13.  then TOUCH=touch
  14.  else TOUCH=true
  15. fi
  16. # ============= u386mon.c ==============
  17. echo "x - extracting u386mon.c (Text)"
  18. sed 's/^X//' << 'SHAR_EOF' > u386mon.c &&
  19. Xchar *revision = "x0.08";
  20. X/*+-------------------------------------------------------------------------
  21. X    u386mon.c - UNIX 386 system monitor
  22. X
  23. X  Defined functions:
  24. X    calc_cpu_avg(cpu_ticks)
  25. X    calc_wait_avg(wait_ticks)
  26. X    clear_area(win,y,x,len)
  27. X    clear_area_char(win,y,x,len,fillchar)
  28. X    draw_cpuscale_literals(win,y,x)
  29. X    draw_per_sec_literals(win,y,x)
  30. X    draw_waitscale_literals(win,y,x)
  31. X    extra_info_stuff()
  32. X    extra_static_stuff()
  33. X    get_cpu_avg(cpu_ticks,period)
  34. X    get_elapsed_time(elapsed_seconds)
  35. X    get_wait_avg(wait_ticks,period)
  36. X    leave(exit_code)
  37. X    leave_text(text,exit_code)
  38. X    main(argc,argv,envp)
  39. X    mkpanel(rows,cols,tly,tlx)
  40. X    pflush()
  41. X    update_cpuscale(win,y,x,width,per_state)
  42. X    update_waitscale(win,y,x,width,per_state,total_ticks)
  43. X    wperror(win,desc)
  44. X
  45. X--------------------------------------------------------------------------*/
  46. X/*+:EDITS:*/
  47. X/*:06-15-1990-18:32-wht@n4hgf-creation */
  48. X
  49. X#define M_TERMINFO
  50. X
  51. X#include <curses.h>
  52. X#include <panel.h>
  53. X#include <signal.h>
  54. X#include <string.h>
  55. X#include <fcntl.h>
  56. X#include <nlist.h>
  57. X#include <errno.h>
  58. X#include <time.h>
  59. X#include <sys/types.h>
  60. X#include <sys/utsname.h>
  61. X#include <sys/stat.h>
  62. X#include <sys/ascii.h>
  63. X#undef NGROUPS_MAX
  64. X#undef NULL
  65. X#include <sys/param.h>
  66. X#include <sys/bootinfo.h>
  67. X#include <sys/tuneable.h>
  68. X#include <sys/sysinfo.h>
  69. X#include <sys/sysmacros.h>
  70. X#include <sys/immu.h>
  71. X#include <sys/region.h>
  72. X#include <sys/proc.h>
  73. X#include <sys/var.h>
  74. X#include "nlsym.h"
  75. X#include "libkmem.h"
  76. X#include "libnlsym.h"
  77. X#include "u386mon.h"
  78. X
  79. X/* screen panel
  80. X00000000001111111111222222222233333333334444444444555555555566666666667777777777
  81. X01234567890123456789012345678901234567890123456789012345678901234567890123456789
  82. X u386mon xxx.xxx                                               mm/dd/yy hh:mm:ss
  83. X
  84. X---- CPU --- tot usr ker brk ---------------------------------------------------
  85. X Instant %   ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  86. X 5 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  87. X10 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  88. X---- Wait -- tot  io swp pio ---------------------------------------------------
  89. X Instant %   ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  90. X 5 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  91. X10 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  92. X
  93. X*/
  94. X
  95. X#define PSCR_TLY    1
  96. X#define PSCR_LINES    25
  97. X#define BOTT_TLY    (PSCR_TLY + PSCR_LINES)
  98. X#define MSGLINE        (LINES - 2)
  99. X#define CMD_TLY        (LINES - 1)
  100. X
  101. X#define CPUSCALE_TLY        1
  102. X#define CPUSCALE_SX            13
  103. X#define CPUSCALE_WIDTH        50
  104. X
  105. X#define WAITSCALE_TLY        5
  106. X#define WAITSCALE_SX        13
  107. X#define WAITSCALE_WIDTH        50
  108. X
  109. X#define PER_SEC_TLY            9
  110. X
  111. X#define LVMSG_Y        (LINES - 2)
  112. X#define LVMSG_X        0
  113. X
  114. Xstruct sysinfo sysinfo;
  115. Xstruct sysinfo sysinfo_last;
  116. X#define sysidelta(x) (sysinfo.x - sysinfo_last.x)
  117. X
  118. Xstruct minfo minfo;
  119. Xstruct minfo minfo_last;
  120. X#define midelta(x) (minfo.x - minfo_last.x)
  121. X
  122. Xstruct bootinfo bootinfo;
  123. Xstruct tune tune;
  124. Xstruct utsname utsname;
  125. Xstruct var v;
  126. Xtime_t now;
  127. Xtime_t then;
  128. Xint hz;
  129. Xint nproc;
  130. Xint nswap;
  131. Xint maxmem;
  132. Xint freemem;
  133. X
  134. X#define CPU_AVG_MAX        10
  135. Xint cpu_avg_init = 0;
  136. Xtime_t *cpu_avg[CPU_AVG_MAX];
  137. Xtime_t cpu_ticks[5];
  138. X
  139. X#define WAIT_AVG_MAX    10
  140. Xint wait_avg_init = 0;
  141. Xtime_t *wait_avg[WAIT_AVG_MAX];
  142. Xtime_t wait_ticks[5];
  143. X
  144. Xchar *cpu_states[] =
  145. X{
  146. X    "idle",
  147. X    "user",
  148. X    "kernel",
  149. X    "wait",
  150. X    "sxbrk"
  151. X};
  152. X
  153. X/*+-------------------------------------------------------------------------
  154. X    pflush() - do update_panels() and doupdate()
  155. X--------------------------------------------------------------------------*/
  156. Xvoid
  157. Xpflush()
  158. X{
  159. X    update_panels();
  160. X    curs_set(0);
  161. X    doupdate();
  162. X    curs_set(1);
  163. X}    /* end of pflush */
  164. X
  165. X/*+-------------------------------------------------------------------------
  166. X    clear_area_char(win,y,x,len,fillchar)
  167. X--------------------------------------------------------------------------*/
  168. Xvoid
  169. Xclear_area_char(win,y,x,len,fillchar)
  170. XWINDOW *win;
  171. Xint y;
  172. Xint x;
  173. Xint len;
  174. Xu_char fillchar;
  175. X{
  176. X    wmove(win,y,x);
  177. X    while(len-- > 0)
  178. X        waddch(win,(chtype)fillchar);
  179. X    wmove(win,y,x);
  180. X
  181. X}    /* end of clear_area_char */
  182. X
  183. X/*+-------------------------------------------------------------------------
  184. X    clear_area(win,y,x,len)
  185. X--------------------------------------------------------------------------*/
  186. Xvoid
  187. Xclear_area(win,y,x,len)
  188. XWINDOW *win;
  189. Xint y;
  190. Xint x;
  191. Xint len;
  192. X{
  193. X    clear_area_char(win,y,x,len,' ');
  194. X}    /* end of clear_area_char */
  195. X
  196. X/*+-------------------------------------------------------------------------
  197. X    leave(exit_code)
  198. X--------------------------------------------------------------------------*/
  199. Xvoid
  200. Xleave(exit_code)
  201. Xint exit_code;
  202. X{
  203. X    pflush();
  204. X    endwin();
  205. X    exit(exit_code);
  206. X}    /* end of leave */
  207. X
  208. X/*+-------------------------------------------------------------------------
  209. X    leave_text(text,exit_code)
  210. X--------------------------------------------------------------------------*/
  211. Xvoid
  212. Xleave_text(text,exit_code)
  213. Xchar *text;
  214. Xint exit_code;
  215. X{
  216. X    wmove(stdscr,LVMSG_Y,LVMSG_X);
  217. X    wclrtoeol(stdscr);
  218. X    waddstr(stdscr,text);
  219. X    leave(exit_code);
  220. X}    /* end of leave */
  221. X
  222. X/*+-------------------------------------------------------------------------
  223. X    wperror(win,desc)
  224. X--------------------------------------------------------------------------*/
  225. Xvoid
  226. Xwperror(win,desc)
  227. XWINDOW *win;
  228. Xchar *desc;
  229. X{
  230. Xextern int errno;
  231. Xextern int sys_nerr;
  232. Xextern char *sys_errlist[];
  233. X
  234. X    waddstr(win,desc);
  235. X    waddstr(win,": ");
  236. X    if(errno < sys_nerr)
  237. X        waddstr(win,sys_errlist[errno]);
  238. X    else
  239. X        wprintw(win,"error %u",errno);
  240. X
  241. X}    /* end of wperror */
  242. X
  243. X/*+-------------------------------------------------------------------------
  244. X    mkpanel(rows,cols,tly,tlx)
  245. X--------------------------------------------------------------------------*/
  246. XPANEL *
  247. Xmkpanel(rows,cols,tly,tlx)
  248. Xint rows;
  249. Xint cols;
  250. Xint tly;
  251. Xint tlx;
  252. X{
  253. XWINDOW *win = newwin(rows,cols,tly,tlx);
  254. XPANEL *pan;
  255. X
  256. X    if(!win)
  257. X        return((PANEL *)0);
  258. X    if(pan = new_panel(win))
  259. X        return(pan);
  260. X    delwin(win);
  261. X    return((PANEL *)0);
  262. X}    /* end of mkpanel */
  263. X
  264. X/*+-----------------------------------------------------------------------
  265. X    char *get_elapsed_time(elapsed_seconds) - "ddd+hh:mm:ss" returned
  266. X  static string address is returned
  267. X------------------------------------------------------------------------*/
  268. Xchar *
  269. Xget_elapsed_time(elapsed_seconds)
  270. Xtime_t elapsed_seconds;
  271. X{
  272. Xstatic char elapsed_time_str[32];
  273. Xtime_t dd,hh,mm,ss;
  274. X
  275. X    dd = 0;
  276. X    hh = elapsed_seconds / 3600;
  277. X    if(hh > 24)
  278. X    {
  279. X        dd = hh / 24;
  280. X        elapsed_seconds -= dd * 3600 * 24;
  281. X        hh %= 24;
  282. X    }
  283. X    elapsed_seconds -= hh * 3600;
  284. X    mm = elapsed_seconds / 60L;
  285. X    elapsed_seconds -= mm * 60L;
  286. X    ss = elapsed_seconds;
  287. X
  288. X    if(dd)
  289. X        sprintf(elapsed_time_str,"%3ld+%02ld:%02ld:%02ld",dd,hh,mm,ss);
  290. X    else
  291. X        sprintf(elapsed_time_str,"    %2ld:%02ld:%02ld",hh,mm,ss);
  292. X    return(elapsed_time_str);
  293. X}    /* end of get_elapsed_time */
  294. X
  295. X/*+-------------------------------------------------------------------------
  296. X    draw_cpuscale_literals(win)
  297. X--------------------------------------------------------------------------*/
  298. Xvoid
  299. Xdraw_cpuscale_literals(win,y,x)
  300. XWINDOW *win;
  301. Xint y;
  302. Xint x;
  303. X{
  304. Xint x2 = x;
  305. X
  306. X    wmove(win,y,x);
  307. X    use_cp(cpBANNER);
  308. X    waddstr(win,"---- CPU --- tot usr ker brk ");
  309. X    getyx(win,y,x2);
  310. X    while(x2 < COLS)
  311. X        waddch(win,(chtype)'-'),x2++;
  312. X    use_cp(cpLIT);
  313. X    wmove(win,y + 1,x);
  314. X      waddstr(win," Instant %");
  315. X    wmove(win,y + 2,x);
  316. X      waddstr(win," 5 Sec Avg %");
  317. X    wmove(win,y + 3,x);
  318. X    waddstr(win,"10 Sec Avg %");
  319. X
  320. X}    /* end of draw_cpuscale_literals */
  321. X
  322. X/*+-------------------------------------------------------------------------
  323. X    update_cpuscale(win,y,width,per_state)
  324. X
  325. X000000000011111111112222222222333333333344444444445555555555666666
  326. X012345678901234567890123456789012345678901234567890123456789012345
  327. Xtot usr ker misc 
  328. X### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  329. X--------------------------------------------------------------------------*/
  330. X#define _CPUSCALE_TX    0
  331. X#define _CPUSCALE_UX    4
  332. X#define _CPUSCALE_KX    8
  333. X#define _CPUSCALE_BX    12
  334. X#define _CPUSCALE_SX    16
  335. X
  336. Xtime_t
  337. Xupdate_cpuscale(win,y,x,width,per_state)
  338. XWINDOW *win;
  339. Xint y;
  340. Xint x;
  341. Xregister width;
  342. Xtime_t *per_state;
  343. X{
  344. Xregister itmp;
  345. Xint accum = 0;
  346. Xtime_t idle = per_state[CPU_IDLE] + per_state[CPU_WAIT];
  347. Xtime_t cpu_ticks_total = idle + per_state[CPU_SXBRK] + 
  348. X    per_state[CPU_IDLE] + per_state[CPU_KERNEL] + per_state[CPU_USER];
  349. Xtime_t percent_user    = (per_state[CPU_USER]   * 100) / cpu_ticks_total;
  350. Xtime_t percent_kernel  = (per_state[CPU_KERNEL] * 100) / cpu_ticks_total;
  351. Xtime_t percent_break   = (per_state[CPU_SXBRK]  * 100) / cpu_ticks_total;
  352. Xtime_t percent_busy    = percent_user + percent_kernel + percent_break;
  353. X
  354. X    if(!idle)            /* take care of integer div truncation */
  355. X        percent_busy = 100;
  356. X
  357. X    wmove(win,y, x + _CPUSCALE_TX);
  358. X    if(percent_busy < 70)
  359. X        use_cp(cpLOW);
  360. X    else if(percent_busy < 90)
  361. X        use_cp(cpMED);
  362. X    else
  363. X        use_cp(cpHIGH);
  364. X    wprintw(win,"%3ld",percent_busy);
  365. X
  366. X    wmove(win,y, x + _CPUSCALE_UX);
  367. X    use_cp(cpINFO);
  368. X    wprintw(win,"%3ld",percent_user);
  369. X    
  370. X    wmove(win,y, x + _CPUSCALE_KX);
  371. X    wprintw(win,"%3ld",percent_kernel);
  372. X    
  373. X    wmove(win,y, x + _CPUSCALE_BX);
  374. X    wprintw(win,"%3ld",percent_break);
  375. X    
  376. X    wmove(win,y, x + _CPUSCALE_SX);
  377. X
  378. X    use_cp(cpLOW);
  379. X    itmp = (width * percent_user) / 100;
  380. X    accum += itmp;
  381. X    while(itmp--)
  382. X        waddch(win,(chtype)'u');
  383. X
  384. X    use_cp(cpMED);
  385. X    itmp = (width * percent_kernel) / 100;
  386. X    accum += itmp;
  387. X    while(itmp--)
  388. X        waddch(win,(chtype)'k');
  389. X
  390. X    use_cp(cpHIGH);
  391. X    itmp = (width * percent_break) / 100;
  392. X    accum += itmp;
  393. X    while(itmp--)
  394. X        waddch(win,(chtype)'b');
  395. X
  396. X    if((percent_busy > 98) && ((width - accum) > 0))
  397. X    {
  398. X        waddch(win,(chtype)'*');
  399. X        accum++;
  400. X    }
  401. X
  402. X    if((itmp = (width - accum)) > 0)
  403. X    {
  404. X        while(itmp--)
  405. X            waddch(win,(chtype)' ');
  406. X    }
  407. X    return(cpu_ticks_total);
  408. X}    /* end of update_cpuscale */
  409. X
  410. X/*+-------------------------------------------------------------------------
  411. X    calc_cpu_avg(cpu_ticks) - add cpu_tick array to avg array
  412. X--------------------------------------------------------------------------*/
  413. Xvoid
  414. Xcalc_cpu_avg(cpu_ticks)
  415. Xtime_t cpu_ticks[];
  416. X{
  417. Xregister itmp;
  418. X
  419. X    if(!cpu_avg_init)
  420. X    {
  421. X        for(itmp = 0; itmp < CPU_AVG_MAX; itmp++)
  422. X            memcpy(cpu_avg[itmp],cpu_ticks,sizeof(time_t) * 5);
  423. X        cpu_avg_init = 1;
  424. X    }
  425. X    else
  426. X    {
  427. X        for(itmp = 0; itmp < CPU_AVG_MAX - 1; itmp++)
  428. X            memcpy(cpu_avg[itmp],cpu_avg[itmp + 1],sizeof(time_t) * 5);
  429. X        memcpy(cpu_avg[itmp],cpu_ticks,sizeof(time_t) * 5);
  430. X    }
  431. X
  432. X}    /* end of calc_cpu_avg */
  433. X
  434. X/*+-------------------------------------------------------------------------
  435. X    get_cpu_avg(cpu_ticks,period)
  436. X--------------------------------------------------------------------------*/
  437. Xget_cpu_avg(cpu_ticks,period)
  438. Xtime_t cpu_ticks[];
  439. Xint period;
  440. X{
  441. Xregister iperiod = CPU_AVG_MAX;
  442. Xregister istate;
  443. Xregister count = period;
  444. X
  445. X    for(istate = 0; istate < 5; istate++)
  446. X        cpu_ticks[istate] = 0;
  447. X
  448. X    while(count--)
  449. X    {
  450. X        iperiod--;
  451. X        for(istate = 0; istate < 5; istate++)
  452. X        {
  453. X            cpu_ticks[istate] += (cpu_avg[iperiod])[istate];
  454. X        }
  455. X    }
  456. X
  457. X    for(istate = 0; istate < 5; istate++)
  458. X        cpu_ticks[istate] /= period;
  459. X
  460. X}    /* end of get_cpu_avg */
  461. X
  462. X/*+-------------------------------------------------------------------------
  463. X    draw_waitscale_literals(win)
  464. X--------------------------------------------------------------------------*/
  465. Xvoid
  466. Xdraw_waitscale_literals(win,y,x)
  467. XWINDOW *win;
  468. Xint y;
  469. Xint x;
  470. X{
  471. Xint x2 = x;
  472. X
  473. X    wmove(win,y,x);
  474. X    use_cp(cpBANNER);
  475. X    waddstr(win,"---- Wait -- tot  io swp pio -- (% of real time) ");
  476. X    getyx(win,y,x2);
  477. X    while(x2 < COLS)
  478. X        waddch(win,(chtype)'-'),x2++;
  479. X    use_cp(cpLIT);
  480. X    wmove(win,y + 1,x);
  481. X      waddstr(win," Instant %");
  482. X    wmove(win,y + 2,x);
  483. X      waddstr(win," 5 Sec Avg %");
  484. X    wmove(win,y + 3,x);
  485. X    waddstr(win,"10 Sec Avg %");
  486. X
  487. X}    /* end of draw_waitscale_literals */
  488. X
  489. X/*+-------------------------------------------------------------------------
  490. X    draw_per_sec_literals(win)
  491. X--------------------------------------------------------------------------*/
  492. Xvoid
  493. Xdraw_per_sec_literals(win,y,x)
  494. XWINDOW *win;
  495. Xint y;
  496. Xint x;
  497. X{
  498. X
  499. X    wmove(win,y,x);
  500. X    use_cp(cpBANNER);
  501. X    waddstr(win,"---- Sysinfo/Minfo --- (last 1 second activity) ");
  502. X    getyx(win,y,x);
  503. X    while(x < COLS)
  504. X        waddch(win,(chtype)'-'),x++;
  505. X
  506. X}    /* end of draw_per_sec_literals */
  507. X
  508. X/*+-------------------------------------------------------------------------
  509. X    update_waitscale(win,y,width,per_state)
  510. X
  511. X000000000011111111112222222222333333333344444444445555555555666666
  512. X012345678901234567890123456789012345678901234567890123456789012345
  513. Xtot  io swp pio 
  514. X### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  515. X--------------------------------------------------------------------------*/
  516. X#define _WAITSCALE_TX    0
  517. X#define _WAITSCALE_IX    4
  518. X#define _WAITSCALE_WX    8
  519. X#define _WAITSCALE_PX    12
  520. X#define _WAITSCALE_SX    16
  521. X
  522. Xtime_t
  523. Xupdate_waitscale(win,y,x,width,per_state,total_ticks)
  524. XWINDOW *win;
  525. Xint y;
  526. Xint x;
  527. Xregister width;
  528. Xtime_t *per_state;
  529. Xtime_t total_ticks;
  530. X{
  531. Xregister itmp;
  532. Xint accum = 0;
  533. Xtime_t percent_io = 0L;
  534. Xtime_t percent_swap = 0L;
  535. Xtime_t percent_pio = 0L;
  536. Xtime_t percent_total_wait;
  537. Xtime_t total_wait;
  538. X
  539. X/* crock: because of latency, total_ticks < all wait ticks sometimes */
  540. X    total_wait = per_state[W_IO] + per_state[W_SWAP] + per_state[W_PIO];
  541. X    if(total_ticks < total_wait)
  542. X        total_ticks = total_wait;
  543. X
  544. X    if(total_ticks)
  545. X    {
  546. X        percent_io    = (per_state[W_IO]   * 100) / total_ticks;
  547. X        percent_swap  = (per_state[W_SWAP] * 100) / total_ticks;
  548. X        percent_pio   = (per_state[W_PIO]  * 100) / total_ticks;
  549. X    }
  550. X
  551. X    percent_total_wait = percent_io + percent_swap + percent_pio;
  552. X    wmove(win,y, x + _WAITSCALE_TX);
  553. X    if(percent_total_wait < 20)
  554. X        use_cp(cpLOW);
  555. X    else if(percent_total_wait < 40)
  556. X        use_cp(cpMED);
  557. X    else
  558. X        use_cp(cpHIGH);
  559. X    wprintw(win,"%3ld",percent_total_wait);
  560. X
  561. X    wmove(win,y, x + _WAITSCALE_IX);
  562. X    use_cp(cpINFO);
  563. X    wprintw(win,"%3ld",percent_io);
  564. X    
  565. X    wmove(win,y, x + _WAITSCALE_WX);
  566. X    wprintw(win,"%3ld",percent_swap);
  567. X    
  568. X    wmove(win,y, x + _WAITSCALE_PX);
  569. X    wprintw(win,"%3ld",percent_pio);
  570. X    
  571. X    wmove(win,y, x + _WAITSCALE_SX);
  572. X
  573. X    use_cp(cpLOW);
  574. X    itmp = (width * percent_io) / 100;
  575. X    accum += itmp;
  576. X    while(itmp--)
  577. X        waddch(win,(chtype)'i');
  578. X
  579. X    use_cp(cpMED);
  580. X    itmp = (width * percent_swap) / 100;
  581. X    accum += itmp;
  582. X    while(itmp--)
  583. X        waddch(win,(chtype)'s');
  584. X
  585. X    use_cp(cpHIGH);
  586. X    itmp = (width * percent_pio) / 100;
  587. X    accum += itmp;
  588. X    while(itmp--)
  589. X        waddch(win,(chtype)'p');
  590. X
  591. X    if((itmp = (width - accum)) > 0)
  592. X    {
  593. X        while(itmp--)
  594. X            waddch(win,(chtype)' ');
  595. X    }
  596. X
  597. X}    /* end of update_waitscale */
  598. X
  599. X/*+-------------------------------------------------------------------------
  600. X    calc_wait_avg(wait_ticks) - add wait_tick array to avg array
  601. X--------------------------------------------------------------------------*/
  602. Xvoid
  603. Xcalc_wait_avg(wait_ticks)
  604. Xtime_t wait_ticks[];
  605. X{
  606. Xregister itmp;
  607. X
  608. X    if(!wait_avg_init)
  609. X    {
  610. X        for(itmp = 0; itmp < WAIT_AVG_MAX; itmp++)
  611. X            memcpy(wait_avg[itmp],wait_ticks,sizeof(time_t) * 3);
  612. X        wait_avg_init = 1;
  613. X    }
  614. X    else
  615. X    {
  616. X        for(itmp = 0; itmp < WAIT_AVG_MAX - 1; itmp++)
  617. X            memcpy(wait_avg[itmp],wait_avg[itmp + 1],sizeof(time_t) * 3);
  618. X        memcpy(wait_avg[itmp],wait_ticks,sizeof(time_t) * 3);
  619. X    }
  620. X
  621. X}    /* end of calc_wait_avg */
  622. X
  623. X/*+-------------------------------------------------------------------------
  624. X    get_wait_avg(wait_ticks,period)
  625. X--------------------------------------------------------------------------*/
  626. Xget_wait_avg(wait_ticks,period)
  627. Xtime_t wait_ticks[];
  628. Xint period;
  629. X{
  630. Xregister iperiod = WAIT_AVG_MAX;
  631. Xregister istate;
  632. Xregister count = period;
  633. X
  634. X    for(istate = 0; istate < 3; istate++)
  635. X        wait_ticks[istate] = 0;
  636. X
  637. X    while(count--)
  638. X    {
  639. X        iperiod--;
  640. X        for(istate = 0; istate < 3; istate++)
  641. X        {
  642. X            wait_ticks[istate] += (wait_avg[iperiod])[istate];
  643. X        }
  644. X    }
  645. X
  646. X    for(istate = 0; istate < 3; istate++)
  647. X        wait_ticks[istate] /= period;
  648. X
  649. X}    /* end of get_wait_avg */
  650. X
  651. X/*+-------------------------------------------------------------------------
  652. X    extra_static_stuff()/extra_info_stuff() - for 43 line display
  653. X--------------------------------------------------------------------------*/
  654. X#define EY1        26
  655. X#define EX1        0
  656. X#define EX2        18
  657. X#define EX3        42
  658. X#define EX4        61
  659. Xvoid
  660. Xextra_static_stuff()
  661. X{
  662. X    display_var(stdscr,EY1,EX1);
  663. X    display_bootinfo(stdscr,EY1,EX2);
  664. X    display_tune(stdscr,EY1,EX3);
  665. X}    /* end of extra_static_stuff */
  666. Xvoid
  667. Xextra_info_stuff()
  668. X{
  669. X    display_proc(stdscr,EY1,EX4);
  670. X}    /* end of extra_info_stuff */
  671. X
  672. X/*+-------------------------------------------------------------------------
  673. X    main(argc,argv,envp)
  674. X--------------------------------------------------------------------------*/
  675. Xmain(argc,argv,envp)
  676. Xint argc;
  677. Xchar **argv;
  678. Xchar **envp;
  679. X{
  680. Xregister itmp;
  681. Xregister char *cptr;
  682. Xtime_t total_ticks;
  683. Xint y,x;
  684. Xint invalidity = 0;
  685. XWINDOW *win = (WINDOW *)0;
  686. X
  687. X    if(uname(&utsname))
  688. X    {
  689. X        perror("uname");
  690. X        exit(1);
  691. X    }
  692. X
  693. X    for(itmp = 0; itmp < CPU_AVG_MAX; itmp++)
  694. X    {
  695. X        if(!(cpu_avg[itmp] = (time_t *)malloc(sizeof(time_t) * 5)))
  696. X        {
  697. X            fputs("cannot alloc memory!\n",stderr);
  698. X            exit(1);
  699. X        }
  700. X    }
  701. X
  702. X    for(itmp = 0; itmp < WAIT_AVG_MAX; itmp++)
  703. X    {
  704. X        if(!(wait_avg[itmp] = (time_t *)malloc(sizeof(time_t) * 3)))
  705. X        {
  706. X            fputs("cannot alloc memory!\n",stderr);
  707. X            exit(1);
  708. X        }
  709. X    }
  710. X
  711. X    if(!initscr())
  712. X    {
  713. X        printf("curses init failed\n");
  714. X        exit(1);
  715. X    }
  716. X    clear();
  717. X    refresh();
  718. X    win = stdscr;
  719. X
  720. X    nlsym_read();
  721. X    kinit(0);    /* read access only */
  722. X    setuid(getuid());
  723. X
  724. X    noecho();
  725. X    keypad(win,1);
  726. X
  727. X    start_color();
  728. X    init_pair(cpLIT,cBLU,cBLK);
  729. X    init_pair(cpINFO,cGRN,cBLK);
  730. X    init_pair(cpLOW,cLTG,cBLK);
  731. X    init_pair(cpMED,cYEL,cBLK);
  732. X    init_pair(cpHIGH,cRED,cBLK);
  733. X#ifdef COLOR_16_TERMINFO
  734. X    init_pair(cpBANNER,cBLK,cGRY);
  735. X#else
  736. X    init_pair(cpBANNER,cBLU,cBLK);
  737. X#endif
  738. X    use_cp(cpLIT);
  739. X
  740. X    /* a hack for now -- assuming AT char set */
  741. X#ifdef HI_BIT_CAN_BE_SET
  742. X    acs_map['l'] = A_ALTCHARSET | sTL;    
  743. X    acs_map['m'] = A_ALTCHARSET | sTR;    
  744. X    acs_map['j'] = A_ALTCHARSET | sBL;    
  745. X    acs_map['k'] = A_ALTCHARSET | sBR;    
  746. X    acs_map['x'] = A_ALTCHARSET | sVR;        /* vertical rule */
  747. X    acs_map['q'] = A_ALTCHARSET | sHR;        /* horizontal rule */
  748. X    acs_map['t'] = A_ALTCHARSET | sLT;        /* left hand T */
  749. X    acs_map['u'] = A_ALTCHARSET | sRT;        /* right hand T */
  750. X#endif
  751. X
  752. X#ifdef REF
  753. X    if(!(p_screen = mkpanel(PSCR_LINES,80,PSCR_TLY,0)))
  754. X    {
  755. X        addstr("cannot make screen panel");
  756. X        refresh();
  757. X        endwin();
  758. X        exit(1);
  759. X    }
  760. X    w_screen = panel_window(p_screen);
  761. X    if(!(p_detail = mkpanel(4,20,PSCR_TLY + getmaxy(w_screen),0)))
  762. X    {
  763. X        addstr("cannot make detail panel");
  764. X        refresh();
  765. X        endwin();
  766. X        exit(1);
  767. X    }
  768. X    w_detail = panel_window(p_detail);
  769. X    winbox(w_detail);
  770. X    hide_panel(p_detail);
  771. X    top_panel(p_screen);
  772. X#endif /* REF */
  773. X
  774. X    wmove(win,0,0);
  775. X    use_cp(cpBANNER);
  776. X    wprintw(win," u386mon %s  ",revision);
  777. X    wprintw(win," %s - %s %s ",utsname.nodename,
  778. X        utsname.machine,utsname.release);
  779. X    getyx(win,y,x);
  780. X    while(x < 80)
  781. X        waddch(win,(chtype)' '),x++;
  782. X    wmove(win,0,70);
  783. X    waddstr(win,"wht@n4hgf");
  784. X    use_cp(cpLIT);
  785. X
  786. X    hz = (cptr = getenv("HZ")) ? atoi(cptr) : HZ;
  787. X    kread((caddr_t)&maxmem,maxmemaddr,sizeof(maxmem));
  788. X    kread((caddr_t)&nswap,nswapaddr,sizeof(nswap));
  789. X    kread((caddr_t)&sysinfo_last,sysinfoaddr,sizeof(sysinfo_last));
  790. X    kread((caddr_t)&minfo_last,minfoaddr,sizeof(minfo));
  791. X    kread((caddr_t)&tune,tuneaddr,sizeof(tune));
  792. X    kread((caddr_t)&v,vaddr,sizeof(v));
  793. X    nproc = v.v_proc;
  794. X    kread((caddr_t)&bootinfo,bootinfoaddr,sizeof(bootinfo));
  795. X
  796. X    draw_cpuscale_literals(win,CPUSCALE_TLY,0);
  797. X    draw_waitscale_literals(win,WAITSCALE_TLY,0);
  798. X    draw_per_sec_literals(win,PER_SEC_TLY,0);
  799. X
  800. X    if(LINES >= 43)
  801. X        extra_static_stuff();
  802. X
  803. X    time(&then);
  804. X    while(1)
  805. X    {
  806. X        nap(1000L);
  807. X        time(&now);
  808. X
  809. X        /* heuristic validity determination */
  810. X        wmove(win,0,45);
  811. X        if((now - then) > 4)
  812. X        {
  813. X            use_cp(cpHIGH);
  814. X            waddstr(win," INVALID ");
  815. X            invalidity += 3;
  816. X        }
  817. X        else if((itmp = ((now - then) > 3)) || (invalidity > 2))
  818. X        {
  819. X            use_cp(cpMED);
  820. X            waddstr(win," INEXACT ");
  821. X            if(itmp)
  822. X                invalidity += 2;
  823. X        }
  824. X        if(invalidity && !(--invalidity))
  825. X        {
  826. X            use_cp(cpBANNER);
  827. X            waddstr(win,"         ");
  828. X        }
  829. X        time(&then);
  830. X
  831. X        kread((caddr_t)&freemem,freememaddr,sizeof(freemem));
  832. X        kread((caddr_t)&sysinfo,sysinfoaddr,sizeof(sysinfo));
  833. X        kread((caddr_t)&minfo,minfoaddr,sizeof(minfo));
  834. X
  835. X        for (itmp = 0; itmp < 5; itmp++)
  836. X            cpu_ticks[itmp] = sysidelta(cpu[itmp]);
  837. X
  838. X        for (itmp = 0; itmp < 3; itmp++)
  839. X            wait_ticks[itmp] = sysidelta(wait[itmp]);
  840. X
  841. X        total_ticks = update_cpuscale(win,CPUSCALE_TLY + 1,CPUSCALE_SX,
  842. X            CPUSCALE_WIDTH,
  843. X            cpu_ticks);
  844. X
  845. X        update_waitscale(win,WAITSCALE_TLY + 1,WAITSCALE_SX,
  846. X            WAITSCALE_WIDTH,
  847. X            wait_ticks,total_ticks);
  848. X
  849. X        calc_cpu_avg(cpu_ticks);
  850. X        calc_wait_avg(wait_ticks);
  851. X
  852. X        get_cpu_avg(cpu_ticks,5);
  853. X        total_ticks = update_cpuscale(win,CPUSCALE_TLY + 2,CPUSCALE_SX,
  854. X            CPUSCALE_WIDTH,
  855. X            cpu_ticks);
  856. X
  857. X        get_wait_avg(wait_ticks,5);
  858. X        update_waitscale(win,WAITSCALE_TLY + 2,WAITSCALE_SX,
  859. X            WAITSCALE_WIDTH,
  860. X            wait_ticks,total_ticks);
  861. X
  862. X        get_cpu_avg(cpu_ticks,10);
  863. X        total_ticks = update_cpuscale(win,CPUSCALE_TLY + 3,CPUSCALE_SX,
  864. X            CPUSCALE_WIDTH,
  865. X            cpu_ticks);
  866. X
  867. X        get_wait_avg(wait_ticks,10);
  868. X        update_waitscale(win,WAITSCALE_TLY + 3,WAITSCALE_SX,
  869. X            WAITSCALE_WIDTH,
  870. X            wait_ticks,total_ticks);
  871. X
  872. X
  873. X#define XX1    0
  874. X#define XX2    15
  875. X#define XX3    32
  876. X#define XX4    48
  877. X#define XX5    63
  878. X
  879. X        use_cp(cpINFO);
  880. X        y = PER_SEC_TLY + 1;
  881. X        wmove(win,y++,XX1);
  882. X        disp_info_long(win,"bread  ","%6ld",sysidelta(bread));
  883. X        wmove(win,y++,XX1);
  884. X        disp_info_long(win,"bwrite ","%6ld",sysidelta(bwrite));
  885. X        wmove(win,y++,XX1);
  886. X        disp_info_long(win,"lread  ","%6ld",sysidelta(lread));
  887. X        wmove(win,y++,XX1);
  888. X        disp_info_long(win,"lwrite ","%6ld",sysidelta(lwrite));
  889. X        wmove(win,y++,XX1);
  890. X        disp_info_long(win,"phread ","%6ld",sysidelta(phread));
  891. X        wmove(win,y++,XX1);
  892. X        disp_info_long(win,"phwrit ","%6ld",sysidelta(phwrite));
  893. X        wmove(win,y++,XX1);
  894. X        disp_info_long(win,"iget   ","%6ld",sysidelta(iget));
  895. X        wmove(win,y++,XX1);
  896. X        disp_info_long(win,"namei  ","%6ld",sysidelta(namei));
  897. X        wmove(win,y++,XX1);
  898. X        disp_info_long(win,"dirblk ","%6ld",sysidelta(dirblk));
  899. X        wmove(win,y++,XX1);
  900. X        disp_info_long(win,"readch ","%6ld",sysidelta(readch));
  901. X        wmove(win,y++,XX1);
  902. X        disp_info_long(win,"writch ","%6ld",sysidelta(writech));
  903. X
  904. X        y = PER_SEC_TLY + 1;
  905. X/*
  906. X        wmove(win,y++,XX2);
  907. X        disp_info_long(win,"rcvint ","%5ld",sysidelta(rcvint));
  908. X        wmove(win,y++,XX2);
  909. X        disp_info_long(win,"xmtint ","%5ld",sysidelta(xmtint));
  910. X        wmove(win,y++,XX2);
  911. X        disp_info_long(win,"mdmint ","%5ld\n",sysidelta(mdmint));
  912. X*/
  913. X        wmove(win,y++,XX2);
  914. X        disp_info_long(win,"rawch  ","%5ld\n",sysidelta(rawch));
  915. X        wmove(win,y++,XX2);
  916. X        disp_info_long(win,"canch  ","%5ld\n",sysidelta(canch));
  917. X        wmove(win,y++,XX2);
  918. X        disp_info_long(win,"outch  ","%5ld\n",sysidelta(outch));
  919. X
  920. X        y++;
  921. X        wmove(win,y++,XX2);
  922. X        disp_info_long(win,"msg    ","%5ld\n",sysidelta(msg));
  923. X        wmove(win,y++,XX2);
  924. X        disp_info_long(win,"sema   ","%5ld\n",sysidelta(sema));
  925. X
  926. X        y++;
  927. X        wmove(win,y++,XX2);
  928. X        disp_static_long(win,"maxmem ","%7ldk",maxmem * NBPP / 1024);
  929. X        wmove(win,y++,XX2);
  930. X        disp_info_long(win,  "frmem  ","%7ldk",freemem * NBPP / 1024);
  931. X        wmove(win,y++,XX2);
  932. X        disp_info_int (win,  "mem used   ","%3d%%",
  933. X            100 - (int)((freemem * 100) / maxmem));
  934. X
  935. X        wmove(win,y++,XX2);
  936. X        disp_static_long(win,"nswap  ","%7ldk",nswap/2);
  937. X        wmove(win,y++,XX2);
  938. X        disp_info_long(win,  "frswp  ","%7ldk",minfo.freeswap/2);
  939. X        wmove(win,y++,XX2);
  940. X        disp_info_int(win,   "swp used   ","%3d%%",
  941. X            100 - (int)((minfo.freeswap * 100) / nswap));
  942. X
  943. X        y = PER_SEC_TLY + 1;
  944. X        wmove(win,y++,XX3);
  945. X        disp_info_long(win,"pswitch ","%4ld",sysidelta(pswitch));
  946. X        wmove(win,y++,XX3);
  947. X        disp_info_long(win,"syscall ","%4ld",sysidelta(syscall));
  948. X        wmove(win,y++,XX3);
  949. X        disp_info_long(win,"sysread ","%4ld",sysidelta(sysread));
  950. X        wmove(win,y++,XX3);
  951. X        disp_info_long(win,"syswrit ","%4ld",sysidelta(syswrite));
  952. X        wmove(win,y++,XX3);
  953. X        disp_info_long(win,"sysfork ","%4ld",sysidelta(sysfork));
  954. X        wmove(win,y++,XX3);
  955. X        disp_info_long(win,"sysexec ","%4ld",sysidelta(sysexec));
  956. X
  957. X        y++;
  958. X        wmove(win,y++,XX3);
  959. X        disp_info_long(win,"runque  ","%4ld",sysidelta(runque));
  960. X        wmove(win,y++,XX3);
  961. X        disp_info_long(win,"runocc  ","%4ld",sysidelta(runocc));
  962. X        wmove(win,y++,XX3);
  963. X        disp_info_long(win,"swpque  ","%4ld",sysidelta(swpque));
  964. X        wmove(win,y++,XX3);
  965. X        disp_info_long(win,"swpocc  ","%4ld",sysidelta(swpocc));
  966. X
  967. X        y = PER_SEC_TLY + 1;
  968. X        wmove(win,y++,XX4);
  969. X        disp_info_long(win,"vfault  ","%3ld",midelta(vfault));
  970. X        wmove(win,y++,XX4);
  971. X        disp_info_long(win,"demand  ","%3ld",midelta(demand));
  972. X        wmove(win,y++,XX4);
  973. X        disp_info_long(win,"pfault  ","%3ld",midelta(pfault));
  974. X        wmove(win,y++,XX4);
  975. X        disp_info_long(win,"cw      ","%3ld",midelta(cw));
  976. X        wmove(win,y++,XX4);
  977. X        disp_info_long(win,"steal   ","%3ld",midelta(steal));
  978. X        wmove(win,y++,XX4);
  979. X        disp_info_long(win,"frdpgs  ","%3ld",midelta(freedpgs));
  980. X        wmove(win,y++,XX4);
  981. X        disp_info_long(win,"vfpg    ","%3ld",midelta(vfpg));
  982. X        wmove(win,y++,XX4);
  983. X        disp_info_long(win,"sfpg    ","%3ld",midelta(sfpg));
  984. X        wmove(win,y++,XX4);
  985. X        disp_info_long(win,"vspg    ","%3ld",midelta(vspg));
  986. X        wmove(win,y++,XX4);
  987. X        disp_info_long(win,"sspg    ","%3ld",midelta(sspg));
  988. X        wmove(win,y++,XX4);
  989. X
  990. X        y = PER_SEC_TLY + 1;
  991. X        disp_info_long(win,"unmodsw ","%3ld",midelta(unmodsw));
  992. X        wmove(win,y++,XX5);
  993. X        disp_info_long(win,"unmodfl ","%3ld",midelta(unmodfl));
  994. X        wmove(win,y++,XX5);
  995. X        disp_info_long(win,"psoutok ","%3ld",midelta(psoutok));
  996. X        wmove(win,y++,XX5);
  997. X        disp_info_long(win,"psinfai ","%3ld",midelta(psinfail));
  998. X        wmove(win,y++,XX5);
  999. X        disp_info_long(win,"psinok  ","%3ld",midelta(psinok));
  1000. X        wmove(win,y++,XX5);
  1001. X        disp_info_long(win,"rsout   ","%3ld",midelta(rsout));
  1002. X        wmove(win,y++,XX5);
  1003. X        disp_info_long(win,"rsin    ","%3ld",midelta(rsin));
  1004. X
  1005. X        y++;
  1006. X        wmove(win,y++,XX5);
  1007. X        use_cp(cpLIT);
  1008. X        waddstr(win,"pages on");
  1009. X        wmove(win,y++,XX5);
  1010. X        disp_info_long(win,"swap  ","%5ld",midelta(swap));
  1011. X        wmove(win,y++,XX5);
  1012. X        disp_info_long(win,"cache ","%5ld",midelta(cache));
  1013. X        wmove(win,y++,XX5);
  1014. X        disp_info_long(win,"file  ","%5ld",midelta(file));
  1015. X
  1016. X        if(LINES >= 43)
  1017. X            extra_info_stuff();
  1018. X
  1019. X        sysinfo_last = sysinfo;
  1020. X        minfo_last = minfo;
  1021. X
  1022. X        pflush();
  1023. X    }
  1024. X
  1025. X    leave(0);
  1026. X}    /* end of main */
  1027. X
  1028. X/* vi: set tabstop=4 shiftwidth=4: */
  1029. X/* end of u386mon.c */
  1030. SHAR_EOF
  1031. $TOUCH -am 0619213590 u386mon.c &&
  1032. chmod 0644 u386mon.c ||
  1033. echo "restore of u386mon.c failed"
  1034. set `wc -c u386mon.c`;Wc_c=$1
  1035. if test "$Wc_c" != "25595"; then
  1036.     echo original size 25595, current size $Wc_c
  1037. fi
  1038. exit 0
  1039.  
  1040. ---------------------------------------------------------------------
  1041. Warren Tucker, TuckerWare    gatech!n4hgf!wht or wht%n4hgf@gatech.edu
  1042. Any perceptible delay will eventually get on your nerves. --Bob Hyers
  1043.