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

📄 m_svr42mp.c

📁 unix系统下top命令的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/*	 * Get process id of last process.	 */	getkval (nextpid_offset, (void *)&(si->last_pid),			sizeof (si->last_pid), "nextpid");	si->last_pid--;	/*	 * Get load average array.	 */	getkval (avenrun_offset, (void *) avenrun, sizeof (avenrun),			"avenrun");		/*	 * Convert load averages to doubles.	 */	for (i = 0; i < 3; i++)		si->load_avg[i] = loaddouble (avenrun[i]);	/*	 * Extract CPU percentages.	 */	/*	 * 1. Retrieve pointer to metrics data structure.	 */	getkval(offset_offset, (void *)&mlpp,		sizeof (struct met_localdata_ptrs_p *),		"met_localdata_ptrs_pp");	/*	 * 2. Retrieve metrics data structure. (ptr to metrics engine)	 */	getkval((unsigned long)mlpp, (void *)&mlp, sizeof (mlp),		"met_localdata_ptrs_p");	/*	 * 3. Retrieve (first local metrics) plocalmet data structure.	 */	getkval((unsigned long)mlp.localdata_p[0], (void *)&plm,		sizeof(struct plocalmet), "plocalmet");	percentages(CPUSTATES, cpu_states, plm.metp_cpu.mpc_cpu,		    cp_old, cp_diff);	/*	 * Retrieve memory information.	 */	/*	 * 1.	Get physical memory size.	 */	getkval(totalmem_offset, (void *)&totalmem, sizeof (unsigned long),		"totalmem");	/*	 * 2.	Get physical swap size, and amount of swap remaining.	 */	get_swapinfo(&totalswap, &totalswapfree);	/*	 * Insert memory information into memory_stat structure.	 */	memory_stats[0]	= totalmem >> 10;	memory_stats[1]	= pagetok(totalswap);	memory_stats[2]	= pagetok(totalswapfree);	/*	 * Set arrays and strings.	 */	si->cpustates	= cpu_states;	si->memory 	= memory_stats;}/* ************************************************************************** *//* * Extract process information. */static struct handle handle;caddr_tget_process_info (		   struct system_info *si,		   struct process_select *sel,		   int (*compare) ()){	register int	i;	register int	j = 0;	register int	active_procs;	register int	total_procs;	register struct	uwproc **prefp;	register struct	uwproc *uwp;	/*	 * These are copied out of sel for speed.	 */	int		show_idle;	int		show_system;	int		show_uid;	/*	 * Read all the proc structures.	 */	getptable (pbase);	/*	 * Get a pointer to the states summary array.	 */	si->procstates	= process_states;	/*	 * Set up flags which define what we are going to select.	 */	show_idle	= sel->idle;	show_system	= sel->system;	show_uid	= sel->uid != -1;	/*	 * Count up process states and get pointers to interesting procs.	 */	total_procs	= 0;	active_procs	= 0;	(void) memset (process_states, 0, sizeof (process_states));	prefp		= pref;	for (i = 0; i < numprocs; i++)	{		uwp	= &pbase[i];		/*		 * Place pointers to each valid proc structure in pref[].		 * Processes with P_SYS set are system processes---these		 * get ignored unless show_system is set.		 */		uwp->dummy	= 0;		if ((show_system || ((uwp->p.p_flag & P_SYS) == 0)))		{			total_procs++;			if (ZOMBIE(uwp))			{				process_states[ZOMBIESTATE]++;			}			else			{				if ( (show_idle || uwp->l.l_stat == SRUN ||				      uwp->l.l_stat == SONPROC) &&				     (!show_uid ||				      uwp->ps.pr_uid == (uid_t)sel->uid))				{					process_states[uwp->l.l_stat]++;					prefp[j]	= uwp;					j++;					active_procs++;				}			}		}	}	/*	 * If requested, sort the "interesting" processes.	 */	if (compare != NULL)		qsort ((void *) pref, active_procs,		       sizeof (struct uwproc *), compare);	/*	 * Remember active and total counts.	 */	si->p_total		= total_procs;	si->P_ACTIVE		= active_procs;	/*	 * Pass back a handle.	 */	handle.next_proc	= pref;	handle.remaining	= active_procs;	return ((caddr_t) & handle);}/* ************************************************************************** *//* * Format the output string for a process. */char fmt[MAX_COLS];			/* static area where result is built */char *format_next_process (		      caddr_t handle,		      char *(*get_userid) ()){	register struct uwproc		*pp;	struct handle			*hp;	register long			 cputime;	register double			 pctcpu;	/*	 * Find and remember the next proc structure.	 */	hp	= (struct handle *) handle;	pp	= *(hp->next_proc++);	hp->remaining--;	(void) snprintf (fmt, MAX_COLS,		PROC_FORMAT,		pp->ps.pr_pid,		(*get_userid) (pp->ps.pr_uid),		pp->PR_pri,#ifdef SHOW_NICE		pp->ps.pr_lwp.pr_nice,#else                (u_short)pp->p.p_nlwp < 999 ? (u_short)pp->p.p_nlwp : 999,#endif		format_k(pagetok (pp->ps.pr_size)),		format_k(pagetok (pp->ps.pr_rssize)),		state_abbrev[pp->PR_state],		format_time(pp->PR_time.tv_sec),		pp->wcpu,		pp->pctcpu,		pp->ps.pr_fname);	/*	 * Return the result.	 */	return (fmt);}/* ************************************************************************** *//* * check_nlist(nlst) - checks the nlist to see if any symbols were not *		found.  For every symbol that was not found, a one-line *		message is printed to stderr.  The routine returns the *		number of symbols NOT found. */intcheck_nlist (register struct nlist *nlst){	register int i;	/*	 * Check to see if we got ALL the symbols we requested.	 * This will write one line to stderr for every symbol not found.	 */	i = 0;	while (nlst->n_name != NULL)	{		if (nlst->n_type == 0)		{			/*			 * This one wasn't found.			 */			fprintf(stderr, "kernel: no symbol named `%s'\n",				nlst->n_name);			i = 1;		}		nlst++;	}	return (i);}/* ************************************************************************** *//* *  getkval(offset, ptr, size, refstr) - get a value out of the kernel. *	"offset" is the byte offset into the kernel for the desired value, *  	"ptr" points to a buffer into which the value is retrieved, *  	"size" is the size of the buffer (and the object to retrieve), *  	"refstr" is a reference string used when printing error meessages, *	    if "refstr" starts with a '!', then a failure on read will not *  	    be fatal (this may seem like a silly way to do things, but I *  	    really didn't want the overhead of another argument). * */intgetkval (          unsigned long offset,          void	*ptr,          int	 size,          char *refstr){	if (lseek (kmem, (long) offset, 0) == -1)	{		if (*refstr == '!')			refstr++;		fprintf (stderr, "%s: lseek to %s: %s\n",			 myname, refstr, strerror(errno));		quit (22);	}	if (read (kmem, (char *) ptr, size) == -1)	{		if (*refstr == '!')		{			/*			 * We lost the race with the kernel,			 * process isn't in memory.			 */			return (0);		}		else		{			(void) fprintf (stderr, "%s: reading %s: %s\n",			myname, refstr, strerror(errno));			quit (23);		}	}	return (1);}/* ************************************************************************** *//* * Extract process table and derive %cpu figures.*/voidgetptable (struct uwproc *baseptr){	struct dirent		*direntp;	struct uwproc		*curruwproc;	struct oldproc		*op;	static struct	timeval	 lasttime = {0, 0};	struct		timeval	 thistime;	double			 alpha, beta, timediff;	int			 pos, i;	numprocs		= 0;	gettimeofday(&thistime, NULL);	/* 	 * Calculate background information for CPU statistic.	 */	if (lasttime.tv_sec)	{		timediff	= ((double)thistime.tv_sec * 1.0e7 +				   (double)thistime.tv_usec * 10.0) -				  ((double)lasttime.tv_sec * 1.0e7 +				   (double)lasttime.tv_usec * 10.0);	}	else	{		timediff	= 1.0e7;	}	/*	 * Constants for exponential average.  avg = alpha * new + beta * avg	 * The goal is 50% decay in 30 sec.  However if the sample period	 * is greater than 30 sec, there's not a lot we can do.	 */	if (timediff < 30.0e7)	{		alpha	= 0.5 * (timediff / 30.0e7);		beta	= 1.0 - alpha;	}	else	{		alpha	= 0.5;		beta	= 0.5;	}	/*	 * While there are still entries (processes) in the /proc	 * filesystem to be examined...	 */	for (rewinddir (procdir); direntp = readdir (procdir);)	{		char	buf[MAXPATHLEN];		int	fd;		int	rc;		int	pos;		/*		 * Ignore parent and current directory entries.		 */		if (direntp->d_name[0] == '.')			continue;		/*		 * Construct filename representing the psinfo		 * structure on disk.		 */		snprintf(buf, MAXPATHLEN, PROCFS "/%s/psinfo", direntp->d_name);				if ((fd	= open (buf, O_RDONLY)) == -1)		{			fprintf(stderr, "Can't open %s: %s\n", buf,				strerror(errno));			continue;		}		curruwproc		= &baseptr[numprocs];		/*		 * Read in psinfo structure from disk.		 */		if (read(fd, (void *)&curruwproc->ps,			 sizeof(psinfo_t)) != sizeof(psinfo_t))		{			close(fd);			fprintf(stderr, "Can't read %s: %s\n", buf,				strerror(errno));			continue;		}		close(fd);		/*		 * Extract the proc structure from the kernel.		 */		rc = getkval((unsigned long)curruwproc->ps.pr_addr,				(void *)&curruwproc->p, sizeof(struct proc),				"!proc");		if (rc == -1)		{			fprintf(stderr, "Can't read proc structure\n");			continue;		}		/*		 * Extract the lwp structure from the kernel.		 */		rc = getkval((unsigned long)curruwproc->ps.pr_lwp.pr_addr,				(void *)&curruwproc->l, sizeof(struct lwp),				"!lwp");		if (rc == -1)		{			fprintf(stderr, "Can't read lwp structure\n");			continue;		}		/*		 * Work out %cpu figure for process.		 */		pos	= HASH(curruwproc->p.p_epid);		while(1)		{			if (oldbase[pos].oldpid == -1)			{				/*				 * Process not present in hash.				 */				break;			}			if (oldbase[pos].oldpid == curruwproc->p.p_epid)			{				double	new;				/*				 * Found old data.				 */				new = (double)curruwproc->PR_time.tv_sec					* 1.0e9 +					curruwproc->PR_time.tv_nsec;				curruwproc->pctcpu = ((					(double)curruwproc->PR_time.tv_sec *				 	1.0e9 +					(double)curruwproc->PR_time.tv_nsec)					- (double)oldbase[pos].oldtime) /					timediff;								curruwproc->wcpu = oldbase[pos].oldpct *					beta + curruwproc->pctcpu * alpha;								break;			}			pos++;			if (pos == numoldprocs)			{				pos	= 0;			}		}		if (oldbase[pos].oldpid == -1)		{			/*			 * New process.			 * All of its cputime used.			 */			if (lasttime.tv_sec)			{				curruwproc->pctcpu =					(curruwproc->PR_time.tv_sec * 1.0e9					 + curruwproc->PR_time.tv_nsec) /					timediff;				curruwproc->wcpu   = curruwproc->pctcpu;			}			else			{				curruwproc->pctcpu	= 0.0;				curruwproc->wcpu	= 0.0;			}		}		numprocs++;	}	/*

⌨️ 快捷键说明

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