⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perfmon.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char sccsid[] = "@(#)perfmon.c 1.1 92/07/30 Copyright Sun Micro";#endif/* * Copyright (c) 1987 by Sun Microsystems, Inc. *//* * This code was lifted from standard UNIX "perfmon" utility, and then modified * to run on a canvas subwindow in Sundiag. *//* * Simple graphical performance monitor for system-wide data. */#include <stdio.h>#include <strings.h>	/*	************* \/ vmstat \/ ***************	*/#include <sys/param.h>#include <sys/vm.h>#include <sys/dk.h>/* #include <nlist.h> */#include <signal.h>#include <sys/buf.h>#include <sundev/mbvar.h>	/*      ************** ^ vmstat ^ ****************      */	/*	*********** \/ netstat/if.c \/ *************	*/#include <sys/socket.h>#include <net/if.h>#include <netinet/in.h>	/*      ************ ^ netstat/if.c ^ **************    *//*	param.h already does ... #include <sys/types.h>	*/#include <sys/file.h>#include <sys/time.h>#include <rpc/rpc.h>#include <utmp.h>#include <rpcsvc/rstat.h>#include <netdb.h>#include "sundiag.h"		/* -JCH- will also include SunView files */extern	time_t	time();struct packet {	int	input, output, collisions};static	struct packet packets, old_packets;#define NUM_VALS_PER	1000struct statistic {	int	min_val, max_val;	int	value[NUM_VALS_PER];	char	*label, *label2;};#define SECS_PER_TIME_TICK	15static	char do_time[NUM_VALS_PER];static	struct timeval current_time, saved_time;static	struct timezone dummy_zone;static	struct timeval TIMEOUT = {60, 0};/* * The array stats always has valid info for stats[i], 0 <= i < num_stats. * For each valid stats[i], stats[i].value[j] is valid for 0 <= j < num_of_val. * The info for the k-th possible statistic of interest is recorded, if it is *   recorded at all, in stats[possible_stats[k]]. */#define	NO_STAT			-1#define USER_CPU_PERCENTAGE	0#define SYSTEM_CPU_PERCENTAGE	1#define PACKETS			2#define PAGING			3#define INTERRUPTS		4#define DISK_TRANSFERS		5#define CONTEXT_SW		6#define LOAD_AVE		7#define COLLISION_PACKETS	8#define ERROR_PACKETS		9#define NUM_POSSIBLE_STATS	10static	int			possible_stats[NUM_POSSIBLE_STATS];#define WANT_STAT(x)		(possible_stats[(x)] != NO_STAT)#define	MAX_STATS		11static	struct statistic	*p_stats;static	struct{	int		gfx_flags;	int		gfx_reps;	struct pixwin	*gfx_pixwin;	struct rect	gfx_rect;} mygfx, *gfx = &mygfx;					/* -JCH- */static	int	first=1;		/* -JCH- the first time to display */static	int num_stats, num_of_val = 0, shift_left_on_new_cycle = -1;static	int graph_x_offset = 0;static	struct rect rect;static	struct pixfont *font;#define FORALLPOSSIBLESTATS(stat)					\	for (stat = 0; stat < NUM_POSSIBLE_STATS; stat++)#define FORALLSTATS(stat)						\	for (stat = 0; stat < num_stats; stat++)	/*	************* \/ vmstat \/ ***************	*//* forward declaration */static	void	redisplay();extern	xdr_statsswtch();char	*sprintf(), *strcpy();long	lseek();int     firstfree, maxfree;int     hz;int     sick;int     getdata_swtch(); 	/* version 3 (RSTATVERS_SWTCH) of RSTATPROG  */int     getdata_var();  	/* version 4 (RSTATVERS_VAR) */struct  vmmeter osum;int     deficit;double  etime;int     mf;long t;static  int ans[MAX_STATS]; int	debug = 0;#define steal(where, var)  \	(void)lseek(mf, (long)where, 0); \	(void)read(mf, (char *)(LINT_CAST(&var)), sizeof var);#define pgtok(a) ((a)*NBPG/1024)	/*	************** ^ vmstat ^ ****************	*/static  int oldsocket = -1;#define VER_NONE -1static  int vers = VER_NONE ;static  int cpustates ;static  int dk_ndrive ;perfmon_main(){	extern	char *calloc();	int	stat;	int	have_disk;	if ((p_stats =	    (struct statistic *)(LINT_CAST(calloc(MAX_STATS,	     sizeof(struct statistic))))) == (struct statistic *)0) {		(void)fprintf(stderr, "malloc failed (out of swap space?)\n");		sundiag_exit(1);	}	(void)setup();	if (vers == RSTATVERS_VAR)	  (void)getdata_var();	else	  (void)getdata_swtch();	etime = 1.0;	have_disk = (ans[DISK_TRANSFERS] ? 1 : 0);	/* Initialize stats */	FORALLPOSSIBLESTATS(stat)		possible_stats[stat] = NO_STAT;	num_stats = 0;	if (num_stats == 0)	    FORALLPOSSIBLESTATS(stat) {		if ((stat == DISK_TRANSFERS) && (have_disk == 0)) continue;		possible_stats[stat] = num_stats++;		if (num_stats == MAX_STATS) break;	    }	init_stat(USER_CPU_PERCENTAGE, 100, "User", " CPU");	init_stat(SYSTEM_CPU_PERCENTAGE, 100, "System", " CPU");	init_stat(PACKETS, (have_disk ? 40 : 60), "Total", " packets");	init_stat(PAGING, 20, "", "Paging");	init_stat(INTERRUPTS, 400, "Inter-", "    rupts");	init_stat(DISK_TRANSFERS, 40, "Disk", " transfers ");	init_stat(CONTEXT_SW, 128, "Context", "  Switches");	init_stat(LOAD_AVE, 10, "Load", "  Average");	init_stat(COLLISION_PACKETS, (have_disk ? 4 : 8),						"Collision", " packets");	init_stat(ERROR_PACKETS, (have_disk ? 10 : 20), "Error", " packets");	font = sundiag_font;		/* always use the Sundiag font -JCH- */	FORALLSTATS(stat) {	    struct pr_size text_size;	    text_size = pf_textwidth(			strlen(p_stats[stat].label), font, p_stats[stat].label);	    graph_x_offset = max(graph_x_offset, text_size.x);	    text_size = pf_textwidth(			strlen(p_stats[stat].label2), font, p_stats[stat].label2);	    graph_x_offset = max(graph_x_offset, text_size.x);	}	graph_x_offset += 15;	(void)gettimeofday(&saved_time, &dummy_zone);/* -JCH- modified so that it will run on a canvas subwindow. */	gfx->gfx_pixwin = canvas_pixwin(sundiag_perfmon);	(void)window_set(sundiag_perfmon, CANVAS_RESIZE_PROC, redisplay, 0);/* -JCH- */}init_stat(index_local, maxval, label_1, label_2)	int index_local, maxval;	char *label_1, *label_2;{	if WANT_STAT(index_local) {		index_local = possible_stats[index_local];		p_stats[index_local].max_val = maxval;		p_stats[index_local].label = label_1;		p_stats[index_local].label2 = label_2;	}}#define	YORIGIN_FOR_STAT(num)					\	(((num)*rect.r_height)/num_stats)#define	YMIDPOINT_FOR_STAT(num)					\	(((num)*rect.r_height+rect.r_height/2)/num_stats - 6)	/* -JCH- */static	int	Y_FOR_STAT_VAL(stat, num_of_val, height_of_stat)int	stat, num_of_val, height_of_stat;{  int	temp;  (void)signal(SIGFPE, SIG_IGN);  temp = YORIGIN_FOR_STAT(stat)+5+height_of_stat - min(height_of_stat,	 (height_of_stat*(p_stats[stat].value[num_of_val]-p_stats[stat].min_val)/	 (p_stats[stat].max_val-p_stats[stat].min_val)));  (void)signal(SIGFPE, SIG_DFL);  return(temp);}display_dividers(pw, clear_first)	struct pixwin *pw;	int clear_first;{	register int	i, stat;	struct rect	div_rect;	div_rect.r_left = graph_x_offset;	div_rect.r_width = rect.r_width-graph_x_offset;	div_rect.r_height = 5;	FORALLSTATS(stat) {	    register int y_origin_of_stat = YORIGIN_FOR_STAT(stat);	    if (stat == 0)		continue;	    div_rect.r_top = y_origin_of_stat-2;	    (void)pw_lock(pw, &div_rect);	    if (clear_first)		(void)pw_writebackground(pw, div_rect.r_left, div_rect.r_top,		    div_rect.r_width, div_rect.r_height, PIX_CLR);	    /* Draw the horizontal line and then add the tick marks */	    (void)pw_vector(pw, div_rect.r_left, y_origin_of_stat,		rect.r_width, y_origin_of_stat, PIX_SRC, -1);	    for (i = 0; i < num_of_val; i++) {		if (do_time[i])		    (void)pw_vector(pw, graph_x_offset+i, div_rect.r_top,			graph_x_offset+i, y_origin_of_stat+2, PIX_SRC, -1);	    }	    (void)pw_unlock(pw);	}}static	void redisplay(){	register int height_of_stat, stat;	rect = *(struct rect *)window_get(sundiag_perfmon, WIN_RECT);	(void)pw_writebackground(gfx->gfx_pixwin, 0, 0,	    rect.r_width, rect.r_height, PIX_CLR);	display_dividers(gfx->gfx_pixwin, 0);	height_of_stat = YORIGIN_FOR_STAT(1) - YORIGIN_FOR_STAT(0) - 10;	FORALLSTATS(stat) {	    register int font_height = (font->pf_defaultsize.y)+2;	    register int y_origin_of_stat = YORIGIN_FOR_STAT(stat);	    struct pr_size text_size;	    char temp[10];	    (void)pw_text(gfx->gfx_pixwin, 0, YMIDPOINT_FOR_STAT(stat),		PIX_SRC, font, p_stats[stat].label);	    (void)pw_text(gfx->gfx_pixwin, 0,		YMIDPOINT_FOR_STAT(stat)+font_height,		PIX_SRC, font, p_stats[stat].label2);	    (void)sprintf(temp, "%d", p_stats[stat].max_val);	    text_size = pf_textwidth(strlen(temp), font, temp);	    (void)pw_text(gfx->gfx_pixwin, graph_x_offset-5-text_size.x,		y_origin_of_stat-3+font_height, PIX_SRC, font, temp);	    (void)sprintf(temp, "%d", p_stats[stat].min_val);	    text_size = pf_textwidth(strlen(temp), font, temp);	    (void)pw_text(gfx->gfx_pixwin, graph_x_offset-5-text_size.x,		y_origin_of_stat+8+height_of_stat, PIX_SRC, font, temp);	}	if (num_of_val > 0) FORALLSTATS(stat) {	    redisplay_stat_values(		gfx->gfx_pixwin, height_of_stat, stat, 0, num_of_val);	}}redisplay_stat_values(pw, height_of_stat, stat, start, stop_plus_one)	struct pixwin *pw;	int height_of_stat, stat, start, stop_plus_one;{	int j, newY;	(void)pw_lock(pw, &rect);	newY = Y_FOR_STAT_VAL(stat, start, height_of_stat);	for (j = start; j < stop_plus_one; ) {		int jcopy = j, oldY = newY;		do {			newY = Y_FOR_STAT_VAL(stat, j, height_of_stat);			j++;		} while ((oldY == newY) && (j < stop_plus_one));		if (j > jcopy+1)			(void)pw_vector(pw, graph_x_offset+jcopy, oldY,				graph_x_offset+j-2, oldY, PIX_SRC, 1);		(void)pw_vector(pw, graph_x_offset+j-2, oldY,			graph_x_offset+j-1, newY, PIX_SRC, 1);	}	(void)pw_unlock(pw);}set_clipping_equal_fixup(pw)	struct pixwin *pw;{	int screenX, screenY;	struct rect screenrect;	screenrect = rect;	(void)win_getscreenposition(		pw->pw_clipdata->pwcd_windowfd, &screenX, &screenY);	screenrect.r_left = screenX;	screenrect.r_top = screenY;	(void)rl_free(&pw->pw_clipdata->pwcd_clipping);	pw->pw_clipdata->pwcd_clipping = pw->pw_fixup;	pw->pw_fixup = rl_null;	(void)_pw_setclippers(pw, &screenrect);}next_display(pw)	struct pixwin *pw;{	int stat, height_of_stat;	height_of_stat = YORIGIN_FOR_STAT(1) - YORIGIN_FOR_STAT(0) - 10;	FORALLSTATS(stat) {	    int newY, oldY;	    newY = Y_FOR_STAT_VAL(stat, num_of_val, height_of_stat);	    if (num_of_val == 0)		oldY = newY;	    else		oldY = Y_FOR_STAT_VAL(stat, num_of_val-1, height_of_stat);	    (void)pw_vector(pw,		graph_x_offset+num_of_val, oldY,		graph_x_offset+num_of_val+1, newY, PIX_SRC, 1);	    if ((stat != 0) && do_time[num_of_val]) {		int y_origin_of_stat = YORIGIN_FOR_STAT(stat);		(void)pw_vector(pw, graph_x_offset+num_of_val,				y_origin_of_stat-2,		    		graph_x_offset+num_of_val,				y_origin_of_stat+2, PIX_SRC, -1);	    }	}	if (++num_of_val >= NUM_VALS_PER ||	num_of_val >= rect.r_width-graph_x_offset) {	    if (shift_left_on_new_cycle) {		int num_shift_left = (rect.r_width-graph_x_offset)/2;		int width = (rect.r_width-graph_x_offset) - num_shift_left;		register int j;		if (num_shift_left < 0) num_shift_left = num_of_val-1;		/* -JCH- fixed the bug which causes core dump when the window			 was resized to reveal only the label portion */		for (j = num_shift_left; j < num_of_val; j++)		    do_time[j-num_shift_left] = do_time[j];		FORALLSTATS(stat) {		    int ys = YORIGIN_FOR_STAT(stat)+5;		    for (j = num_shift_left; j < num_of_val; j++)			p_stats[stat].value[j-num_shift_left] =			  p_stats[stat].value[j];		    (void)pw_copy(pw, graph_x_offset, ys,				  width, height_of_stat+1, PIX_SRC,				  pw, graph_x_offset+num_shift_left, ys);		    if (!rl_empty(&pw->pw_fixup)) {			set_clipping_equal_fixup(pw);			(void)pw_writebackground(			    pw, 0, 0, rect.r_width, rect.r_height, PIX_SRC);			redisplay_stat_values(			    pw, height_of_stat, stat, 0,			    num_of_val-num_shift_left-1);			(void)pw_exposed(pw);		    }		    (void)pw_writebackground(			pw, graph_x_offset+num_shift_left, ys,			width, height_of_stat+1, PIX_SRC);		}		num_of_val -= num_shift_left+1;		display_dividers(pw, 1);	    } else {		num_of_val = 0;	    }	}}#define	TIMER_EXPIRED(timer)						\	(*timer && ((*timer)->tv_sec == 0) && ((*timer)->tv_usec == 0))perfmon_update(){	int *target[CPUSTATES-1], trash;	if (first == 1)		/* -JCH- */	{	  redisplay();		/* display the graphics for the first time */	  first = 0;		/* reset the flag */	}	/* get stats from rstatd - fill in ans[]. */	if (vers == RSTATVERS_VAR)	  (void)getdata_var();	else	  (void)getdata_swtch();		if WANT_STAT(USER_CPU_PERCENTAGE)	  p_stats[possible_stats[USER_CPU_PERCENTAGE]].value[num_of_val] =	    ans[USER_CPU_PERCENTAGE];	if WANT_STAT(SYSTEM_CPU_PERCENTAGE)	  p_stats[possible_stats[SYSTEM_CPU_PERCENTAGE]].value[num_of_val] =	    ans[SYSTEM_CPU_PERCENTAGE];	if WANT_STAT(DISK_TRANSFERS)	  p_stats[possible_stats[DISK_TRANSFERS]].value[num_of_val] =            ans[DISK_TRANSFERS];	if WANT_STAT(INTERRUPTS)	  p_stats[possible_stats[INTERRUPTS]].value[num_of_val] =	    ans[INTERRUPTS];	if WANT_STAT(PACKETS)	  p_stats[possible_stats[PACKETS]].value[num_of_val] =	    ans[PACKETS];	if WANT_STAT(ERROR_PACKETS)	  p_stats[possible_stats[ERROR_PACKETS]].value[num_of_val] =	    ans[ERROR_PACKETS] / FSCALE;	if WANT_STAT(COLLISION_PACKETS)	  p_stats[possible_stats[COLLISION_PACKETS]].value[num_of_val] =	     ans[COLLISION_PACKETS] / FSCALE;	if WANT_STAT(LOAD_AVE)	  p_stats[possible_stats[LOAD_AVE]].value[num_of_val] =	     ans[LOAD_AVE] / FSCALE;	if WANT_STAT(PAGING)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -