home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / u386mon / part03 < prev    next >
Encoding:
Text File  |  1992-11-20  |  50.4 KB  |  1,905 lines

  1. Newsgroups: comp.sources.misc
  2. From: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
  3. Subject:  v33i112:  u386mon - SVR3 performance/status monitor v2.60, Part03/09
  4. Message-ID: <1992Nov22.020019.24090@sparky.imd.sterling.com>
  5. X-Md4-Signature: 4354a39d956d61a1640565f0cf3be39a
  6. Date: Sun, 22 Nov 1992 02:00:19 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
  10. Posting-number: Volume 33, Issue 112
  11. Archive-name: u386mon/part03
  12. Environment: SYSVR3
  13. Supersedes: u386mon: Volume 22, Issue 3-9
  14.  
  15. #!/bin/sh
  16. # This is part 03 of u386mon.2.60
  17. # ============= u386mon.c ==============
  18. if test -f 'u386mon.c' -a X"$1" != X"-c"; then
  19.     echo 'x - skipping u386mon.c (File already exists)'
  20. else
  21. echo 'x - extracting u386mon.c (Text)'
  22. sed 's/^X//' << 'SHAR_EOF' > 'u386mon.c' &&
  23. X/* CHK=0x0C21 */
  24. Xchar *revision = "2.6";
  25. X/*+-------------------------------------------------------------------------
  26. X    u386mon.c - UNIX 386 (and other) system monitor
  27. X    wht@n4hgf.Mt-Park.GA.US and many others
  28. X
  29. X  Defined functions:
  30. X    adb_trap()
  31. X    calc_cpu_avg(per_state)
  32. X    calc_wait_avg(per_state)
  33. X    caught_signal(sig)
  34. X    draw_cpuscale_literals(win,y,x)
  35. X    draw_per_sec_literals(win,y,x)
  36. X    draw_waitscale_literals(win,y,x)
  37. X    extra_info_stuff()
  38. X    extra_static_stuff()
  39. X    get_cpu_avg(cpu_ticks,period)
  40. X    get_elapsed_time(elapsed_seconds)
  41. X    get_wait_avg(wait_ticks,period)
  42. X    leave(exit_code)
  43. X    leave_text(text,exit_code)
  44. X    leaving(exit_code)
  45. X    main(argc,argv,envp)
  46. X    update_cpuscale(win,y,x,width,per_state)
  47. X    update_waitscale(win,y,x,width,per_state,total_ticks)
  48. X
  49. X00000000001111111111222222222233333333334444444444555555555566666666667777777777
  50. X01234567890123456789012345678901234567890123456789012345678901234567890123456789
  51. X u386mon xxx.xxx                       PLOCK     INVALID      hh:mm:ss wht@n4hgf
  52. X
  53. X---- CPU --- tot usr ker brk ---------------------------------------------------
  54. X Instant %   ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  55. X 5 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  56. X10 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  57. X---- Wait -- tot  io pio swp ---------------------------------------------------
  58. X Instant %   ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  59. X 5 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  60. X10 Sec Avg % ### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  61. X
  62. X--------------------------------------------------------------------------*/
  63. X/*+:EDITS:*/
  64. X/*:07-15-1992-14:34-wht@n4hgf-2.60 release - u386mon+siotools merge */
  65. X/*:03-09-1992-11:54-wht@n4hgf-bump version number for p_sid addition */
  66. X/*:08-20-1991-12:44-root@n4hgf-nba@sysware.dk S5R31 and config reorg */
  67. X/*:08-14-1991-13:04-wht@n4hgf-STREAMS and table works for ISC 2.2 */
  68. X/*:08-11-1991-14:05-root@n4hgf-use PATCHLEVEL */
  69. X/*:08-01-1991-23:35-wht@n4hgf-release 2.40 source control point */
  70. X/*:05-15-1991-17:22-wht@n4hgf-2.3 patches for SVR31 from nba@sysware.dk */
  71. X/*:05-14-1991-06:11-root@n4hgf-evidently a fast cpu gets 0 cpu sometimes :-) */
  72. X/*:05-09-1991-03:57-wht@n4hgf-fix HZ problem reported by ir@crosfield.co.uk */
  73. X/*:05-09-1991-03:35-wht@n4hgf-gcc gives good warning */
  74. X/*:05-09-1991-02:24-wht@n4hgf-HZ environment variable might be non-zero */
  75. X/*:04-16-1991-02:25-martin@hppcmart additions for SCO 3.2.2 */
  76. X/*:03-16-1991-14:22-wht@n4hgf-widen sysinfo column 4 */
  77. X/*:08-14-1990-19:08-root@n4hgf-fix **argv bug */
  78. X/*:08-10-1990-14:12-jmd@p1so/wht@n4hgf-2.20-add Tandem Integrity S2 */
  79. X/*:08-07-1990-14:24-wht@n4hgf-nba@sysware.dk SVR31 updates */
  80. X/*:08-02-1990-15:36-wht@n4hgf-2.12-old curses hacks+minor 3.2 formalizations */
  81. X/*:08-01-1990-19:24-jdc@dell.com-add DELL config */
  82. X/*:08-01-1990-17:25-wht@n4hgf-fix sysi86 swap calculations */
  83. X/*:07-28-1990-18:06-wht@n4hgf-2.10 release */
  84. X/*:07-28-1990-15:05-wht@n4hgf-make CYCLEmsec variable */
  85. X/*:07-11-1990-03:45-root@n4hgf-faster proc table manipulation */
  86. X/*:07-10-1990-19:06-root@n4hgf-redesign attributes/color pairs */
  87. X/*:07-10-1990-18:33-root@n4hgf-move pio wait to medium alert */
  88. X/*:07-10-1990-18:01-root@n4hgf-"improvement" didnt do much, but leave for now */
  89. X/*:07-10-1990-13:54-root@n4hgf-improve nap heuristics and catch signals */
  90. X/*:07-08-1990-20:31-root@n4hgf-make room for phread/phwrite */
  91. X/*:07-03-1990-02:48-root@n4hgf-more accurate timing using ftime calculations */
  92. X/*:06-27-1990-01:57-wht@n4hgf-1.10-incorporate suggestions from alpha testers */
  93. X/*:06-27-1990-01:07-wht@n4hgf-add ^R and ^L refresh */
  94. X/*:06-25-1990-17:34-wht@n4hgf-add detail extra for 25 line tubes */
  95. X/*:06-25-1990-04:14-wht@n4hgf-1.02-better error handling */
  96. X/*:06-24-1990-20:53-wht@n4hgf-v1.01-add ISC support thanks to peter@radig.de */
  97. X/*:06-21-1990-14:26-r@n4hgf-version x0.12 seems bug free */
  98. X/*:06-15-1990-18:32-wht@n4hgf-creation */
  99. X
  100. X#include "config.h"
  101. X#include "patchlevel.h"
  102. X
  103. X#include <curses.h>
  104. X#include <sys/types.h>
  105. X#undef timeout /* conflict in curses.h and bootinfo.h per trb@ima.ima.isc.com */
  106. X#undef reg     /* per nba@sysware.dk */
  107. X#include "libpanel.h"
  108. X#include <signal.h>
  109. X#include <string.h>
  110. X#include <fcntl.h>
  111. X#include <nlist.h>
  112. X#include <errno.h>
  113. X#include <time.h>
  114. X#if defined(HAS_TIMEB)
  115. X# include <sys/timeb.h>
  116. X#endif
  117. X#include <sys/lock.h>
  118. X#include <sys/utsname.h>
  119. X#include <sys/stat.h>
  120. X#if defined(HAS_ASCII)
  121. X# include <sys/ascii.h>
  122. X#else
  123. X#define A_ESC    '\033'
  124. X#endif
  125. X#undef NGROUPS_MAX
  126. X#undef NULL
  127. X#include <sys/param.h>
  128. X#if defined(HAS_BOOTINFO)
  129. X# include <sys/bootinfo.h>
  130. X#endif
  131. X#include <sys/tuneable.h>
  132. X#include <sys/sysinfo.h>
  133. X#include <sys/sysmacros.h>
  134. X#include <sys/immu.h>
  135. X#include <sys/region.h>
  136. X#if defined(mips)
  137. X# include <sys/sbd.h>
  138. X#endif
  139. X#include <sys/proc.h>
  140. X#include <sys/var.h>
  141. X#if defined(i386) || defined(i486)
  142. X# include <sys/sysi86.h>
  143. X#endif
  144. X#if defined(mips)
  145. X# include <sys/sysmips.h>
  146. X#endif
  147. X#include <sys/swap.h>
  148. X#if !defined(mips)
  149. X# include <sys/trap.h>
  150. X#endif
  151. X
  152. X#include "nlsym.h"
  153. X#include "libkmem.h"
  154. X#include "libmem.h"
  155. X#include "libswap.h"
  156. X#include "libnlsym.h"
  157. X#include "u386mon.h"
  158. X
  159. Xlong nap();
  160. XPANEL *mkpanel();
  161. X
  162. X#if defined(HAS_TIMEB)
  163. X#define delta_msec(t,t0) ((( t.time * 1000L) +  t.millitm) - \
  164. X                          ((t0.time * 1000L) + t0.millitm))
  165. X#endif
  166. X
  167. X#define INEXACT_STATE    2
  168. X#define INVALID_STATE    5
  169. X
  170. X#if defined(mips)
  171. X#define CYCLEmsecDef 5000L
  172. X#define CYCLEmsecMax 9000L
  173. X#else
  174. X#define CYCLEmsecDef 2000L
  175. X#define CYCLEmsecMax 4000L
  176. X#endif
  177. X
  178. Xlong CYCLEmsec = CYCLEmsecDef;
  179. X
  180. Xstruct sysinfo sysinfo;
  181. Xstruct sysinfo sysinfo_last;
  182. X#define sysidelta(x) (sysinfo.x - sysinfo_last.x)
  183. X
  184. Xstruct minfo minfo;
  185. Xstruct minfo minfo_last;
  186. X#define midelta(x) (minfo.x - minfo_last.x)
  187. X
  188. X#if defined(HAS_BOOTINFO)
  189. Xstruct bootinfo bootinfo;
  190. X#endif
  191. X
  192. Xswpt_t swaptab [MSFILES];
  193. Xswpi_t swapint = {SI_LIST, (char *)swaptab};
  194. Xstruct tune tune;
  195. Xstruct utsname utsname;
  196. Xstruct var v;
  197. X
  198. X#if defined(HAS_TIMEB)
  199. Xstruct timeb timeb_cycle_start;
  200. Xstruct timeb timeb_cycle_end;
  201. Xstruct timeb timeb_info_read;
  202. Xstruct timeb timeb_last_info_read;
  203. X#endif
  204. X
  205. Xint hz;
  206. Xint nswap;    /* seems to be in units of NBPSCTR bytes */
  207. Xint maxmem;
  208. Xint freemem;
  209. Xdaddr_t myreadlen = 0L;
  210. Xint myreadcnt = 0;
  211. Xint stat_period_msec_y = -1;
  212. Xint stat_period_msec_x = -1;
  213. Xint color_avail = 0;
  214. Xint invalidity = 0;
  215. X
  216. XPANEL *pscr;
  217. XWINDOW *wscr;
  218. Xextern WINDOW *wdet;
  219. X
  220. X#define CPU_AVG_MAX        10
  221. Xint cpu_avg_init = 0;
  222. Xtime_t *cpu_avg[CPU_AVG_MAX];
  223. Xtime_t cpu_ticks[5];
  224. X
  225. X#define WAIT_AVG_MAX    10
  226. Xint wait_avg_init = 0;
  227. Xtime_t *wait_avg[WAIT_AVG_MAX];
  228. Xtime_t wait_ticks[5];
  229. X
  230. X/*+-------------------------------------------------------------------------
  231. X    basename(fullname) - strip directory name from filename
  232. X
  233. Xreturns address of static string
  234. X--------------------------------------------------------------------------*/
  235. Xchar *
  236. Xbasename(fullname)
  237. Xchar *fullname;
  238. X{
  239. X    register char *start;
  240. X    static char outstr[256];
  241. X    char *strrchr();
  242. X
  243. X    start = strrchr(fullname,'/'); /* find last slash */
  244. X    if(!start)
  245. X        return(fullname);
  246. X    start++;
  247. X    strcpy(outstr,start);
  248. X    return(outstr);
  249. X}    /* end of basename */
  250. X
  251. X/*+-------------------------------------------------------------------------
  252. X    leaving() - perform leave() basic processing and return
  253. X--------------------------------------------------------------------------*/
  254. Xvoid
  255. Xleaving()
  256. X{
  257. X    wmove(wscr,CMD_TLY,0);
  258. X    use_cp(wscr,cpLIT);
  259. X    wclrtoeol(wscr);
  260. X    pflush();
  261. X    endwin();
  262. X}    /* end of leaving */
  263. X
  264. X/*+-------------------------------------------------------------------------
  265. X    leave(exit_code) - leave program with exit code
  266. X--------------------------------------------------------------------------*/
  267. Xvoid
  268. Xleave(exit_code)
  269. Xint exit_code;
  270. X{
  271. X    leaving();
  272. X    exit(exit_code);
  273. X}    /* end of leave */
  274. X
  275. X/*+-------------------------------------------------------------------------
  276. X    leave_text(text,exit_code) - leave program with message and exit code
  277. XIf exit_code == 255, do wperror
  278. X--------------------------------------------------------------------------*/
  279. Xvoid
  280. Xleave_text(text,exit_code)
  281. Xchar *text;
  282. Xint exit_code;
  283. X{
  284. X    if(exit_code == 255)
  285. X    {
  286. X        int y;
  287. X        register x;
  288. X        extern int errno;
  289. X        extern int sys_nerr;
  290. X        extern char *sys_errlist[];
  291. X
  292. X        top_panel(pscr);
  293. X        wmove(wscr,MSG_TLY - 2,0);
  294. X        use_cp(wscr,cpHIGH);
  295. X        x = 0;
  296. X        while(x++ < COLS)
  297. X            waddch(wscr,(chtype)' ');
  298. X        wmove(wscr,MSG_TLY - 1,0);
  299. X        wprintw(wscr,"errno %d",errno);
  300. X        if(errno < sys_nerr)
  301. X            wprintw(wscr,": %s",sys_errlist[errno]);
  302. X        getyx(wscr,y,x);
  303. X        while(x++ < COLS)
  304. X            waddch(wscr,(chtype)' ');
  305. X    }
  306. X    if (text && *text)
  307. X        disp_msg(cpHIGH,text);
  308. X    else
  309. X    {
  310. X        wmove(stdscr,LINES - 1,0);
  311. X        wclrtoeol(stdscr);
  312. X    }
  313. X    leave(exit_code);
  314. X}    /* end of leave_text */
  315. X
  316. X/*+-------------------------------------------------------------------------
  317. X    adb_trap() - convenient trap for catching abort
  318. X
  319. X  Get a look at stack before abort() botches it
  320. X--------------------------------------------------------------------------*/
  321. X#if defined(ADB_DEBUG)
  322. Xvoid
  323. Xadb_trap()
  324. X{
  325. X    printf("too bad .... goodbye\n");
  326. X}    /* end of adb_trap */
  327. X#endif
  328. X
  329. X/*+-------------------------------------------------------------------------
  330. X    caught_signal(sig) - SIGHUP thru SIGSYS: leave with possible abort
  331. X--------------------------------------------------------------------------*/
  332. Xvoid
  333. Xcaught_signal(sig)
  334. Xint sig;
  335. X{
  336. X    leaving();
  337. X    switch(sig)
  338. X    {
  339. X        case SIGQUIT:
  340. X        case SIGILL:
  341. X        case SIGTRAP:
  342. X        case SIGIOT:
  343. X        case SIGEMT:
  344. X        case SIGFPE:
  345. X        case SIGBUS:
  346. X        case SIGSEGV:
  347. X        case SIGSYS:
  348. X#if defined(ADB_DEBUG)
  349. X            adb_trap();    /* if debugging, stop at convenient breakpoint */
  350. X#endif
  351. X            abort();
  352. X    }
  353. X    exit(200);
  354. X}    /* end of caught_signal */
  355. X
  356. X/*+-----------------------------------------------------------------------
  357. X    char *get_elapsed_time(elapsed_seconds) - "ddd+hh:mm:ss" returned
  358. X  static string address is returned
  359. X------------------------------------------------------------------------*/
  360. Xchar *
  361. Xget_elapsed_time(elapsed_seconds)
  362. Xtime_t elapsed_seconds;
  363. X{
  364. X    static char elapsed_time_str[32];
  365. X    time_t dd,hh,mm,ss;
  366. X
  367. X    dd = 0;
  368. X    hh = elapsed_seconds / 3600;
  369. X    if(hh > 24)
  370. X    {
  371. X        dd = hh / 24;
  372. X        elapsed_seconds -= dd * 3600 * 24;
  373. X        hh %= 24;
  374. X    }
  375. X    elapsed_seconds -= hh * 3600;
  376. X    mm = elapsed_seconds / 60L;
  377. X    elapsed_seconds -= mm * 60L;
  378. X    ss = elapsed_seconds;
  379. X
  380. X    if(dd)
  381. X        (void)sprintf(elapsed_time_str,"%3ld+%02ld:%02ld:%02ld",dd,hh,mm,ss);
  382. X    else
  383. X        (void)sprintf(elapsed_time_str,"    %2ld:%02ld:%02ld",hh,mm,ss);
  384. X    return(elapsed_time_str);
  385. X}    /* end of get_elapsed_time */
  386. X
  387. X/*+-------------------------------------------------------------------------
  388. X    draw_cpuscale_literals(win)
  389. X--------------------------------------------------------------------------*/
  390. Xvoid
  391. Xdraw_cpuscale_literals(win,y,x)
  392. XWINDOW *win;
  393. Xint y;
  394. Xint x;
  395. X{
  396. X    int x2 = x;
  397. X
  398. X    wmove(win,y,x);
  399. X    use_cp(wscr,cpBANNER);
  400. X    waddstr(win,"---- CPU --- tot usr ker brk ");
  401. X    getyx(win,y,x2);
  402. X    while(x2 < COLS)
  403. X        waddch(win,(chtype)'-'),x2++;
  404. X    use_cp(wscr,cpLIT);
  405. X    wmove(win,y + 1,x);
  406. X    if(CYCLEmsec == 1000L)
  407. X        waddstr(win," Instant %  ");
  408. X    else
  409. X        wprintw(win,"%2d Sec Avg %%",(int)(CYCLEmsec / 1000L));
  410. X    wmove(win,y + 2,x);
  411. X      wprintw(win,"%2d Sec Avg %%",(int)(CYCLEmsec * 5 / 1000L));
  412. X    wmove(win,y + 3,x);
  413. X      wprintw(win,"%2d Sec Avg %%",(int)(CYCLEmsec * 10 / 1000L));
  414. X
  415. X}    /* end of draw_cpuscale_literals */
  416. X
  417. X/*+-------------------------------------------------------------------------
  418. X    update_cpuscale(win,y,width,per_state)
  419. X
  420. X000000000011111111112222222222333333333344444444445555555555666666
  421. X012345678901234567890123456789012345678901234567890123456789012345
  422. Xtot usr ker misc 
  423. X### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  424. X--------------------------------------------------------------------------*/
  425. X#define _CPUSCALE_TX    0
  426. X#define _CPUSCALE_UX    4
  427. X#define _CPUSCALE_KX    8
  428. X#define _CPUSCALE_BX    12
  429. X#define _CPUSCALE_SX    16
  430. X
  431. Xtime_t
  432. Xupdate_cpuscale(win,y,x,width,per_state)
  433. XWINDOW *win;
  434. Xint y;
  435. Xint x;
  436. Xregister width;
  437. Xtime_t *per_state;
  438. X{
  439. X    register itmp;
  440. X    int accum = 0;
  441. X    time_t idle = per_state[CPU_IDLE] + per_state[CPU_WAIT];
  442. X    time_t cpu_ticks_total = idle + per_state[CPU_SXBRK] + 
  443. X                             per_state[CPU_KERNEL] + per_state[CPU_USER];
  444. X    time_t percent_user    = 0;
  445. X    time_t percent_kernel  = 0;
  446. X    time_t percent_break   = 0;
  447. X    time_t percent_busy    = 0;
  448. X
  449. X    if(cpu_ticks_total)
  450. X    {
  451. X        percent_user    = (per_state[CPU_USER]   * 100) / cpu_ticks_total;
  452. X        percent_kernel  = (per_state[CPU_KERNEL] * 100) / cpu_ticks_total;
  453. X        percent_break   = (per_state[CPU_SXBRK]  * 100) / cpu_ticks_total;
  454. X        percent_busy    = percent_user + percent_kernel + percent_break;
  455. X    }
  456. X
  457. X    if(!idle)            /* take care of integer div truncation */
  458. X        percent_busy = 100;
  459. X
  460. X    wmove(win,y, x + _CPUSCALE_TX);
  461. X    if(percent_busy < 70)
  462. X        use_cp(wscr,cpLOW);
  463. X    else if(percent_busy < 90)
  464. X        use_cp(wscr,cpMED);
  465. X    else
  466. X        use_cp(wscr,cpHIGH);
  467. X    wprintw(win,"%3ld",percent_busy);
  468. X
  469. X    wmove(win,y, x + _CPUSCALE_UX);
  470. X    use_cp(wscr,cpINFO);
  471. X    wprintw(win,"%3ld",percent_user);
  472. X    
  473. X    wmove(win,y, x + _CPUSCALE_KX);
  474. X    wprintw(win,"%3ld",percent_kernel);
  475. X    
  476. X    wmove(win,y, x + _CPUSCALE_BX);
  477. X    wprintw(win,"%3ld",percent_break);
  478. X    
  479. X    wmove(win,y, x + _CPUSCALE_SX);
  480. X    use_cp(wscr,cpLOW);
  481. X    itmp = (width * percent_user) / 100;
  482. X    accum += itmp;
  483. X    while(itmp--)
  484. X        waddch(win,(chtype)'u');
  485. X
  486. X    use_cp(wscr,cpMED);
  487. X    itmp = (width * percent_kernel) / 100;
  488. X    accum += itmp;
  489. X    while(itmp--)
  490. X        waddch(win,(chtype)'k');
  491. X
  492. X    use_cp(wscr,cpHIGH);
  493. X    itmp = (width * percent_break) / 100;
  494. X    accum += itmp;
  495. X    while(itmp--)
  496. X        waddch(win,(chtype)'b');
  497. X
  498. X    if((percent_busy > 98) && ((width - accum) > 0))
  499. X    {
  500. X        waddch(win,(chtype)'*');
  501. X        accum++;
  502. X    }
  503. X
  504. X    use_cp(wscr,cpLIT);
  505. X    if((itmp = (width - accum)) > 0)
  506. X    {
  507. X        while(itmp--)
  508. X            waddch(win,(chtype)' ');
  509. X    }
  510. X    return(cpu_ticks_total);
  511. X}    /* end of update_cpuscale */
  512. X
  513. X/*+-------------------------------------------------------------------------
  514. X    calc_cpu_avg(per_state) - add per_state array to avg array
  515. X--------------------------------------------------------------------------*/
  516. Xvoid
  517. Xcalc_cpu_avg(per_state)
  518. Xtime_t per_state[];
  519. X{
  520. X    register itmp;
  521. X
  522. X    if(!cpu_avg_init)
  523. X    {
  524. X        for(itmp = 0; itmp < CPU_AVG_MAX; itmp++)
  525. X            (void)memcpy(cpu_avg[itmp],per_state,sizeof(time_t) * 5);
  526. X        cpu_avg_init = 1;
  527. X    }
  528. X    else
  529. X    {
  530. X        for(itmp = 0; itmp < CPU_AVG_MAX - 1; itmp++)
  531. X            (void)memcpy(cpu_avg[itmp],cpu_avg[itmp + 1],sizeof(time_t) * 5);
  532. X        (void)memcpy(cpu_avg[itmp],per_state,sizeof(time_t) * 5);
  533. X    }
  534. X
  535. X}    /* end of calc_cpu_avg */
  536. X
  537. X/*+-------------------------------------------------------------------------
  538. X    get_cpu_avg(cpu_ticks,period)
  539. X--------------------------------------------------------------------------*/
  540. Xget_cpu_avg(cpu_ticks,period)
  541. Xtime_t cpu_ticks[];
  542. Xint period;
  543. X{
  544. X    register iperiod = CPU_AVG_MAX;
  545. X    register istate;
  546. X    register count = period;
  547. X
  548. X    for(istate = 0; istate < 5; istate++)
  549. X        cpu_ticks[istate] = 0;
  550. X
  551. X    while(count--)
  552. X    {
  553. X        iperiod--;
  554. X        for(istate = 0; istate < 5; istate++)
  555. X        {
  556. X            cpu_ticks[istate] += (cpu_avg[iperiod])[istate];
  557. X        }
  558. X    }
  559. X
  560. X    for(istate = 0; istate < 5; istate++)
  561. X        cpu_ticks[istate] /= period;
  562. X
  563. X}    /* end of get_cpu_avg */
  564. X
  565. X/*+-------------------------------------------------------------------------
  566. X    draw_waitscale_literals(win)
  567. X--------------------------------------------------------------------------*/
  568. Xvoid
  569. Xdraw_waitscale_literals(win,y,x)
  570. XWINDOW *win;
  571. Xint y;
  572. Xint x;
  573. X{
  574. X    int x2 = x;
  575. X
  576. X    wmove(win,y,x);
  577. X    use_cp(wscr,cpBANNER);
  578. X    waddstr(win,"---- Wait -- tot  io pio swp -- (% of real time) ");
  579. X    getyx(win,y,x2);
  580. X    while(x2 < COLS)
  581. X        waddch(win,(chtype)'-'),x2++;
  582. X    use_cp(wscr,cpLIT);
  583. X    wmove(win,y + 1,x);
  584. X    if(CYCLEmsec == 1000L)
  585. X        waddstr(win," Instant %  ");
  586. X    else
  587. X        wprintw(win,"%2d Sec Avg %%",(int)(CYCLEmsec / 1000L));
  588. X    wmove(win,y + 2,x);
  589. X      wprintw(win,"%2d Sec Avg %%",(int)(CYCLEmsec * 5 / 1000L));
  590. X    wmove(win,y + 3,x);
  591. X      wprintw(win,"%2d Sec Avg %%",(int)(CYCLEmsec * 10 / 1000L));
  592. X
  593. X}    /* end of draw_waitscale_literals */
  594. X
  595. X/*+-------------------------------------------------------------------------
  596. X    draw_per_sec_literals(win)
  597. X--------------------------------------------------------------------------*/
  598. Xvoid
  599. Xdraw_per_sec_literals(win,y,x)
  600. XWINDOW *win;
  601. Xint y;
  602. Xint x;
  603. X{
  604. X
  605. X    wmove(win,y,x);
  606. X    use_cp(wscr,cpBANNER);
  607. X    waddstr(win,"---- Sysinfo/Minfo --- (last ");
  608. X    getyx(win,stat_period_msec_y,stat_period_msec_x);
  609. X     wprintw(win," %4ld msec activity) ",CYCLEmsec);
  610. X    getyx(win,y,x);
  611. X    while(x < getmaxx(win))
  612. X        waddch(win,(chtype)'-'),x++;
  613. X
  614. X}    /* end of draw_per_sec_literals */
  615. X
  616. X/*+-------------------------------------------------------------------------
  617. X    update_waitscale(win,y,width,per_state)
  618. X
  619. X000000000011111111112222222222333333333344444444445555555555666666
  620. X012345678901234567890123456789012345678901234567890123456789012345
  621. Xtot  io pio swp  
  622. X### ### ### ### xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  623. X--------------------------------------------------------------------------*/
  624. X#define _WAITSCALE_TX    0
  625. X#define _WAITSCALE_IX    4
  626. X#define _WAITSCALE_PX    8
  627. X#define _WAITSCALE_WX    12
  628. X#define _WAITSCALE_SX    16
  629. X
  630. Xtime_t
  631. Xupdate_waitscale(win,y,x,width,per_state,total_ticks)
  632. XWINDOW *win;
  633. Xint y;
  634. Xint x;
  635. Xregister width;
  636. Xtime_t *per_state;
  637. Xtime_t total_ticks;
  638. X{
  639. X    register itmp;
  640. X    int accum = 0;
  641. X    time_t percent_io = 0L;
  642. X    time_t percent_swap = 0L;
  643. X    time_t percent_pio = 0L;
  644. X    time_t percent_total_wait;
  645. X    time_t total_wait;
  646. X
  647. X/* crock: because of latency, total_ticks < all wait ticks sometimes */
  648. X    total_wait = per_state[W_IO] + per_state[W_SWAP] + per_state[W_PIO];
  649. X    if(total_ticks < total_wait)
  650. X        total_ticks = total_wait;
  651. X
  652. X    if(total_ticks)
  653. X    {
  654. X        percent_io    = (per_state[W_IO]   * 100) / total_ticks;
  655. X        percent_pio   = (per_state[W_PIO]  * 100) / total_ticks;
  656. X        percent_swap  = (per_state[W_SWAP] * 100) / total_ticks;
  657. X    }
  658. X
  659. X    wmove(win,y, x + _WAITSCALE_TX);
  660. X    percent_total_wait = percent_io + percent_swap + percent_pio;
  661. X    if(percent_total_wait < 30)
  662. X        use_cp(wscr,cpLOW);
  663. X    else if(percent_total_wait < 50)
  664. X        use_cp(wscr,cpMED);
  665. X    else
  666. X        use_cp(wscr,cpHIGH);
  667. X    wprintw(win,"%3ld",percent_total_wait);
  668. X
  669. X    use_cp(wscr,cpINFO);
  670. X    wmove(win,y, x + _WAITSCALE_IX);
  671. X    wprintw(win,"%3ld",percent_io);
  672. X    
  673. X    wmove(win,y, x + _WAITSCALE_PX);
  674. X    wprintw(win,"%3ld",percent_pio);
  675. X    
  676. X    wmove(win,y, x + _WAITSCALE_WX);
  677. X    wprintw(win,"%3ld",percent_swap);
  678. X    
  679. X    wmove(win,y, x + _WAITSCALE_SX);
  680. X    use_cp(wscr,cpLOW);
  681. X    itmp = (width * percent_io) / 100;
  682. X    accum += itmp;
  683. X    while(itmp--)
  684. X        waddch(win,(chtype)'i');
  685. X
  686. X    use_cp(wscr,cpMED);
  687. X    itmp = (width * percent_pio) / 100;
  688. X    accum += itmp;
  689. X    while(itmp--)
  690. X        waddch(win,(chtype)'p');
  691. X
  692. X    use_cp(wscr,cpHIGH);
  693. X    itmp = (width * percent_swap) / 100;
  694. X    accum += itmp;
  695. X    while(itmp--)
  696. X        waddch(win,(chtype)'s');
  697. X
  698. X    use_cp(wscr,cpLIT);
  699. X    if((itmp = (width - accum)) > 0)
  700. X    {
  701. X        while(itmp--)
  702. X            waddch(win,(chtype)' ');
  703. X    }
  704. X
  705. X}    /* end of update_waitscale */
  706. X
  707. X/*+-------------------------------------------------------------------------
  708. X    calc_wait_avg(per_state) - add per_state array to avg array
  709. X--------------------------------------------------------------------------*/
  710. Xvoid
  711. Xcalc_wait_avg(per_state)
  712. Xtime_t per_state[];
  713. X{
  714. X    register itmp;
  715. X
  716. X    if(!wait_avg_init)
  717. X    {
  718. X        for(itmp = 0; itmp < WAIT_AVG_MAX; itmp++)
  719. X            (void)memcpy(wait_avg[itmp],per_state,sizeof(time_t) * 3);
  720. X        wait_avg_init = 1;
  721. X    }
  722. X    else
  723. X    {
  724. X        for(itmp = 0; itmp < WAIT_AVG_MAX - 1; itmp++)
  725. X            (void)memcpy(wait_avg[itmp],wait_avg[itmp + 1],sizeof(time_t) * 3);
  726. X        (void)memcpy(wait_avg[itmp],per_state,sizeof(time_t) * 3);
  727. X    }
  728. X
  729. X}    /* end of calc_wait_avg */
  730. X
  731. X/*+-------------------------------------------------------------------------
  732. X    get_wait_avg(wait_ticks,period)
  733. X--------------------------------------------------------------------------*/
  734. Xget_wait_avg(wait_ticks,period)
  735. Xtime_t wait_ticks[];
  736. Xint period;
  737. X{
  738. X    register iperiod = WAIT_AVG_MAX;
  739. X    register istate;
  740. X    register count = period;
  741. X
  742. X    for(istate = 0; istate < 3; istate++)
  743. X        wait_ticks[istate] = 0;
  744. X
  745. X    while(count--)
  746. X    {
  747. X        iperiod--;
  748. X        for(istate = 0; istate < 3; istate++)
  749. X        {
  750. X            wait_ticks[istate] += (wait_avg[iperiod])[istate];
  751. X        }
  752. X    }
  753. X
  754. X    for(istate = 0; istate < 3; istate++)
  755. X        wait_ticks[istate] /= period;
  756. X
  757. X}    /* end of get_wait_avg */
  758. X
  759. X/*+-------------------------------------------------------------------------
  760. X    extra_static_stuff()/extra_info_stuff() - for 43 line display
  761. X--------------------------------------------------------------------------*/
  762. Xvoid
  763. Xextra_static_stuff()
  764. X{
  765. X    display_var(wscr,EXTRA_TLY,EXTRA1_TLX);
  766. X#if defined(HAS_BOOTINFO)
  767. X    display_bootinfo(wscr,EXTRA_TLY,EXTRA2_TLX);
  768. X#endif
  769. X    display_tune(wscr,EXTRA_TLY,EXTRA3_TLX);
  770. X}    /* end of extra_static_stuff */
  771. X
  772. Xvoid
  773. Xextra_info_stuff()
  774. X{
  775. X    display_proc(wscr,EXTRA_TLY,EXTRA4_TLX);
  776. X}    /* end of extra_info_stuff */
  777. X
  778. X/*+-------------------------------------------------------------------------
  779. X    read_sysinfo_and_minfo()
  780. X--------------------------------------------------------------------------*/
  781. Xvoid
  782. Xread_sysinfo_and_minfo()
  783. X{
  784. X#if defined(HAS_TIMEB)
  785. X    timeb_last_info_read = timeb_info_read;
  786. X    (void)ftime(&timeb_info_read);
  787. X#endif
  788. X    kread((caddr_t)&sysinfo,sysinfoaddr,sizeof(sysinfo));
  789. X    kread((caddr_t)&minfo,minfoaddr,sizeof(minfo));
  790. X}    /* end of read_sysinfo_and_minfo */
  791. X
  792. X/*+-------------------------------------------------------------------------
  793. X    main(argc,argv,envp)
  794. X--------------------------------------------------------------------------*/
  795. X/*ARGSUSED*/
  796. Xmain(argc,argv,envp)
  797. Xint argc;
  798. Xchar **argv;
  799. Xchar **envp;
  800. X{
  801. X    register itmp;
  802. X    register char *cptr;
  803. X    register chtype cmd;
  804. X    register chtype initial_cmd = 0;
  805. X    int errflg = 0;
  806. X    int plock_indicator = 0;
  807. X    time_t total_ticks;
  808. X    long stat_period_msec;
  809. X    long nap_msec;
  810. X    long nap_msec_remaining;
  811. X    int y,x;
  812. X    int banner_free_x;
  813. X    long ltmp, now;
  814. X#if !defined(HAS_TIMEB)
  815. X    long then;
  816. X#endif /* HAS_TIMEB */
  817. X    struct tm *lt;
  818. X    static char stdoutbuf[2048];
  819. X    char s80[80];
  820. X    extern int optind;
  821. X
  822. X/*
  823. X * curses works better if standard output is fully buffered
  824. X */
  825. X    (void)setvbuf(stdout,stdoutbuf,_IOFBF,sizeof(stdoutbuf));
  826. X
  827. X/*
  828. X * check out command line
  829. X */
  830. X    while((itmp = getopt(argc,argv,"lPnpstw")) != -1)
  831. X    {
  832. X        switch(itmp)
  833. X        {
  834. X            case 'P':
  835. X            case 'p':
  836. X#if defined(DPT_STREAMS)
  837. X            case 'n':
  838. X#endif
  839. X#if defined(DPT_TABLE)
  840. X            case 't':
  841. X#endif
  842. X#if defined(DPT_SIO)
  843. X            case 's':
  844. X#endif
  845. X#if defined(DPT_WD)
  846. X            case 'w':
  847. X#endif
  848. X                initial_cmd = (chtype) itmp;
  849. X                break;
  850. X            case 'l':
  851. X                plock_indicator = 1;
  852. X                break;
  853. X            case '?':
  854. X                errflg++;
  855. X        }
  856. X    }
  857. X    if(errflg || (optind != argc))
  858. X    {
  859. X        static char *usage_str[]=
  860. X        {
  861. X            "-l lock process into memory (if root)",
  862. X            "-p begin with short ps display",
  863. X            "-P begin with long ps display (if 43 line screen)",
  864. X            (char *)0
  865. X        };
  866. X        char **cpptr = usage_str;
  867. X        fprintf(stderr,"usage: %s [-l] [-p | -P]\n",basename(*argv));
  868. X        while(*cpptr)
  869. X            (void)fprintf(stderr,"%s\n",*(cpptr++));
  870. X        exit(1);
  871. X    }
  872. X
  873. X/*
  874. X * if man wants to plock() try it; fail silently if non-root
  875. X */
  876. X    if(plock_indicator && plock(PROCLOCK))
  877. X    {
  878. X        nice(-5);
  879. X        plock_indicator = 0;
  880. X    }
  881. X
  882. X/*
  883. X * Real(tm) performance monitor users will have done a kernel link
  884. X * and won't need to rely on /etc/systemid
  885. X */
  886. X    if(uname(&utsname))
  887. X    {
  888. X        leave_text("uname failed",255);
  889. X        exit(1);
  890. X    }
  891. X
  892. X/*
  893. X * allocate memory for cpu time array averaging buckets
  894. X */
  895. X    for(itmp = 0; itmp < CPU_AVG_MAX; itmp++)
  896. X    {
  897. X        if(!(cpu_avg[itmp] = (time_t *)malloc(sizeof(time_t) * 5)))
  898. X            leave_text("cannot alloc memory for cpu avg arrays",1);
  899. X    }
  900. X
  901. X/*
  902. X * allocate memory for wait time array averaging buckets
  903. X */
  904. X    for(itmp = 0; itmp < WAIT_AVG_MAX; itmp++)
  905. X    {
  906. X        if(!(wait_avg[itmp] = (time_t *)malloc(sizeof(time_t) * 3)))
  907. X            leave_text("cannot alloc memory for wait avg arrays",1);
  908. X    }
  909. X
  910. X/*
  911. X * initialize curses environment
  912. X */
  913. X    if(!initscr())
  914. X    {
  915. X        (void)printf("curses init failed\n");
  916. X        exit(1);
  917. X    }
  918. X#if defined(COLOR_PAIR)
  919. X    has_colors_kludge();
  920. X#endif
  921. X    clear();
  922. X    refresh();
  923. X
  924. X    if((LINES < 24) || (COLS < 80))
  925. X    {
  926. X        waddstr(stdscr,"\n\n\nNeed at least 80x24 screen\n\n");
  927. X        refresh();
  928. X        endwin();
  929. X        exit(1);
  930. X    }
  931. X
  932. X    noecho();
  933. X    keypad(stdscr,TRUE);
  934. X    typeahead(-1);
  935. X#if !defined(HAS_RDCHK)
  936. X    cbreak ();
  937. X#endif
  938. X
  939. X/*
  940. X * see u386mon.h cXXX definitons for A_BOLD requirements for bright colors
  941. X */
  942. X#if defined(COLOR_PAIR)
  943. X    if(color_avail)
  944. X    {
  945. X        start_color();
  946. X        init_pair(cpLIT,cBLU,cBLK);
  947. X        init_pair(cpINFO,cGRN,cBLK);
  948. X        init_pair(cpLOW,cLTG,cBLK);
  949. X        init_pair(cpMED,cYEL,cBLK);
  950. X        init_pair(cpHIGH,cRED,cBLK);
  951. X        init_pair(cpBANNER,cBLK,cWHT);
  952. X        init_pair(cpREVERSE,cRED,cWHT);
  953. X        init_pair(cpBANWARN,cBLU,cWHT);
  954. X    }
  955. X#endif
  956. X
  957. X#if (defined(i386) || defined(i486)) && defined(HI_BIT_CAN_BE_SET)
  958. X    /* a hack for now -- assuming AT char set */
  959. X    /* This does NOT work with SCO ... rumours are it does work somewhere */
  960. X    acs_map['l'] = A_ALTCHARSET | sTL;    
  961. X    acs_map['m'] = A_ALTCHARSET | sTR;    
  962. X    acs_map['j'] = A_ALTCHARSET | sBL;    
  963. X    acs_map['k'] = A_ALTCHARSET | sBR;    
  964. X    acs_map['x'] = A_ALTCHARSET | sVR;        /* vertical rule */
  965. X    acs_map['q'] = A_ALTCHARSET | sHR;        /* horizontal rule */
  966. X    acs_map['t'] = A_ALTCHARSET | sLT;        /* left hand T */
  967. X    acs_map['u'] = A_ALTCHARSET | sRT;        /* right hand T */
  968. X#endif
  969. X
  970. X    if(!(pscr = mkpanel(LINES - 1,COLS,0,0,"main")))
  971. X    {
  972. X        addstr("cannot make screen panel");
  973. X        refresh();
  974. X        endwin();
  975. X        exit(1);
  976. X    }
  977. X    wscr = panel_window(pscr);
  978. X    top_panel(pscr);
  979. X#if !defined(HAS_RDCHK)
  980. X    nodelay (wscr, TRUE);
  981. X#endif
  982. X
  983. X/*
  984. X * catch signals that can leave our tty in disarray
  985. X */
  986. X    for(itmp = SIGHUP; itmp < SIGSYS; itmp++)
  987. X        signal(itmp,caught_signal);
  988. X
  989. X/*
  990. X * read nlist symbols, open /dev/kmem, /dev/mem, /dev/swap,
  991. X * initialize detail environment
  992. X * (all of these must occur after curses init)
  993. X * drop euid and egid (after opening privileged mem/devices)
  994. X * initialize process status uid->name hasher
  995. X */
  996. X    nlsym_read();
  997. X    kinit(0);    /* /dev/kmem, read access only */
  998. X    minit(0);    /* /dev/mem,  read access only */
  999. X    sinit();    /* /dev/swap, only read access available */
  1000. X    (void)setuid(getuid());    /* some people run us setuid, so clen that up */
  1001. X    (void)setgid(getgid());    /* now that we have the fds open, drop egid */
  1002. X    kread((caddr_t)&v,vaddr,sizeof(v));
  1003. X    detail_init();
  1004. X
  1005. X/*
  1006. X * start fireworks
  1007. X */
  1008. X    wmove(wscr,0,0);
  1009. X    use_cp(wscr,cpBANNER);
  1010. X    waddch(wscr,(chtype)' ');
  1011. X    waddstr(wscr,basename(*argv));
  1012. X    waddch(wscr,(chtype)' ');
  1013. X    waddstr(wscr,revision);
  1014. X    wprintw(wscr,"%d",PATCHLEVEL);    /* good for nine patches */
  1015. X
  1016. X#if defined(mips)
  1017. X    waddstr(wscr,"/Tandem");
  1018. X#else
  1019. X#if defined(M_UNIX)
  1020. X    waddstr(wscr,"/SCO");
  1021. X#else
  1022. X#if defined(ISC)
  1023. X#if defined(DELL)
  1024. X    waddstr(wscr,"/Dell");
  1025. X#else
  1026. X    waddstr(wscr,"/ISC");
  1027. X#endif
  1028. X#endif
  1029. X#endif
  1030. X#endif
  1031. X    
  1032. X#if defined(DELL)
  1033. X    wprintw(wscr," Rel %s Ver %s - Node %s ",
  1034. X        utsname.release,utsname.version,utsname.nodename);
  1035. X#else
  1036. X#if defined(m68k)
  1037. X    wprintw(wscr," %s %s - %s ",
  1038. X        utsname.release,utsname.version,utsname.nodename);
  1039. X#else
  1040. X    /* utsname.release and utsname.version are practcally redundant here */
  1041. X    wprintw(wscr," %s - %s ",utsname.release,utsname.nodename);
  1042. X#endif
  1043. X#endif
  1044. X    getyx(wscr,y,x);
  1045. X    banner_free_x = x+2;
  1046. X    while(x < getmaxx(wscr))
  1047. X        waddch(wscr,(chtype)' '),x++;
  1048. X    wmove(wscr,0,COLS - 9);
  1049. X    waddstr(wscr,"wht@n4hgf");
  1050. X    if(plock_indicator)
  1051. X    {
  1052. X        wmove(wscr,0,banner_free_x);
  1053. X        use_cp(wscr,cpMED);
  1054. X        waddstr(wscr," PLOCK ");
  1055. X        use_cp(wscr,cpBANNER);
  1056. X    }
  1057. X    wmove(wscr,3,0);
  1058. X    use_cp(wscr,cpMED);
  1059. X    waddstr(wscr,"WAIT");
  1060. X    pflush();
  1061. X
  1062. X    wmove(stdscr,CMD_TLY,0);
  1063. X    use_cp(stdscr,cpBANNER);
  1064. X    if(LINES >= 43)
  1065. X        waddstr(stdscr,"ESC=quit P,p=ps m=main ");
  1066. X    else
  1067. X        waddstr(stdscr,"ESC=quit p=ps e=extra m=main ");
  1068. X#if defined(DPT_SIO)
  1069. X    waddstr(stdscr,"s=sio ");
  1070. X#endif
  1071. X#if defined(DPT_TABLE)
  1072. X    waddstr(stdscr,"t=table ");
  1073. X#endif
  1074. X#if defined(DPT_STREAMS)
  1075. X    waddstr(stdscr,"n=net ");
  1076. X#endif
  1077. X#if defined(DPT_WD)
  1078. X    waddstr(stdscr,"w=disk ");
  1079. X#endif
  1080. X
  1081. X    if(getuid() == 0)    /* root can launch fireworks very predictably */
  1082. X        waddstr(stdscr,"l/u=lock ");
  1083. X    waddstr(stdscr,"+/-=rate");
  1084. X    getyx(stdscr,y,x);
  1085. X    while(x < getmaxx(stdscr))
  1086. X        waddch(stdscr,(chtype)' '),x++;
  1087. X    use_cp(stdscr,cpLIT);
  1088. X    use_cp(wscr,cpLIT);
  1089. X
  1090. X/*
  1091. X * make initial kmem readings
  1092. X */
  1093. X    hz = (cptr = getenv("HZ")) ? atoi(cptr) : HZ;
  1094. X    if(!hz)        /* avoid problem reported by Ian Reid <ir@crosfield.co.uk> */
  1095. X        hz = HZ;
  1096. X    kread((caddr_t)&maxmem,maxmemaddr,sizeof(maxmem));
  1097. X    kread((caddr_t)&tune,tuneaddr,sizeof(tune));
  1098. X    kread((caddr_t)&v,vaddr,sizeof(v));
  1099. X
  1100. X    kread((caddr_t)&nswap,nswapaddr,sizeof(nswap));
  1101. X    itmp = -1;
  1102. X#if defined(S3BSWPI)    /* 68000 handled here, not AT&T 3B */
  1103. X    itmp = _sysm68k (S3BSWPI,&swapint);    /* per nba@sysware.dk */
  1104. X#endif
  1105. X#if defined(SI86SWPI)
  1106. X    itmp = sysi86(SI86SWPI,&swapint);
  1107. X#endif
  1108. X#if defined(SMIPSSWPI)
  1109. X    itmp = sysmips(SMIPSSWPI,&swapint);
  1110. X#endif
  1111. X    if(!itmp)
  1112. X    {
  1113. X        nswap = 0;
  1114. X        for (itmp = 0; itmp < MSFILES; itmp++)
  1115. X            nswap += swaptab[itmp].st_npgs * NBPP / NBPSCTR;
  1116. X    }
  1117. X
  1118. X#if defined(HAS_BOOTINFO)
  1119. X    kread((caddr_t)&bootinfo,bootinfoaddr,sizeof(bootinfo));
  1120. X#endif
  1121. X
  1122. X    read_sysinfo_and_minfo();
  1123. X    sysinfo_last = sysinfo;
  1124. X    minfo_last = minfo;
  1125. X
  1126. X#if defined(HAS_TIMEB)
  1127. X    timeb_last_info_read = timeb_info_read;
  1128. X#else
  1129. X    (void)time (&now);
  1130. X#endif
  1131. X
  1132. X/*
  1133. X * initialize static display (literals)
  1134. X */
  1135. X    draw_cpuscale_literals(wscr,CPUSCALE_TLY,0);
  1136. X    draw_waitscale_literals(wscr,WAITSCALE_TLY,0);
  1137. X    draw_per_sec_literals(wscr,PER_SEC_TLY,0);
  1138. X
  1139. X    if(LINES >= 43)
  1140. X        extra_static_stuff();
  1141. X
  1142. X/*
  1143. X * while(user_not_bored) entertain_and_inform_user();
  1144. X */
  1145. X#ifdef HAS_NAP
  1146. X    nap(CYCLEmsec);
  1147. X#else
  1148. X    napms(CYCLEmsec);
  1149. X#endif
  1150. X    while(1)
  1151. X    {
  1152. X
  1153. X#if defined(HAS_RDCHK)
  1154. X        if(rdchk(0))
  1155. X            goto RDCHK;
  1156. X#endif
  1157. X
  1158. X#if defined(HAS_TIMEB)
  1159. X        ftime(&timeb_cycle_start);
  1160. X        stat_period_msec = delta_msec(timeb_info_read,timeb_last_info_read);
  1161. X        (void)time(&now);
  1162. X#else
  1163. X        then = now;
  1164. X        (void)time(&now);
  1165. X        stat_period_msec = (now - then) * 1000L;
  1166. X#endif
  1167. X
  1168. X        lt = localtime(&now);
  1169. X        wmove(wscr,0,COLS - 18);
  1170. X        use_cp(wscr,cpBANNER);
  1171. X        wprintw(wscr,"%02d:%02d:%02d",lt->tm_hour,lt->tm_min,lt->tm_sec);
  1172. X
  1173. X        kread((caddr_t)&freemem,freememaddr,sizeof(freemem));
  1174. X        read_sysinfo_and_minfo();
  1175. X
  1176. X        /* heuristic validity determination */
  1177. X        wmove(wscr,0,banner_free_x + 8);
  1178. X        if((itmp = stat_period_msec > (CYCLEmsec + 3000L)) ||
  1179. X            (invalidity > INVALID_STATE))
  1180. X        {
  1181. X            use_cp(wscr,cpHIGH);
  1182. X            waddstr(wscr," INVALID ");
  1183. X            if(itmp)
  1184. X            {    /* gack - a hack */
  1185. X                itmp = (stat_period_msec - CYCLEmsec) / 1000;
  1186. X                if(itmp > 4)
  1187. X                    itmp = 4;
  1188. X                invalidity += INVALID_STATE + itmp;
  1189. X            }
  1190. X        }
  1191. X        else if((itmp = (stat_period_msec > (CYCLEmsec + 1500L))) ||
  1192. X                (invalidity > INEXACT_STATE))
  1193. X        {
  1194. X            use_cp(wscr,cpMED);
  1195. X            waddstr(wscr," INEXACT ");
  1196. X            if(itmp)
  1197. X                invalidity += INEXACT_STATE;
  1198. X        }
  1199. X        if(invalidity && !(--invalidity))
  1200. X        {
  1201. X            use_cp(wscr,cpBANNER);
  1202. X            waddstr(wscr,"         ");
  1203. X        }
  1204. X        if(stat_period_msec > (CYCLEmsec + 1000L))
  1205. X            use_cp(wscr,cpREVERSE);
  1206. X        else if(stat_period_msec > (CYCLEmsec + 500L))
  1207. X            use_cp(wscr,cpBANWARN);
  1208. X        else
  1209. X            use_cp(wscr,cpBANNER);
  1210. X        wmove(wscr,stat_period_msec_y,stat_period_msec_x);
  1211. X        wprintw(wscr,"%5ld",stat_period_msec);
  1212. X
  1213. X
  1214. X#if defined(FIRST_TRY)
  1215. X        /* going this way seems to get cpu+wait ticks > real time */
  1216. X        for (itmp = 0; itmp < 5; itmp++)
  1217. X            cpu_ticks[itmp] = sysidelta(cpu[itmp]);
  1218. X        for (itmp = 0; itmp < 3; itmp++)
  1219. X            wait_ticks[itmp] = sysidelta(wait[itmp]);
  1220. X#else
  1221. X        for (itmp = 0; itmp < 5; itmp++)
  1222. X        {
  1223. X            if(itmp != CPU_WAIT)
  1224. X                cpu_ticks[itmp] = sysidelta(cpu[itmp]);
  1225. X        }
  1226. X        cpu_ticks[CPU_WAIT] = 0;
  1227. X        for (itmp = 0; itmp < 3; itmp++)
  1228. X            cpu_ticks[CPU_WAIT] += (wait_ticks[itmp] = sysidelta(wait[itmp]));
  1229. X#endif
  1230. X
  1231. X        total_ticks = update_cpuscale(wscr,CPUSCALE_TLY + 1,CPUSCALE_SX,
  1232. X            CPUSCALE_WIDTH,cpu_ticks);
  1233. X
  1234. X        update_waitscale(wscr,WAITSCALE_TLY + 1,WAITSCALE_SX,
  1235. X            WAITSCALE_WIDTH,wait_ticks,total_ticks);
  1236. X
  1237. X        calc_cpu_avg(cpu_ticks);
  1238. X        calc_wait_avg(wait_ticks);
  1239. X
  1240. X        get_cpu_avg(cpu_ticks,5);
  1241. X        total_ticks = update_cpuscale(wscr,CPUSCALE_TLY + 2,CPUSCALE_SX,
  1242. X            CPUSCALE_WIDTH,cpu_ticks);
  1243. X
  1244. X        get_wait_avg(wait_ticks,5);
  1245. X        update_waitscale(wscr,WAITSCALE_TLY + 2,WAITSCALE_SX,
  1246. X            WAITSCALE_WIDTH,wait_ticks,total_ticks);
  1247. X
  1248. X        get_cpu_avg(cpu_ticks,10);
  1249. X        total_ticks = update_cpuscale(wscr,CPUSCALE_TLY + 3,CPUSCALE_SX,
  1250. X            CPUSCALE_WIDTH,cpu_ticks);
  1251. X
  1252. X        get_wait_avg(wait_ticks,10);
  1253. X        update_waitscale(wscr,WAITSCALE_TLY + 3,WAITSCALE_SX,
  1254. X            WAITSCALE_WIDTH,wait_ticks,total_ticks);
  1255. X
  1256. X        use_cp(wscr,cpINFO);
  1257. X        y = PER_SEC_TLY + 1;
  1258. X        wmove(wscr,y++,PER_SEC1_TLX);
  1259. X        disp_info_long(wscr,"bread    ","%7ld",sysidelta(bread));
  1260. X        wmove(wscr,y++,PER_SEC1_TLX);
  1261. X        disp_info_long(wscr,"bwrite   ","%7ld",sysidelta(bwrite));
  1262. X        wmove(wscr,y++,PER_SEC1_TLX);
  1263. X        if((ltmp = sysidelta(lread) - myreadcnt) < 0)
  1264. X            ltmp = 0;
  1265. X        disp_info_long(wscr,"lread    ","%7ld",ltmp);
  1266. X        myreadcnt = 0;    /* reset /dev/{mem,kmem,swap} read count */
  1267. X        wmove(wscr,y++,PER_SEC1_TLX);
  1268. X        disp_info_long(wscr,"lwrite   ","%7ld",sysidelta(lwrite));
  1269. X        wmove(wscr,y++,PER_SEC1_TLX);
  1270. X        disp_info_long(wscr,"phread   ","%7ld",sysidelta(phread));
  1271. X        wmove(wscr,y++,PER_SEC1_TLX);
  1272. X        disp_info_long(wscr,"phwrite  ","%7ld",sysidelta(phwrite));
  1273. X        wmove(wscr,y++,PER_SEC1_TLX);
  1274. X        disp_info_long(wscr,"swapin   ","%7ld",sysidelta(swapin));
  1275. X        wmove(wscr,y++,PER_SEC1_TLX);
  1276. X        disp_info_long(wscr,"swapout  ","%7ld",sysidelta(swapout));
  1277. X        wmove(wscr,y++,PER_SEC1_TLX);
  1278. X        disp_info_long(wscr,"bswapin  ","%7ld",sysidelta(bswapin));
  1279. X        wmove(wscr,y++,PER_SEC1_TLX);
  1280. X        disp_info_long(wscr,"bswapout ","%7ld",sysidelta(bswapout));
  1281. X        wmove(wscr,y++,PER_SEC1_TLX);
  1282. X        disp_info_long(wscr,"iget     ","%7ld",sysidelta(iget));
  1283. X        wmove(wscr,y++,PER_SEC1_TLX);
  1284. X        disp_info_long(wscr,"namei    ","%7ld",sysidelta(namei));
  1285. X        wmove(wscr,y++,PER_SEC1_TLX);
  1286. X        disp_info_long(wscr,"dirblk   ","%7ld",sysidelta(dirblk));
  1287. X
  1288. X        y = PER_SEC_TLY + 1;
  1289. X        wmove(wscr,y++,PER_SEC2_TLX);
  1290. X        if((ltmp = sysidelta(readch) - myreadlen) < 0)
  1291. X            ltmp = 0;
  1292. X        disp_info_long(wscr,"readch  ","%7ld",ltmp);
  1293. X        myreadlen = 0;    /* reset /dev/{mem,kmem,swap} read count */
  1294. X
  1295. X        wmove(wscr,y++,PER_SEC2_TLX);
  1296. X        disp_info_long(wscr,"writch  ","%7ld",sysidelta(writech));
  1297. X
  1298. X        wmove(wscr,y++,PER_SEC2_TLX);
  1299. X        disp_info_long(wscr,"rawch   ","%7ld",sysidelta(rawch));
  1300. X        wmove(wscr,y++,PER_SEC2_TLX);
  1301. X        disp_info_long(wscr,"canch   ","%7ld",sysidelta(canch));
  1302. X        wmove(wscr,y++,PER_SEC2_TLX);
  1303. X        disp_info_long(wscr,"outch   ","%7ld",sysidelta(outch));
  1304. X
  1305. X        wmove(wscr,y++,PER_SEC2_TLX);
  1306. X        disp_info_long(wscr,"msg     ","%7ld",sysidelta(msg));
  1307. X        wmove(wscr,y++,PER_SEC2_TLX);
  1308. X        disp_info_long(wscr,"sema    ","%7ld",sysidelta(sema));
  1309. X
  1310. X        wmove(wscr,y++,PER_SEC2_TLX);
  1311. X        disp_static_long(wscr, "maxmem  ","%6ldk",(long)maxmem * NBPP / 1024);
  1312. X        wmove(wscr,y++,PER_SEC2_TLX);
  1313. X        disp_info_long(wscr,   "frmem   ","%6ldk",(long)freemem * NBPP / 1024);
  1314. X        wmove(wscr,y++,PER_SEC2_TLX);
  1315. X        disp_info_int (wscr,   "mem used","%6d%%",
  1316. X            100 - (int)((freemem * 100) / maxmem));
  1317. X
  1318. X        wmove(wscr,y++,PER_SEC2_TLX);
  1319. X        disp_static_int(wscr, "nswap   ","%6ldk",nswap * NBPSCTR / 1024);
  1320. X        wmove(wscr,y++,PER_SEC2_TLX);
  1321. X        disp_info_long(wscr,  "frswp   ","%6ldk",minfo.freeswap* NBPSCTR/1024);
  1322. X        wmove(wscr,y++,PER_SEC2_TLX);
  1323. X        disp_info_int(wscr,   "swp used","%6d%%",
  1324. X            100 - (int)((minfo.freeswap * 100) / nswap));
  1325. X
  1326. X        y = PER_SEC_TLY + 1;
  1327. X        wmove(wscr,y++,PER_SEC3_TLX);
  1328. X        disp_info_long(wscr,"pswitch ","%5ld",sysidelta(pswitch));
  1329. X        wmove(wscr,y++,PER_SEC3_TLX);
  1330. X        disp_info_long(wscr,"syscall ","%5ld",sysidelta(syscall));
  1331. X        wmove(wscr,y++,PER_SEC3_TLX);
  1332. X        disp_info_long(wscr,"sysread ","%5ld",sysidelta(sysread));
  1333. X        wmove(wscr,y++,PER_SEC3_TLX);
  1334. X        disp_info_long(wscr,"syswrit ","%5ld",sysidelta(syswrite));
  1335. X        wmove(wscr,y++,PER_SEC3_TLX);
  1336. X        disp_info_long(wscr,"sysfork ","%5ld",sysidelta(sysfork));
  1337. X        wmove(wscr,y++,PER_SEC3_TLX);
  1338. X        disp_info_long(wscr,"sysexec ","%5ld",sysidelta(sysexec));
  1339. X
  1340. X        y++;
  1341. X        wmove(wscr,y++,PER_SEC3_TLX);
  1342. X        disp_info_long(wscr,"runque  ","%5ld",sysidelta(runque));
  1343. X        wmove(wscr,y++,PER_SEC3_TLX);
  1344. X        disp_info_long(wscr,"runocc  ","%5ld",sysidelta(runocc));
  1345. X        wmove(wscr,y++,PER_SEC3_TLX);
  1346. X        disp_info_long(wscr,"swpque  ","%5ld",sysidelta(swpque));
  1347. X        wmove(wscr,y++,PER_SEC3_TLX);
  1348. X        disp_info_long(wscr,"swpocc  ","%5ld",sysidelta(swpocc));
  1349. X
  1350. X        y = PER_SEC_TLY + 1;
  1351. X        wmove(wscr,y++,PER_SEC4_TLX);
  1352. X        disp_info_long(wscr,"vfault  ","%4ld",midelta(vfault));
  1353. X        wmove(wscr,y++,PER_SEC4_TLX);
  1354. X        disp_info_long(wscr,"demand  ","%4ld",midelta(demand));
  1355. X        wmove(wscr,y++,PER_SEC4_TLX);
  1356. X        disp_info_long(wscr,"pfault  ","%4ld",midelta(pfault));
  1357. X        wmove(wscr,y++,PER_SEC4_TLX);
  1358. X        disp_info_long(wscr,"cw      ","%4ld",midelta(cw));
  1359. X        wmove(wscr,y++,PER_SEC4_TLX);
  1360. X        disp_info_long(wscr,"steal   ","%4ld",midelta(steal));
  1361. X        wmove(wscr,y++,PER_SEC4_TLX);
  1362. X        disp_info_long(wscr,"frdpgs  ","%4ld",midelta(freedpgs));
  1363. X#if defined(SVR32)
  1364. X        wmove(wscr,y++,PER_SEC4_TLX);
  1365. X        disp_info_long(wscr,"vfpg    ","%4ld",midelta(vfpg));
  1366. X        wmove(wscr,y++,PER_SEC4_TLX);
  1367. X        disp_info_long(wscr,"sfpg    ","%4ld",midelta(sfpg));
  1368. X        wmove(wscr,y++,PER_SEC4_TLX);
  1369. X        disp_info_long(wscr,"vspg    ","%4ld",midelta(vspg));
  1370. X        wmove(wscr,y++,PER_SEC4_TLX);
  1371. X        disp_info_long(wscr,"sspg    ","%4ld",midelta(sspg));
  1372. X        wmove(wscr,y++,PER_SEC4_TLX);
  1373. X        disp_info_long(wscr,"pnpfault","%4ld",sysidelta(pnpfault));
  1374. X        wmove(wscr,y++,PER_SEC4_TLX);
  1375. X        disp_info_long(wscr,"wrtfault","%4ld",sysidelta(wrtfault));
  1376. X#endif
  1377. X
  1378. X        y = PER_SEC_TLY + 1;
  1379. X        wmove(wscr,y++,PER_SEC5_TLX);
  1380. X        disp_info_long(wscr,"unmodsw ","%3ld",midelta(unmodsw));
  1381. X        wmove(wscr,y++,PER_SEC5_TLX);
  1382. X        disp_info_long(wscr,"unmodfl ","%3ld",midelta(unmodfl));
  1383. X#if defined(SVR32)
  1384. X        wmove(wscr,y++,PER_SEC5_TLX);
  1385. X        disp_info_long(wscr,"psoutok ","%3ld",midelta(psoutok));
  1386. X        wmove(wscr,y++,PER_SEC5_TLX);
  1387. X        disp_info_long(wscr,"psinfai ","%3ld",midelta(psinfail));
  1388. X        wmove(wscr,y++,PER_SEC5_TLX);
  1389. X        disp_info_long(wscr,"psinok  ","%3ld",midelta(psinok));
  1390. X        wmove(wscr,y++,PER_SEC5_TLX);
  1391. X        disp_info_long(wscr,"rsout   ","%3ld",midelta(rsout));
  1392. X        wmove(wscr,y++,PER_SEC5_TLX);
  1393. X        disp_info_long(wscr,"rsin    ","%3ld",midelta(rsin));
  1394. X#endif
  1395. X
  1396. X        y++;
  1397. X        wmove(wscr,y++,PER_SEC5_TLX);
  1398. X        use_cp(wscr,cpLIT);
  1399. X        waddstr(wscr,"pages on   ");
  1400. X        wmove(wscr,y++,PER_SEC5_TLX);
  1401. X        disp_info_long(wscr,"swap  ","%5ld",midelta(swap));
  1402. X        wmove(wscr,y++,PER_SEC5_TLX);
  1403. X        disp_info_long(wscr,"cache ","%5ld",midelta(cache));
  1404. X        wmove(wscr,y++,PER_SEC5_TLX);
  1405. X        disp_info_long(wscr,"file  ","%5ld",midelta(file));
  1406. X
  1407. X        if(LINES >= 43)
  1408. X            extra_info_stuff();
  1409. X
  1410. X        detail_panel_update();
  1411. X
  1412. X        if(initial_cmd)
  1413. X        {
  1414. X            detail_panel_cmd(initial_cmd);
  1415. X            initial_cmd = 0;
  1416. X        }
  1417. X
  1418. X        pflush();
  1419. X
  1420. X        cmd = 0;
  1421. X#if defined(HAS_RDCHK)
  1422. XRDCHK:
  1423. X        while(rdchk(0))
  1424. X#endif
  1425. X        {
  1426. X            switch(cmd = wgetch(wscr))
  1427. X            {
  1428. X                case 'L' & 0x1F:        /* ^L */
  1429. X                case 'R' & 0x1F:        /* ^R */
  1430. X                    clearok (wscr, TRUE);
  1431. X                    touchwin(wscr);
  1432. X                    wrefresh(wscr);
  1433. X                    if(wdet)
  1434. X                    {
  1435. X                        touchwin(wdet);
  1436. X                        wrefresh(wscr);
  1437. X                    }
  1438. X                    break;
  1439. X
  1440. X                case 'q':
  1441. X                case A_ESC:
  1442. X                    goto GOOD_BYE;
  1443. X#if defined(HAS_BOOTINFO)
  1444. X                case 'b':
  1445. X                    if(bootinfo.bootstrlen > 79)
  1446. X                        itmp = 79;
  1447. X                    else
  1448. X                        itmp = bootinfo.bootstrlen;
  1449. X                    kread(s80,bootinfoaddr +
  1450. X                        (bootinfo.bootstr - (caddr_t)&bootinfo),itmp);
  1451. X                    s80[itmp] = 0;
  1452. X                    disp_msg(cpMED,s80);
  1453. X                    break;
  1454. X#endif
  1455. X                case 'e':
  1456. X                case 'P':
  1457. X                case 'p':
  1458. X                case 'm':
  1459. X#if defined(DPT_TABLE)
  1460. X                case 't':
  1461. X#endif
  1462. X#if defined(DPT_STREAMS)
  1463. X                case 'n':
  1464. X#endif
  1465. X#if defined(DPT_SIO)
  1466. X                case 's':
  1467. X#endif
  1468. X#if defined(DPT_WD)
  1469. X                case 'w':
  1470. X#endif
  1471. X                    detail_panel_cmd(cmd);
  1472. X                    break;
  1473. X                case 'l':
  1474. X                    if(!plock_indicator)
  1475. X                    {
  1476. X                        if(!plock(PROCLOCK))
  1477. X                        {
  1478. X                            plock_indicator = 1;
  1479. X                            wmove(wscr,0,banner_free_x);
  1480. X                            use_cp(wscr,cpMED);
  1481. X                            waddstr(wscr," PLOCK ");
  1482. X                            nice(-5);
  1483. X                        }
  1484. X                    }
  1485. X                    break;
  1486. X                case 'u':
  1487. X                    if(plock_indicator)
  1488. X                    {
  1489. X                        if(!plock(UNLOCK))
  1490. X                        {
  1491. X                            plock_indicator = 0;
  1492. X                            wmove(wscr,0,banner_free_x);
  1493. X                            use_cp(wscr,cpBANNER);
  1494. X                            waddstr(wscr,"       ");
  1495. X                            nice(5);
  1496. X                        }
  1497. X                    }
  1498. X                    break;
  1499. X                case '+':
  1500. X                    if(CYCLEmsec < CYCLEmsecMax)
  1501. X                    {
  1502. X                        invalidity += (INEXACT_STATE * (CYCLEmsec + 1000L)) /
  1503. X                                            CYCLEmsec;
  1504. X                        CYCLEmsec += 1000L;
  1505. X                        draw_cpuscale_literals(wscr,CPUSCALE_TLY,0);
  1506. X                        draw_waitscale_literals(wscr,WAITSCALE_TLY,0);
  1507. X                    }
  1508. X                    else beep();
  1509. X                    break;
  1510. X                case '-':
  1511. X                    if(CYCLEmsec > 1000L)
  1512. X                    {
  1513. X                        CYCLEmsec -= 1000L;
  1514. X                        draw_cpuscale_literals(wscr,CPUSCALE_TLY,0);
  1515. X                        draw_waitscale_literals(wscr,WAITSCALE_TLY,0);
  1516. X                    }
  1517. X                    else beep();
  1518. X                    break;
  1519. X                case 0:
  1520. X                case (chtype)-1:
  1521. X                    break;
  1522. X                default:
  1523. X                    beep();
  1524. X                    break;
  1525. X            }
  1526. X        }
  1527. X
  1528. X        /* remember previous statistics for next delta */
  1529. X        sysinfo_last = sysinfo;
  1530. X        minfo_last = minfo;
  1531. X
  1532. X        /* ex-lax: all in the name of regularity */
  1533. X#if defined(HAS_TIMEB)
  1534. X        ftime(&timeb_cycle_end);
  1535. X        nap_msec = CYCLEmsec - delta_msec(timeb_cycle_end,timeb_cycle_start);
  1536. X        if(nap_msec < (CYCLEmsec - 300L))
  1537. X            nap_msec = (CYCLEmsec - 300L);
  1538. X#else
  1539. X        nap_msec = (CYCLEmsec - 300L);
  1540. X#endif
  1541. X
  1542. X        nap_msec_remaining = nap_msec;
  1543. X
  1544. X#if defined(HAS_RDCHK)
  1545. X        while(nap_msec_remaining > 0)
  1546. X        {
  1547. X#ifdef HAS_NAP
  1548. X            nap(250L);
  1549. X#else
  1550. X            napms(250);    /* curses call: alas most round UP to nearest second */
  1551. X#endif
  1552. X            nap_msec_remaining -= 250;
  1553. X            if(rdchk(0))
  1554. X                break;
  1555. X        }
  1556. X#else /* do not have rdchk() */
  1557. X#ifdef HAS_NAP
  1558. X            nap(nap_msec_remaining);
  1559. X#else
  1560. X            napms(nap_msec_remaining);
  1561. X#endif
  1562. X#endif /* HAS_NAP */
  1563. X            
  1564. X    }
  1565. X
  1566. XGOOD_BYE:
  1567. X    leave_text("",0);
  1568. X    /*NOTREACHED*/
  1569. X}    /* end of main */
  1570. X
  1571. X/* vi: set tabstop=4 shiftwidth=4: */
  1572. X/* end of u386mon.c */
  1573. SHAR_EOF
  1574. chmod 0644 u386mon.c ||
  1575. echo 'restore of u386mon.c failed'
  1576. Wc_c="`wc -c < 'u386mon.c'`"
  1577. test 40718 -eq "$Wc_c" ||
  1578.     echo 'u386mon.c: original size 40718, current size' "$Wc_c"
  1579. fi
  1580. # ============= bootinfo.c ==============
  1581. if test -f 'bootinfo.c' -a X"$1" != X"-c"; then
  1582.     echo 'x - skipping bootinfo.c (File already exists)'
  1583. else
  1584. echo 'x - extracting bootinfo.c (Text)'
  1585. sed 's/^X//' << 'SHAR_EOF' > 'bootinfo.c' &&
  1586. X/* CHK=0xA59C */
  1587. X/*+-------------------------------------------------------------------------
  1588. X    bootinfo.c - u386mon bootinfo struct display
  1589. X
  1590. X  Defined functions:
  1591. X    bmemf_text(flags)
  1592. X    display_bootinfo(win,y,x)
  1593. X
  1594. XWe try to be dynamic with memory block counts, but if the sum of
  1595. Xmemavailcnt and memusedcnt ever exceeds 7, we will lose in 24 line
  1596. Xsessions (8 in 25 line, 9 in 43 line)
  1597. X
  1598. X
  1599. X--------------------------------------------------------------------------*/
  1600. X/*+:EDITS:*/
  1601. X/*:07-15-1992-14:31-wht@n4hgf-2.60 release - u386mon+siotools merge */
  1602. X/*:06-21-1992-00:34-root@n4hgf-needed extern for 3.2v4 */
  1603. X/*:06-20-1992-20:19-root@n4hgf-dont let info fall off bottom */
  1604. X/*:08-20-1991-12:44-root@n4hgf-nba@sysware.dk S5R31 and config reorg */
  1605. X/*:08-01-1991-23:34-wht@n4hgf-release 2.40 source control point */
  1606. X/*:08-10-1990-14:12-jmd@p1so/wht@n4hgf-2.20-add Tandem Integrity S2 */
  1607. X/*:08-07-1990-14:24-wht@n4hgf-nba@sysware.dk SVR31 updates */
  1608. X/*:08-02-1990-15:35-wht@n4hgf-2.12-old curses hacks+minor 3.2 formalizations */
  1609. X/*:07-28-1990-18:06-wht@n4hgf-2.10 release */
  1610. X/*:07-11-1990-17:19-root@n4hgf-more input from trb@ima.ima.isc.com */
  1611. X/*:07-04-1990-01:28-root@n4hgf-alan@cms2.lonestar.org reported missing M_ */
  1612. X/*:06-27-1990-01:57-wht@n4hgf-1.10-incorporate suggestions from alpha testers */
  1613. X/*:06-25-1990-04:14-wht@n4hgf-1.02-better error handling */
  1614. X/*:06-25-1990-03:18-wht@n4hgf-ODT/3.2.1 has B_MEM_CANTDMA not B_MEM_NODMA */
  1615. X/*:06-24-1990-20:53-wht@n4hgf-v1.01-add ISC support thanks to peter@radig.de */
  1616. X/*:06-21-1990-14:26-r@n4hgf-version x0.12 seems bug free */
  1617. X/*:06-17-1990-14:59-wht-creation */
  1618. X
  1619. X#include "config.h"
  1620. X
  1621. X#if defined(HAS_BOOTINFO)
  1622. X
  1623. X#include <curses.h>
  1624. X#undef timeout /* conflict in curses.h and bootinfo.h per trb@ima.ima.isc.com */
  1625. X#undef reg     /* per nba@sysware.dk */
  1626. X#include "libpanel.h"
  1627. X#include <sys/types.h>
  1628. X#include <sys/bootinfo.h>
  1629. X#include "u386mon.h"
  1630. X
  1631. Xextern struct bootinfo bootinfo;
  1632. X
  1633. X/*+-------------------------------------------------------------------------
  1634. X    bmemf_text(flags)
  1635. X--------------------------------------------------------------------------*/
  1636. Xchar *
  1637. Xbmemf_text(flags)
  1638. Xulong flags;
  1639. X{
  1640. X    static char hex_errant[16];
  1641. X    ulong orig_flags = flags;
  1642. X
  1643. X#if defined(B_MEM_DOWN)        /* SCO only */
  1644. X    flags &= ~B_MEM_DOWN;
  1645. X#endif
  1646. X#if defined(B_MEM_BASE)        /* ISC only (or is it SVR3.2.2?) */
  1647. X    flags &= ~B_MEM_BASE;
  1648. X#endif
  1649. X#if defined(B_MEM_EXPANS)    /* ISC */
  1650. X    flags &= ~B_MEM_EXPANS;
  1651. X#endif
  1652. X#if defined(B_MEM_SHADOW)    /* ISC */
  1653. X    flags &= ~B_MEM_SHADOW;
  1654. X#endif
  1655. X#if defined(B_MEM_TREV)        /* ISC */
  1656. X    flags &= ~B_MEM_TREV;
  1657. X#endif
  1658. X
  1659. X    if(!flags)
  1660. X        return("    ");
  1661. X    switch(flags)
  1662. X    {
  1663. X#if defined(B_MEM_RSRVD)
  1664. X        case B_MEM_RSRVD: return("RSVD");
  1665. X#endif
  1666. X#if defined(B_MEM_KBSS)
  1667. X        case B_MEM_KBSS:  return("KBSS");
  1668. X#endif
  1669. X#if defined(B_MEM_KTEXT)
  1670. X        case B_MEM_KTEXT: return("KTXT");
  1671. X#endif
  1672. X#if defined(B_MEM_KDATA)
  1673. X        case B_MEM_KDATA: return("KDTA");
  1674. X#endif
  1675. X#if defined(B_MEM_NODMA)
  1676. X        case B_MEM_NODMA: return("NODM");
  1677. X#endif
  1678. X#if defined(B_MEM_CANTDMA)
  1679. X        case B_MEM_CANTDMA: return("NODM");
  1680. X#endif
  1681. X    }
  1682. X    sprintf(hex_errant,"%04x",(ushort)orig_flags);
  1683. X    return(hex_errant);
  1684. X}    /* end of bmemf_text */
  1685. X
  1686. X/*+-------------------------------------------------------------------------
  1687. X    ISC_machinetype_text(machine)
  1688. X--------------------------------------------------------------------------*/
  1689. X#if defined(ME_COMPAQVGA)    /* ISC machdep.h */
  1690. Xchar *
  1691. XISC_machinetype_text(machine)
  1692. Xunsigned char machine;
  1693. X{
  1694. X    switch(machine)
  1695. X    {
  1696. X#if defined(M_UNKNOWN)    /* some ISC bootinfo.h do not have these */
  1697. X        case M_UNKNOWN:
  1698. X            return("");
  1699. X            break;
  1700. X#endif
  1701. X#if defined(M_COMPAQ)
  1702. X        case M_COMPAQ:
  1703. X            return("Compaq");
  1704. X            break;
  1705. X#endif
  1706. X#if defined(M_PS2)
  1707. X        case M_PS2:
  1708. X            return("PS/2");
  1709. X            break;
  1710. X#endif
  1711. X#if defined(M_AT)
  1712. X        case M_AT:
  1713. X            return("Generic 386");
  1714. X            break;
  1715. X#endif
  1716. X#if defined(M_ATT)
  1717. X        case M_ATT:
  1718. X            return("AT&T 6386");
  1719. X            break;
  1720. X#endif
  1721. X#if defined(M_ATT5)
  1722. X        case M_ATT5:
  1723. X            return("AT&T 6386");
  1724. X            break;
  1725. X#endif
  1726. X#if defined(M_M380)
  1727. X        case M_M380:
  1728. X            return("Olivetti M380");
  1729. X            break;
  1730. X#endif
  1731. X#if defined(M_DELL)
  1732. X        case M_DELL:
  1733. X            return("Dell 386");
  1734. X            break;
  1735. X#endif
  1736. X#if defined(M_D325)
  1737. X        case M_D325:
  1738. X            return("Dell 325");
  1739. X            break;
  1740. X#endif
  1741. X#if defined(M_ALR)
  1742. X        case M_ALR:
  1743. X            return("Adv Logic Res");
  1744. X            break;
  1745. X#endif
  1746. X#if defined(M_ZDS)
  1747. X        case M_ZDS:
  1748. X            return("Zenith Data");
  1749. X            break;
  1750. X#endif
  1751. X    }
  1752. X    return("i386");
  1753. X}    /* end of ISC_machinetype_text */
  1754. X#endif
  1755. X
  1756. X/*+-------------------------------------------------------------------------
  1757. X    ISC_displaytype_text(adapter)
  1758. X--------------------------------------------------------------------------*/
  1759. X#if defined(ME_COMPAQVGA)    /* ISC machdep.h */
  1760. Xchar *
  1761. XISC_displaytype_text(adapter)
  1762. Xunsigned char adapter;
  1763. X{
  1764. X
  1765. X    switch(adapter)
  1766. X    {
  1767. X        case ME_UNKNOWN:
  1768. X            return("unknown to sys");
  1769. X            break;
  1770. X        case ME_EGA:
  1771. X            return("EGA");
  1772. X            break;
  1773. X        case ME_CGA80:
  1774. X            return("CGA");
  1775. X            break;
  1776. X        case ME_MONO:
  1777. X            return("MONO");
  1778. X            break;
  1779. X        case ME_COMPAQHR:
  1780. X            return("Compaq mono");
  1781. X            break;
  1782. X        case ME_Z449:
  1783. X            return("Zenith Z449");
  1784. X            break;
  1785. X        case ME_T5100:
  1786. X            return("Toshiba T5100");
  1787. X            break;
  1788. X        case ME_COMPAQVGA:
  1789. X            return("Compaq VGA");
  1790. X            break;
  1791. X        case ME_OTHERVGA:
  1792. X            return("VGA");
  1793. X            break;
  1794. X#if defined(ME_PVGA1)
  1795. X        case ME_PVGA1:
  1796. X            return("Paradise VGA1");
  1797. X            break;
  1798. X#endif /*ME_PVGA1*/
  1799. X#if defined(ME_V7VGA)
  1800. X        case ME_V7VGA:
  1801. X            return("Video 7 VGA");
  1802. X            break;
  1803. X#endif /*ME_V7VGA*/
  1804. X    }
  1805. X    return("???");
  1806. X}    /* end of ISC_displaytype_text */
  1807. X#endif
  1808. X
  1809. X/*+-------------------------------------------------------------------------
  1810. X    display_bootinfo(win,y,x)
  1811. X--------------------------------------------------------------------------*/
  1812. Xvoid
  1813. Xdisplay_bootinfo(win,y,x)
  1814. XWINDOW *win;
  1815. Xint y;
  1816. Xint x;
  1817. X{
  1818. X    register itmp;
  1819. X    register struct bootmem *bmem;
  1820. X    int maxy = getmaxy(win);
  1821. X
  1822. X    use_cp(win,cpBANNER);
  1823. X    wmove(win,y++,x);
  1824. X    waddstr(win,"-- Bootinfo ----------");
  1825. X#if defined(M_UNIX)    /* ISC doesn't have this in struct */
  1826. X    wmove(win,y++,x);
  1827. X    disp_static_long(win,"basemem  ","%7ldk     ",bootinfo.basemem / 1024);
  1828. X    wmove(win,y++,x);
  1829. X    disp_static_long(win,"extmem   ","%7ldk     ",bootinfo.extmem / 1024);
  1830. X#endif
  1831. X#if defined(ME_COMPAQVGA)    /* ISC machdep.h */
  1832. X    wmove(win,y++,x);
  1833. X    wprintw(win,"machine %14.14s",
  1834. X        ISC_machinetype_text(bootinfo.machenv.machine));
  1835. X    wmove(win,y++,x);
  1836. X    wprintw(win,"disp %17.17s",
  1837. X        ISC_displaytype_text(bootinfo.machenv.adapter));
  1838. X#endif
  1839. X    wmove(win,y++,x);
  1840. X    disp_static_long(win,"bflags   ","%08lx     ",bootinfo.bootflags);
  1841. X
  1842. X    wmove(win,y++,x); waddstr(win,"memory available      ");
  1843. X    for(itmp = 0; itmp < bootinfo.memavailcnt; itmp++)
  1844. X    {
  1845. X        bmem = &bootinfo.memavail[itmp];
  1846. X#if defined(B_MEM_DOWN)
  1847. X        if(bmem->flags & B_MEM_DOWN)
  1848. X        {
  1849. X            bmem->base -= bmem->extent;
  1850. X            bmem->flags &= ~B_MEM_DOWN;
  1851. X        }
  1852. X#endif
  1853. X        if(y == (maxy - 2))
  1854. X            goto NO_ROOM;
  1855. X        wmove(win,y++,x);
  1856. X        wprintw(win,"%08lx %08lx %s",bmem->base,bmem->extent,
  1857. X            bmemf_text(bmem->flags));
  1858. X    }
  1859. X
  1860. X    if(y == (maxy - 2))
  1861. X        goto NO_ROOM;
  1862. X    wmove(win,y++,x);
  1863. X    waddstr(win,"memory used           ");
  1864. X    for(itmp = 0; itmp < bootinfo.memusedcnt; itmp++)
  1865. X    {
  1866. X        bmem = &bootinfo.memused[itmp];
  1867. X#if defined(B_MEM_DOWN)
  1868. X        if(bmem->flags & B_MEM_DOWN)
  1869. X        {
  1870. X            bmem->base -= bmem->extent;
  1871. X            bmem->flags &= ~B_MEM_DOWN;
  1872. X        }
  1873. X#endif
  1874. X        if(y == (maxy - 2))
  1875. X            goto NO_ROOM;
  1876. X        wmove(win,y++,x);
  1877. X        wprintw(win,"%08lx %08lx %s",bmem->base,bmem->extent,
  1878. X            bmemf_text(bmem->flags));
  1879. X    }
  1880. X
  1881. X
  1882. X    return;
  1883. X
  1884. XNO_ROOM:
  1885. X    wmove(win,maxy - 2,x);
  1886. X    waddstr(win,"insufficient display rows for complete information");
  1887. X
  1888. X}    /* end of display_bootinfo */
  1889. X
  1890. X#endif /* HAS_BOOTINFO */
  1891. X/* vi: set tabstop=4 shiftwidth=4: */
  1892. X/* end of bootinfo.c */
  1893. SHAR_EOF
  1894. chmod 0644 bootinfo.c ||
  1895. echo 'restore of bootinfo.c failed'
  1896. Wc_c="`wc -c < 'bootinfo.c'`"
  1897. test 7500 -eq "$Wc_c" ||
  1898.     echo 'bootinfo.c: original size 7500, current size' "$Wc_c"
  1899. fi
  1900. true || echo 'restore of detail.c failed'
  1901. echo End of part 3, continue with part 4
  1902. exit 0
  1903.  
  1904. exit 0 # Just in case...
  1905.