📄 perfmeter.c
字号:
#ifndef lint#endif/* * Copyright (c) 1985, 1986, 1987, 1988 by Sun Microsystems Inc. *//* * perfmeter [-v name] [-s sample] [-m minute] [-h hour] * [ -M value minmax maxmax ] [ host ] * * displays meter for value 'name' sampling * every 'sample' seconds. The minute hand is an * average over 'minute' seconds, the hour hand over * 'hour' seconds */#include <stdio.h>#include <sys/time.h>#include <sys/param.h>#include <rpc/rpc.h>#include <rpcsvc/rstat.h>#include <sys/socket.h>#include <netdb.h>#include <sys/dk.h>#include <sys/vmmeter.h>#include <sys/wait.h>#include <suntool/sunview.h>#include <sunwindow/rect.h>#include <sunwindow/pixwin.h>#include <suntool/wmgr.h>#include "meter.h"#define MAXINT 0x7fffffff#define TRIES 8 /* number of bad rstat's before giving up */#define TOP_KEY KEY_LEFT(5)#define OPEN_KEY KEY_LEFT(7)#define max_of(x,y) MAX((x),(y))#define min_of(x,y) MIN((x),(y))struct timeval TIMEOUT = {20,0};struct meter meters_init[] = { /* name maxmax minmax curmax scale lastval */ { "cpu", 100, 100, 100, 1, -1 },#define CPU 0 { "pkts", MAXINT, 32, 32, 1, -1 },#define PKTS 1 { "page", MAXINT, 16, 16, 1, -1 },#define PAGE 2 { "swap", MAXINT, 4, 4, 1, -1 },#define SWAP 3 { "intr", MAXINT, 100, 100, 1, -1 },#define INTR 4 { "disk", MAXINT, 40, 40, 1, -1 },#define DISK 5 { "cntxt", MAXINT, 64, 64, 1, -1 },#define CNTXT 6 { "load", MAXINT, 4, 4, FSCALE, -1 },#define LOAD 7 { "colls", MAXINT, 4, 4, FSCALE, -1 },#define COLL 8 { "errs", MAXINT, 4, 4, FSCALE, -1 },#define ERR 9};#define MAXMETERS sizeof (meters_init) / sizeof (meters_init[0])struct meter *meters; /* [MAXMETERS] */int *getdata_swtch(); /* version 3 (RSTATVERS_SWTCH) of RSTATPROG */int *getdata_var(); /* version 4 (RSTATVERS_VAR) */int killkids();int meter_selected();char *calloc();static caddr_t do_menu();void wmgr_changerect();static Notify_value meter_event();static Notify_value meter_itimer_expired();caddr_t window_get();Frame frame;struct pixfont *pfont;struct pixrect *ic_mpr;Icon metericon; /* Defaults to all zeros */Pixwin *pw;static Menu menu; /* walking menus */static Rect ic_gfxrect;struct pixrect *ic_mpr;int (*old_selected)();int wantredisplay; /* flag set by interrupt handler */int *save; /* saved values for redisplay; dynamically * allocated to be [MAXMETERS][MAXSAVE] */int saveptr; /* where I am in save+(visible*MAXMETERS) */int dead; /* is remote machine dead? */int sick; /* is remote machine sick? (sending bogus data) */int visible; /* which quantity is visible*/int length = sizeof (meters_init) / sizeof (meters_init[0]);int remote; /* is meter remote? */int rootfd; /* file descriptor for the root window */int width; /* current width of graph area */int height; /* current height of graph area */char *hostname; /* name of host being metered */int sampletime; /* sample seconds */int minutehandintv; /* average this second interval */int hourhandintv; /* long average over this seconds */int shortexp, longexp;int designee;int meter_client;static int oldsocket;#define VER_NONE -1static int vers = VER_NONE;#ifdef STANDALONEmain(argc, argv)#elseperfmeter_main(argc, argv)#endif STANDALONE int argc; char **argv;{ register int i, j; register struct meter *mp; char *cmdname; char **av; int pid; /* Dynamically allocate save */ save = (int *)(calloc(1, sizeof (int)*MAXMETERS*MAXSAVE)); /* Dynamically allocate and initialize meters */ meters = (struct meter *)(calloc(1, sizeof (meters_init))); for (i = 0; i < MAXMETERS; i++) meters[i] = meters_init[i]; sampletime = 2; minutehandintv = 2; hourhandintv = 20; oldsocket = -1; /* * Create tool window and customize */ cmdname = argv[0]; argc--; argv++; /* skip over program name */ frame = window_create(0, FRAME, FRAME_SHOW_LABEL, FALSE, WIN_WIDTH, ICONWIDTH, WIN_HEIGHT, 6, /* not really, check later */ WIN_ERROR_MSG, "Unable to create frame\n", FRAME_ARGC_PTR_ARGV, &argc, argv, WIN_CONSUME_KBD_EVENT, WIN_ASCII_EVENTS, 0); if (frame == (Frame)NULL) { exit(1); } (void) notify_interpose_event_func((Notify_client)frame, meter_event, NOTIFY_SAFE); while (argc > 0) { if (argv[0][0] == '-') { if (argv[0][2] != '\0') goto toolarg; switch (argv[0][1]) { case 's': if (argc < 2) usage(cmdname); sampletime = atoi(argv[1]); break; case 'h': if (argc < 2) usage(cmdname); hourhandintv = atoi(argv[1]); break; case 'm': if (argc < 2) usage(cmdname); minutehandintv = atoi(argv[1]); break; case 'v': if (argc < 2) usage(cmdname); for (i = 0, mp = meters; i < length; i++, mp++) if (strcmp(argv[1], mp->m_name) == 0) break; if (i >= length) usage(cmdname); visible = i; break; case 'M': if (argc < 4) usage(cmdname); for (i = 0, mp = meters; i < length; i++, mp++) if (strcmp(argv[1], mp->m_name) == 0) break; if (i >= length) usage(cmdname); visible = i; mp->m_curmax = mp->m_minmax = atoi(argv[2]); mp->m_maxmax = atoi(argv[3]); argc -= 2; argv += 2; break; default: toolarg: /* * Pick up generic tool arguments. *//* if ((i = tool_parse_one(cmdname, argc, argv)) == -1) { (void)tool_usage(cmdname); exit(1); } else if (i == 0) usage(cmdname);*/ argc -= i; argv += i; continue; } argc--; argv++; } else { if (hostname != NULL) usage(cmdname); hostname = argv[0]; remote = 1; } argc--; argv++; } if (sampletime <= 0 || hourhandintv < 0 || minutehandintv < 0) usage(cmdname); shortexp = (1 - ((double)sampletime/max_of(hourhandintv, sampletime))) * FSCALE; longexp = (1 - ((double)sampletime/max_of(minutehandintv, sampletime))) * FSCALE; /* * Set up meter icon. */ ic_gfxrect.r_width = ICONWIDTH; ic_gfxrect.r_height = remote ? RICONHEIGHT : ICONHEIGHT; ic_mpr = mem_create(ICONWIDTH, remote ? RICONHEIGHT : ICONHEIGHT, 1); metericon = icon_create( ICON_WIDTH, ICONWIDTH, ICON_HEIGHT, remote ? RICONHEIGHT : ICONHEIGHT, ICON_IMAGE_RECT,&ic_gfxrect, 0); if ((int)window_get(frame, WIN_HEIGHT) == 6) { window_set(frame, FRAME_ICON, metericon, WIN_HEIGHT, remote ? RICONHEIGHT : ICONHEIGHT, 0); } else window_set(frame, FRAME_ICON, metericon, 0); icon_destroy(metericon); metericon = window_get(frame, FRAME_ICON); (void)icon_set(metericon, ICON_IMAGE, ic_mpr, 0); /* * Open font for icon label. */ pfont = pf_open("/usr/lib/fonts/fixedwidthfonts/screen.r.7"); if (pfont == NULL) { (void)fprintf(stderr, "%s: can't find screen.r.7\n", cmdname); exit(1); } pw = (Pixwin *) window_get(frame, WIN_PIXWIN); /* * Setup timer. */ if (setup() < 0) { dead = 1; sick = 0; keeptrying(); } /* * Get first set of data, then initialize arrays. */ updatedata(); for (i = 0; i < length; i++) for (j = 1; j < MAXSAVE; j++) save_access(i, j) = -1; /* * Initialize menu. */ av = (char **)( malloc((unsigned)(3*length*sizeof(char*) + sizeof(char *)))); for (i = 0; i < 3*length; i+=3) { av[i] = (char *)MENU_STRING_ITEM; av[i+1] = meters[i/3].m_name; av[i+2] = (char *)(i/3); } av[i] = 0; menu = menu_create(ATTR_LIST, av, MENU_ACTION_PROC, do_menu, 0); (void)menu_set(menu, MENU_INSERT, 0, menu_create_item(MENU_PULLRIGHT_ITEM, "frame", window_get(frame, WIN_MENU), 0), 0); window_set(frame, WIN_MENU, menu, 0); pid = getpid(); (void)setpgrp(pid, pid); (void)signal(SIGTERM, killkids); (void)signal(SIGINT, killkids); /* Set itimer event handler */ (void) meter_itimer_expired((Notify_client) &meter_client, ITIMER_REAL); window_main_loop(frame); while (wantredisplay) { wantredisplay = 0; meter_paint(); notify_start(); } /* * Cleanup */ (void)pf_close(pfont); (void)pr_destroy(ic_mpr); killkids(); exit(0);}usage(name) char *name;{ register int i; (void)fprintf(stderr, "Usage: %s [-m minutehandintv] [-h hourhandintv] \[-s sampletime] [-v value] [-M value minmax maxmax] [hostname]\n", name); (void)fprintf(stderr, "value is one of: "); for (i = 0; i < length; i++) (void)fprintf(stderr, " %s", meters[i].m_name); (void)fprintf(stderr,"\n"); exit(1);}/* * New selection handler for perfmeter tool window. *//*ARGSUSED*/staticNotify_valuemeter_event(object, event, arg, type) Window object; Event *event; Notify_arg arg; Notify_event_type type;{ int n; Notify_value value; value = notify_next_event_func((Notify_client) (object), (Notify_event)(event), arg, type); switch (event->ie_code) { case WIN_RESIZE: { Rect rect; (void)win_getsize(window_get(object, WIN_FD), &rect); width = rect.r_width - 2*BORDER; height = rect.r_height - 2*BORDER - NAMEHEIGHT - 1; if (remote) height -= NAMEHEIGHT; break; }/* case MENU_BUT: { int n; n = (int)menu_show(window_get(object, WIN_MENU), object, event, 0); if (menu_get(window_get(object, WIN_MENU), MENU_VALID_RESULT)) { visible = n; meter_paint(); } event->ie_code = 0; break; }*/ case WIN_REPAINT: meter_paint(); break; case '1': sampletime = 1; break; case '2': sampletime = 2; break; case '3': sampletime = 3; break; case '4': sampletime = 4; break; case '5': sampletime = 5; break; case '6': sampletime = 6; break; case '7': sampletime = 7; break; case '8': sampletime = 8; break; case '9': sampletime = 9; break; case 'h': /* hour hand */ if (hourhandintv > 0) hourhandintv--; break; case 'H': /* hour hand */ hourhandintv++; break; case 'm': /* minute hand */ if (minutehandintv > 0) minutehandintv--; break; case 'M': /* minute hand */ minutehandintv++; break; } shortexp = (1 - ((double)sampletime/ max_of(hourhandintv, sampletime))) * FSCALE; longexp = (1 - ((double)sampletime/ max_of(minutehandintv, sampletime))) * FSCALE; return(value);}/* * SIGCHLD signal catcher. * Harvest any child (from keeptrying). * If can now contact host, request redisplay. */ondeath(){ union wait status; while (wait3(&status, WNOHANG, (struct rusage *)0) > 0) ; if (setup() < 0) keeptrying(); else { dead = 0; /* * Can't do redisplay from interrupt level * so set flag and do a tool_done. */ wantredisplay = 1; notify_stop(); }}/* * Convert raw data into properly scaled and averaged data * and save it for later redisplay. */updatedata(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -