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

📄 cpustat.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
# ifndef lintstatic	char	*sccsid = "@(#)cpustat.c	4.5	(ULTRIX)	12/20/90";# endif not lint/************************************************************************ *									* *			Copyright (c) 1988, 1990 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************/#include <curses.h>#include <signal.h>#include <nlist.h>#include <utmp.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/smp_lock.h>#include <sys/time.h>#include <sys/param.h>#include <sys/proc.h>#include <sys/cpudata.h>#ifdef mips#include <sys/fixpoint.h>#endif mips#ifdef vax#include <machine/vectors.h>#endif /* vax *//************************************************************************** * A program to display per cpu information 				  * * * to be compiled with curses library * cc -o cpustat cpustat.c -lcurses -ltermcap * * * This program is designed to display different sets of information  * about each cpu. In the default mode, the intent is to display as   * much as possible on a full screen. But the user can select specific  * flags for specific displays ('s' for statistics and 'c' for cpu   * states). If the program is to be modified to display new sets of  * information, the following need to be done: * 	1. If a new data structure is to be accessed in the kernel,  *	   update the namelist structure and modify the update_info()  *	   routine to extract the new information. *	2. Add a new flag to the command line and modify the get_opts() *	   routine to set the corresponding flag on. *	3. display() is the central routine controlling the display. *	   Wherever a test is done for the current optional flags *	   (sflg or cflg), add the test for the new flag. If the new *	   flag is set, call the corresponding routine to display the *	   header or the updated information. *	4. Add a new switch condition for the new flag (i.e. a one  *	   letter command is to be added to the commands available from *	   the full screen.). Do things similar to what is currently *	   being done for 'c' or 's' commands. *	5. Write two new routines to set up the header for the new set *	   of information (similar to setup_state()) and display the *	   new information (similar to upd_statistics_scrn()). *	6. Write a new routine to print the new information on the *	   screen (similar to pr_state()). *	7. Special things may have to be done depending on the format *	   in which the new information is to be displayed (like *	   format_state()). *	8. Update the help messages help_stats[], help_state[] and *	   help_info[]. *	9. Update the string *cmd for the new command. *	10. Update the man page. * **************************************************************************//************************************************************************** * Modification History: * * 20 dec 90 - dlh *	corrected output of pid field *	changed display of vp state * * 14 Nov 90 - paradis *	Add support for displaying vector-processor statistics *	(only on vector-capable VAX architectures) * * 08 Dec 89 - jaw  *	add error check for select call for interrupted system call. * 09 Jun 89 - gmm *	Fixes to print load average correctly on mips. * 15 Jun 88 - George Mathew *	Changes to conform to the new way cpudata allocated * 01 Jun 88 - George Mathew *	Fixed some display alignment problems * 22 Feb 88 - George Mathew *	Created this progam. * ***************************************************************************/struct nlist namelist[] = {#define C_HZ		0	{ "_hz" },#define	C_CPUDATA	1	{ "_cpudata" },#define C_AVENRUN	2	{ "_avenrun" },#ifdef vax#define C_VPTOTAL	3	{ "_vptotal" },#define C_VPMASK	4	{ "_vpmask" },#endif /* vax */	{ "" }};#define	HOSTLEN	255char	hname[HOSTLEN];#define	DEF_INTERVAL	10		/* default interval between displays *//* #define MAXCPU	32	 max. no of cpus/slots (now defined in cpudata.h) *//* X-Y positions on the window */#define XZERO 	0#define YZERO 	0#define	YTWO	2#define YTHREE	3int	activecpu;			/* mask of active cpus */int	fflg,cflg,sflg,errflg;		/* command line options */int	vflg = 0;			/* vector option */int	vptotal = 0;			/* # vector processors */unsigned vpmask = 0;			/* mask of installed VPs */int	kmem;				/* file descriptor for kmem file */int	deflt = 1;				/* default flag */int	interval,iter;char	*kernfile = "/vmunix";char	*kmemfile = "/dev/kmem";int	total_cpus,cpudata_size;struct	cpudata *pcpudata, *cpudata_p1, *cpudata_p0;#ifdef vaxstruct  vpdata *vpdata_p1, *vpdata_p0;#endif /* vax */char	*state_hdr = "cpu      state      ipi-mask    proc    pid";char	*statistics_hdr = "cpu  us%%  ni%%  sy%%  id%%    csw     sys     trap    intr     ipi   ttyin   ttyout";#ifdef vaxchar	*vp_hdr = "cpu     vp state    vp owner    chp cxsw    exp cxsw    succ req   failed req"; #endif /* vax */char	printbuf[100];		/* buffer to hold the format string for printing*/char *st_format = "       %s         %s     %c    ";#ifdef vaxdouble	loadav[3];#endif vax#ifdef mipsfix	loadav[3];#endiflong	cur_time;int	users;	char	*help_0 =  "cpustat HELP screen";char	*help_stats[] = {	"When in full screen mode, to change the display type:",	"	s : Display cpu statistics only",	"	c : Display cpu states only",#ifdef vax	"	v : Display vector processor states only",#endif /* vax */	"	d : Display default mode (stats) and states if less than 8 cpus",	"	q : Quit this program",	"	h : Display this help screen",	"	Any other character refreshes the screen",	0	};char	*help_state[] = {	"The options for cpustat are:",	" 	-f : display cpu statistics and state on full screen",	"	-s : display only cpu statistics information",	"	-c : display only cpu state information",#ifdef vax	"	-v : display only vector processor state information",#endif /* vax */	"	-h : display this help information",	"	interval: interval in seconds before refreshing display",	"	count: count of intervals before exiting the program",	"If no option is used, all information will be displayed line by line",	0	};char	*help_info[] = {	"The Statistics fields are:",	"	us%% : %% time spent in user mode",	"	ni%% : %% time spent in nice mode",	"	sy%% : %% time spent in system mode",	"	id%% : %% time spent idle by the cpu",	"	csw : number of context switches",	"	sys: number of system calls",	"	trap: number of traps",	"	intr: number of device interrupts",	"	ipi: number of inter processor interrupts",	"	ttyin: number of input tty characters",	"	ttyout: number of output tty characters",	"The Cpu States fields are:",	"	cpuid: Unique identifier of the cpu",	"	state: Cpu state: B - Boot cpu, R - running, T - TB needs invalidation,",	"		P - paniced, D - disable soft errors, S - cpu stopped",	"	ipi-mask: Inter processor interrupt mask: P - panic, R - console print",	"		S - schedule, T - TB invalidation, H - stop cpu",	"	proc: if the cpu has an associated process (Y/N)",	"	pid:  process id of the running process",	0	};char 	*help_1 = "To get out of the help screen, type any character";#ifdef vaxchar	*cmd = "Commands: <c,d,v,h,q,s>";  /* commands available from within					  * the full display screen */#elsechar	*cmd = "Commands: <c,d,h,q,s>";  /* commands available from within					  * the full display screen */#endif /* vax */struct	stats {		/* structure to internally hold all statistics */	float	st_usr;	float	st_nice;	float	st_sys;	float	st_idle;	int	st_csw;	int	st_calls;	int	st_trap;	int	st_intr;	int	st_ipi;	int	st_ttyin;	int	st_ttyout;} stats;struct  cpu_states {	/* structure to internally hold all states */	char		cps_state[15];	char		cps_ipi[15];	char		cps_proc;	short		cps_pid;} cpu_states;char	scale_data();int	done();extern int errno;main(argc,argv)int argc;char *argv[];{	register int i;	struct cpudata *pcpu;	if(--argc > 0) {		if (argv[1][0] == '-') {			if(get_opts(argv[1])) {				usage();				exit(1);			}		argc--;		argv++;		}		if(argc--)			interval = atoi(argv[1]);		if(argc)			iter = atoi((++argv)[1]);	}	nlist(kernfile,namelist);	if(namelist[C_AVENRUN].n_type == 0) {		printf("Namelist could not be found for %s\n",kernfile);		exit(1);	}	if ( (kmem = open(kmemfile,0)) == 0 ) {		printf("Cannot open %s\n",kmemfile);		exit(1);	}#ifdef vax	if(namelist[C_VPMASK].n_value != 0) {	    lseek(kmem, (long)namelist[C_VPMASK].n_value, 0);	    read(kmem, &vpmask, sizeof(vpmask));	}	else {	    vpmask = 0;	}	if(namelist[C_VPTOTAL].n_value != 0) {	    lseek(kmem, (long)namelist[C_VPTOTAL].n_value, 0);	    read(kmem, &vptotal, sizeof(vptotal));	}	else {	    vptotal = 0;	}#endif /* vax */	for(i=0; i<MAXCPU; i++) {		lseek(kmem, (long)namelist[C_CPUDATA].n_value + 4*i, 0);		read(kmem, &pcpu, sizeof (pcpu));		if (pcpu) {			activecpu = activecpu | (1<<i);			total_cpus++;		}	}	if( (cpudata_p0 = (struct cpudata *)calloc(total_cpus,sizeof(struct cpudata)) ) == NULL) {		printf("No memory to allocate cpudata structures\n");		exit(1);	}	if( (cpudata_p1 = (struct cpudata *)calloc(total_cpus,sizeof(struct cpudata)) ) == NULL) {		printf("No memory to allocate cpudata structures\n");		exit(1);	}#ifdef vax	if(vptotal > 0) {	    if( (vpdata_p0 = 		    (struct vpdata *)calloc(total_cpus,					    sizeof(struct vpdata)) ) == NULL) {		printf("No memory to allocate vpdata structures\n");		exit(1);	    }	    if( (vpdata_p1 = 		    (struct vpdata *)calloc(total_cpus,					    sizeof(struct vpdata)) ) == NULL) {		printf("No memory to allocate vpdata structures\n");		exit(1);	    }	}#endif /* vax */	signal(SIGINT,done);	signal(SIGQUIT,done);	display();	/* NO RETURN */}get_opts(ptr)char *ptr;{	char c;	int errflg = 0;		while (c = *ptr++) {		switch(c) {		case 'f':			fflg++;			break;		case 'c':			cflg++;			deflt = 0;			break;		case 's':			sflg++;			deflt = 0;			break;#ifdef vax		case'v':			vflg++;			deflt = 0;			break;#endif /* vax */		case 'h':			print_help();			exit(0);		case '-':			break;		default:			errflg++;		 		}	} 	if(errflg)		return(1);	else		return(0);}/* This is the routine which controls all the display. It loops for ever * updating the display at requested intervals. */display(){	struct timeval tintv;	int mask,tin;	char c;	int hdr = 0;	if(interval == 0)		tintv.tv_sec = DEF_INTERVAL;	else		tintv.tv_sec = interval;	tintv.tv_usec = 0;	if(fflg) {   /* if full screen option, set up the headers */		gethostname(hname,HOSTLEN);		init_screen();		if(sflg || cflg || vflg) {			if(sflg)				setup_statistics();			if(cflg)				setup_state();			if(vflg && vptotal)				setup_vecstate();		} else {  /* if only -f option used, try to display all info */			setup_statistics();			if( total_cpus <=8 )				setup_state();			if( vptotal && (total_cpus <= 6 ))				setup_vecstate();		}	}	for(;;) {		update_info();  /* pick up the latest data from /dev/kmem */		if(fflg) {			standout();  /* start highligting display */#ifdef vax			mvprintw(YZERO,25,"%4.2f %4.2f %4.2f",loadav[0],loadav[1],loadav[2]);#endif vax#ifdef mips			mvprintw(YZERO,25,"%4.2f %4.2f %4.2f",FIX_TO_DBL(loadav[0]),FIX_TO_DBL(loadav[1]),FIX_TO_DBL(loadav[2]));#endif mips			mvprintw(YZERO,45,ctime(&cur_time));			move (YZERO,70);			if(users != -1) {				if(users == 1)					addstr("1 user");				else					printw("%d users",users);			}			standend(); /* end highlighting display */			if(sflg || cflg || vflg ) {				if(sflg)					upd_statistics_scrn();				if(cflg) 					upd_state_scrn();				if(vflg)					upd_vec_scrn();			} else {				upd_statistics_scrn();				if( total_cpus <=8 ) 					upd_state_scrn();				if( total_cpus <= 6 )					upd_vec_scrn();			}			mvprintw(LINES-1,XZERO,cmd);			refresh();  /* put the stuff up on the screen */		} else {			if(sflg || cflg || vflg) {				if (cflg) {					if( (hdr == 0) || (sflg) ) {						printf(statistics_hdr);						printf("\n");					}					pr_statistics();				}				if(sflg) {					if( (hdr == 0) || (cflg) )						printf("\n");						printf("%s\n",state_hdr);					pr_state();				}#ifdef vax				if((vflg != 0) && (vptotal != 0)) {					if( (hdr == 0) || (vflg) ) {						printf("\n");						printf("%s\n", vp_hdr);					}					pr_vecstate();				}#endif /* vax */				if(hdr == 0)					hdr = 19/total_cpus; /* to print header*/				else					hdr--;			} else {				printf(statistics_hdr);				printf("\n");				pr_statistics();				printf("%s\n",state_hdr);				pr_state();#ifdef vax				if(vptotal > 0) {					printf("%s\n", vp_hdr);					pr_vecstate();				}#endif /* vax */			}			printf("\n");		}		if(--iter == 0)			done();		if(fflg) {  /* wait for any user input for full screen option */			tin = 1;	/* mask for stdin for select() */			/* pick up the user typed character within the desired			 * time interval */			errno = 0;			mask = select(2, &tin, (int *)0, (int *)0, &tintv);			if( !errno && mask && tin) {				int saved;				c = getchar();				switch(c) {				case 'q':					done();				case 'h':					display_help();					saved = tintv.tv_sec;					/* display the help message for a max. 					 * of 10 mins. before going back to the					 * original display */					tintv.tv_sec = 10 * 60; /* max. 10 mins */					tin = 1;					errno = 0;					mask = select(2,&tin,(int *)0, (int *)0,&tintv);					if(!errno && mask && tin)						c = getchar();					tintv.tv_sec = saved;					/* setup the screen as was before 					 * putting up the help screen */					setup_init();					if(sflg || cflg || vflg) {						if(sflg)							setup_statistics();						if(cflg)							setup_state();						if(vflg && vptotal)							setup_vecstate();					} else {						setup_statistics();						if( total_cpus <=8 )							setup_state();						if(vptotal&&(total_cpus <= 6))							setup_vecstate();					}					break;				case 'c':					if(sflg || vflg || (!cflg) ) {						deflt = 0;						cflg = 1;						sflg = 0;						vflg = 0;							setup_init();						setup_state();					}					break;#ifdef vax				case 'v':					if(sflg || cflg || (!vflg) ) { 						deflt = 0;						vflg = 1;						cflg = 0;						sflg = 0;						setup_init();						if(vptotal) 							setup_vecstate();					}					break;#endif /* vax */				case 's':					if(cflg || vflg || (!sflg) ) {						deflt = 0;						sflg = 1;						cflg = 0;						vflg = 0;						setup_statistics();					}					break;				case 'd':  /* display the default option 					    * ie. only f flag */					if(!deflt) {						deflt = 1;						vflg = cflg = sflg = 0;						setup_statistics();						if(total_cpus <= 8)							setup_state();						if(vptotal&&(total_cpus <= 6))							setup_vecstate();					}

⌨️ 快捷键说明

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